<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
  <channel>
    <title>Dan Sanderson</title>
    <link>https://dansanderson.com/</link>
    <description>Dan Sanderson </description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>contact@dansanderson.com (Dan Sanderson)</managingEditor>
    <webMaster>contact@dansanderson.com (Dan Sanderson)</webMaster>
    <copyright>Copyright &amp;#xA9; 2025 Dan Sanderson. All Rights Reserved.</copyright>
    <lastBuildDate>Sat, 14 Mar 2026 00:00:00 -0800</lastBuildDate>

    <atom:link href="https://dansanderson.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Roguecraft DX; Introducing the Raster Rewrite Buffer</title>
      <link>https://dansanderson.com/mega65/raster-rewrite-buffer/</link>
      <pubDate>Sat, 14 Mar 2026 00:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/raster-rewrite-buffer/</guid>
      <description>&lt;p&gt;Roguecraft DX; Introducing the Raster Rewrite Buffer. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for March 2026.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Roguecraft DX; Introducing the Raster Rewrite Buffer. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for March 2026.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/M65Digest_2026Mar.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/M65Digest_2026Mar.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Introducing the Raster Rewrite Buffer.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft1.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft1.png 944w, https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft1_hu_90c3f03bf488bac.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft1_hu_e1d64193c2497cf8.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft1.png&#34;
        alt=&#34;Roguecraft DX for the MEGA65, coming soon&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Roguecraft DX for the MEGA65, now available!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 community is buzzing with the release of &lt;em&gt;Roguecraft DX,&lt;/em&gt; a new highly polished commercial game from Badger Punch Games for the MEGA65. Among many other fine qualities, &lt;em&gt;Roguecraft&lt;/em&gt; takes advantage of the MEGA65&amp;rsquo;s full color character graphics features to show animated, colorful foreground figures on a colorful background.&lt;/p&gt;
&lt;p&gt;In our continuing series on character graphics, we&amp;rsquo;ve seen how to prepare colorful high resolution graphics tiles in character sets, and plot characters onto the screen at coordinates in a grid pattern. We&amp;rsquo;ve also seen how a character set can become a canvas, by spreading all the characters across the screen like a quilt then updating the character set itself. But this is &lt;em&gt;not&lt;/em&gt; how &lt;em&gt;Roguecraft&lt;/em&gt; achieves a foreground and a background: it would take too much computation to draw and update foreground images onto such a canvas.&lt;/p&gt;
&lt;p&gt;Instead, &lt;em&gt;Roguecraft&lt;/em&gt; uses a powerful feature of the VIC-IV, called the &lt;em&gt;raster rewrite buffer&lt;/em&gt; (or RRB). With this feature, your program can tell the VIC-IV to draw characters &lt;em&gt;on top of other characters&lt;/em&gt;, treating some pixels as transparent. Moreover, these characters can be drawn &lt;em&gt;at arbitrary pixel positions&lt;/em&gt;. The RRB unlocks a whole new world of graphics capabilities, such as hundreds of fast-moving graphics objects, particle systems, and multiple parallax background layers, all built on top of the character graphics features we&amp;rsquo;ve seen so far.&lt;/p&gt;
&lt;p&gt;In this Digest, we will introduce the raster rewrite buffer through a simple example. We won&amp;rsquo;t quite reach the sophistication of &lt;em&gt;Roguecraft&lt;/em&gt; in one sitting, but we&amp;rsquo;ll get the general idea, enough to start using it in our own programs.&lt;/p&gt;
&lt;p&gt;But first, let&amp;rsquo;s see what everyone has been up to these last few months!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;roguecraft-dx-for-the-mega65&#34;&gt;Roguecraft DX for the MEGA65&lt;/h2&gt;
&lt;figure class=&#34;youtube-player&#34;&gt;
&lt;iframe
    width=&#34;600&#34;
    height=&#34;337&#34;
    src=&#34;https://www.youtube.com/embed/OEQl8A9dZ2A&#34;
    title=&#34;Roguecraft DX for the MEGA65 reveal trailer&#34;
    frameborder=&#34;0&#34;
    allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#34;
    allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;Roguecraft DX,&lt;/em&gt; the hit arcade dungeon crawler by Badger Punch Games, &lt;a href=&#34;https://thalamusdigital.itch.io/roguecraft-dx-mega&#34;&gt;is now available for the MEGA65&lt;/a&gt;! You can get the digital download today, and you can &lt;a href=&#34;https://www.thalamus.shop/product/roguecraft-dx-mega65&#34;&gt;pre-order the physical boxed edition&lt;/a&gt;, which is expected to ship in June. Our very own &lt;a href=&#34;https://retrocogs.mega65.com/&#34;&gt;RetroCogs&lt;/a&gt; developed this gorgeous adaptation that takes advantage of the MEGA65&amp;rsquo;s graphics capabilities.&lt;/p&gt;
&lt;p&gt;Badger Punch&amp;rsquo;s instant classic began as &lt;a href=&#34;https://www.badgerpunch.com/title/rogue4k/&#34;&gt;a 4 kilobyte game jam title for the Commodore 64&lt;/a&gt;, which was later expanded with gorgeous art into the commercial release &lt;a href=&#34;https://www.badgerpunch.com/title/rogue64/&#34;&gt;Rogue64&lt;/a&gt;, named Game of the Year in 2022 by FREEZE64 magazine. This inspired the vibrant isometric &lt;a href=&#34;https://www.badgerpunch.com/title/roguecraft/&#34;&gt;Roguecraft for the Amiga&lt;/a&gt;, with all-new stunning art, animation, and turn-based gameplay. This was later expanded again into &lt;a href=&#34;https://www.badgerpunch.com/title/roguecraftdx-evercade/&#34;&gt;Roguecraft DX&lt;/a&gt; with more levels, gameplay, and music, originally exclusive to the &lt;a href=&#34;https://evercade.co.uk/&#34;&gt;Evercade&lt;/a&gt; modern retro console as &lt;a href=&#34;https://evercade.co.uk/cartridges/roguecraft-dx/&#34;&gt;a cartridge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This announcement includes three new versions of Roguecraft DX: the MEGA65 version, an Amiga version (the DX expansions are new), and an all-new Game Boy Color version with a top-down perspective. Of course, I&amp;rsquo;m most excited for the MEGA65 version, which preserves the color depth of the Evercade art assets.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://thalamusdigital.itch.io/roguecraft-dx-mega&#34;&gt;Purchase Roguecraft DX for the MEGA65&lt;/a&gt; as a digital download on Itch.io, or &lt;a href=&#34;https://www.thalamus.shop/product/roguecraft-dx-mega65&#34;&gt;pre-order the physical boxed edition&lt;/a&gt; from publisher Thalamus Digital.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft2.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft2.png 734w, https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft2_hu_89b44f5ac4e43e94.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft2_hu_b584eacb77baa64b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft2.png&#34;
        alt=&#34;Another still from Roguecraft DX for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Another still from Roguecraft DX for the MEGA65.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;interview-with-paul-gardner-stephen&#34;&gt;Interview with Paul Gardner-Stephen&lt;/h2&gt;
&lt;p&gt;RetroTech &amp;amp; Café published &lt;a href=&#34;https://retrotechycafe.wordpress.com/2025/12/31/interview-with-paul-gardnerstephen-architect-of-the-mega65-we-are-building-the-future-that-commodore-never-launched/&#34;&gt;an interview with MEGA65 creator Paul Gardner-Stephen&lt;/a&gt; about the project.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;RT&amp;amp;C: What role does the community play in the evolution of the MEGA65?&lt;/p&gt;
&lt;p&gt;Paul: Everything! Our community might not be huge, but it’s still several thousand strong, and a really high proportion of that community are active in making stuff for the MEGA65 or contributing in other ways (and they don’t all require being able to program!). We could have gone for maximum community size as fast as possible, but for us, it’s the quality of experience of being part of the MEGA65 project that makes it so rich and engaging for everyone.&lt;/p&gt;
&lt;p&gt;And this is an invitation that we keep offering — be part of us in this crazy but rewarding project.  The journey is the destination, and it’s a tremendously exciting and joyful one.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;prog8-and-6502-fart-bmbs&#34;&gt;Prog8 and 6502 Fart B*mbs!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/fartbombs.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/fartbombs.png 1024w, https://dansanderson.com/mega65/raster-rewrite-buffer/fartbombs_hu_180cb7650875b53c.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/fartbombs_hu_2053a1ef5ecacee9.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/fartbombs.png&#34;
        alt=&#34;6502 Fart B*mbs! a game for the MEGA65 written in Prog8&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;6502 Fart B*mbs! a game for the MEGA65 written in Prog8.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://prog8.readthedocs.io/en/latest/introduction.html&#34;&gt;Prog8&lt;/a&gt; is a cross-compiled programming language that targets 6502-CPU-family 8-bit platforms, including the Commodore 64, the &lt;a href=&#34;https://www.commanderx16.com/&#34;&gt;Commander X16&lt;/a&gt;, and the &lt;a href=&#34;https://wildbitscomputing.com/&#34;&gt;Wildbits F256&lt;/a&gt; (formerly of Foenix Retro Systems). Thanks to CommodoreSam and Andrew Gillham, Prog8 now has a full working example that can be built natively for the MEGA65. No changes to the Prog8 system were needed to get this to work: you can add support for new platforms with a configuration file.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=74a9e34b-d3af-410a-b86c-1bc22f0eec96&#34;&gt;6502 Fart B*mbs!&lt;/a&gt;, a Minesweeper-like logic game, is written in Prog8, and includes a working build configuration for the MEGA65. Sam and Andrew have released &lt;a href=&#34;https://github.com/CommodoreSam/6502_Fart_Bombs&#34;&gt;the game&amp;rsquo;s source code&lt;/a&gt; under the MIT License, so you can see how it is written, and how to set up a MEGA65 Prog8 project of your own. It&amp;rsquo;s also a fun game! Try it out!&lt;/p&gt;
&lt;h2 id=&#34;commodore-plus4-and-commodore-128-emulators&#34;&gt;Commodore plus/4 and Commodore 128 emulators&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/plus4.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/plus4.png 1024w, https://dansanderson.com/mega65/raster-rewrite-buffer/plus4_hu_fa9ce53187357886.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/plus4_hu_4fe42a25d3154a47.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/plus4.png&#34;
        alt=&#34;plus4, a Commodore Plus/4 emulator, by xlar54&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;plus4, a Commodore plus/4 emulator, by xlar54&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;xlar54 has started a pair of compelling experiments: a &lt;a href=&#34;https://files.mega65.org?id=48b42681-86a3-450b-a064-4dd25cc728b0&#34;&gt;Commodore Plus/4 emulator&lt;/a&gt; and a &lt;a href=&#34;https://files.mega65.org?id=5e7eea8a-dd6f-4771-b3aa-4c116fa9f277&#34;&gt;Commodore 128 emulator&lt;/a&gt;, both for the MEGA65. Unlike alternate FPGA cores, these emulators run in MEGA65 mode, and use the MEGA65&amp;rsquo;s extra speed to outrun the original CPUs. These do not yet have every feature of their real-world counterparts, including some features of each platform&amp;rsquo;s unique video capabilities. They otherwise support nearly all of the functionality of the original ROM files, which you must supply.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/xlar54/plus4-emu-m65&#34;&gt;the plus/4 project&amp;rsquo;s Github repo&lt;/a&gt; and &lt;a href=&#34;https://github.com/xlar54/c128-emu-m65&#34;&gt;the C128 project&amp;rsquo;s Github repo&lt;/a&gt; for source code and other useful files.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/c128emu.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/c128emu.png 1024w, https://dansanderson.com/mega65/raster-rewrite-buffer/c128emu_hu_fd335094672b00d5.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/c128emu_hu_3c51e505267e7e3a.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/c128emu.png&#34;
        alt=&#34;c128, a Commodore 128 emulator, by xlar54&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;c128, a Commodore 128 emulator, by xlar54&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/chopper.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/chopper.png 705w, https://dansanderson.com/mega65/raster-rewrite-buffer/chopper_hu_d1b82feb19325407.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/chopper_hu_25d38b153425e4c3.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/chopper.png&#34;
        alt=&#34;Chopper, by SirGeldi&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Chopper, by SirGeldi.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;More fun things to check out on Filehost:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=7e5ce0e9-cf69-493b-a99f-15d242651c4e&#34;&gt;CHOPPER65&lt;/a&gt;, by SirGeldi. An original helicopter game, written in BASIC 65.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=eaa8ff4f-8fba-4596-b5c4-02abdf8dcd9f&#34;&gt;Snowflake&lt;/a&gt;, by geehaf. A simple demo using a technique based on the raster rewrite buffer.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=4848465a-f589-4d31-9a47-d656df44445c&#34;&gt;SEAM Sinus Demo&lt;/a&gt;, by sirlazarus. An assembly language version of the sine curve example at the end of &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/&#34;&gt;the October Digest&lt;/a&gt;, using an assembler-generated sine table.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=0eb33347-dc3a-40d7-8f85-b0bfbe652123&#34;&gt;Fifth Wins&lt;/a&gt;, by Hanyic Róbert. A two-player logic game; play against another player or against the computer. Connect a mouse to play.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=9cf9b419-4614-4eb0-8877-8c257559a3d9&#34;&gt;Escape From Spaceship Seven&lt;/a&gt;, by GeirS. A MEGA65 port of a space-themed text-based adventure game originally for the Commodore 64 and MAX Machine, in English and Spanish.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=09150f08-5204-4812-b939-dd175097bfb1&#34;&gt;m65cribbage&lt;/a&gt;, by Shinobi (aa7ae). The classic card and board game, with a computer opponent.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=025632e7-ae4a-4365-a74d-2372887c024e&#34;&gt;FCM library&lt;/a&gt;, by xlar54. A featureful graphics library in assembly language that implements multiple screen modes with the MEGA65&amp;rsquo;s Full Color Mode features. Check out the demo disk on Filehost, and see &lt;a href=&#34;https://github.com/xlar54/m65-fcm&#34;&gt;the Github repo&lt;/a&gt; for sources.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=1fa77d8e-ebf9-431e-9ca6-1897f8e78057&#34;&gt;SixSeven&lt;/a&gt;, by AwesomeDolphin, a simple single-button gag game written in BASIC 65.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;h2 id=&#34;tactical-strike&#34;&gt;Tactical Strike&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/ts_tilesheet.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/ts_tilesheet.png 640w, https://dansanderson.com/mega65/raster-rewrite-buffer/ts_tilesheet_hu_d811b0f2a8dbb64d.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/ts_tilesheet_hu_93d0200e714025f2.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/ts_tilesheet.png&#34;
        alt=&#34;Tactical Strike tile sheet&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Tactical Strike tile sheet
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;Over hill, over dale, &lt;br&gt;
As we hit the dusty trail, &lt;br&gt;
And the caissons go rolling along. &lt;br&gt;
— &amp;ldquo;The Caissons Go Rolling Along,&amp;rdquo; Gruber (1908)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;rsquo;ve been playing around with &lt;a href=&#34;https://kenney.nl/assets/tiny-battle&#34;&gt;this game tile set by Kenney&lt;/a&gt; intended for a military strategy game. There are tiles for fields, lakes, rivers, roads, and bridges to form a landscape, an assortment of military soldiers and vehicles in five color variations, and indicators and icons for user interface elements. The tiles are 16 pixels wide and tall and reasonably low color depth, so they seem suitable for a MEGA65 project.&lt;/p&gt;
&lt;p&gt;The image above is my rendering of this tileset on a MEGA65 using NCM graphics over a solid grass-green background color. Most vintage computers are limited to drawing characters on solid background colors like this, and there is a deep history of vintage computer games doing so.&lt;/p&gt;
&lt;p&gt;Very many vintage games, such as &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/&#34;&gt;Crossroads&lt;/a&gt; or &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/&#34;&gt;robotfindskitten&lt;/a&gt;, declare the solid background color to be the ground on which characters could walk, using tiles exclusively for foreground objects such as the player, enemies, and obstacles.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/crossroads_screenshot.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/crossroads_screenshot.png 384w, https://dansanderson.com/mega65/raster-rewrite-buffer/crossroads_screenshot_hu_aa9feeb98ea8c4a8.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/crossroads_screenshot_hu_27a9f7e151be967e.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/crossroads_screenshot.png&#34;
        alt=&#34;Crossroads for the Commodore 64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Crossroads for the Commodore 64.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Other games, such as &lt;a href=&#34;https://www.lemon64.com/game/ultima-1&#34;&gt;Ultima&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=7f3d1007-6250-44e4-86cb-93444ae669b5&#34;&gt;Commando B65&lt;/a&gt;, or &lt;a href=&#34;https://files.mega65.org?id=9ad15b5a-eefd-430a-8144-840b67229501&#34;&gt;MEGAMAGE&lt;/a&gt;, use characters to indicate the ground also, such as grass in a field. When a foreground object is resting on a background surface, the game just draws the foreground tile, relying on the surrounding unoccupied background tiles to indicate what the object is standing on. Characters cannot overlap in most vintage character graphics systems.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/ultima_i_03.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/ultima_i_03.png 320w, https://dansanderson.com/mega65/raster-rewrite-buffer/ultima_i_03_hu_21760abbcd3a1b89.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/ultima_i_03_hu_509987e207c389c6.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/ultima_i_03.png&#34;
        alt=&#34;Ultima 1 for the Commodore 64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Ultima 1 for the Commodore 64.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Allowing graphics objects to overlap is the primary purpose of the &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/&#34;&gt;VIC-II&amp;rsquo;s hardware sprites&lt;/a&gt;. Sprites can appear &amp;ldquo;in front of&amp;rdquo; or &amp;ldquo;behind&amp;rdquo; characters, and can be positioned at any pixel coordinate. The video chip composes the scene as it draws the screen, calculating the color of each pixel based on characters in screen memory and sprites described in registers. The VIC-II needs to handle sprites in a special way, so it can only support eight of them at a time. &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/&#34;&gt;As we&amp;rsquo;ve seen&lt;/a&gt;, if the program jiggles the sprite registers fast enough, it can get the VIC to draw more than eight sprites on the same screen, with some limitations.&lt;/p&gt;
&lt;p&gt;But this won&amp;rsquo;t do for my strategy game, which I&amp;rsquo;m calling &lt;em&gt;Tactical Strike&lt;/em&gt;. I want vehicles to roll over flowers, just like in the dramatic openings of war movies. I want boats in the water, and helicopters over everything. And I have user interface elements such as unit counters and movement arrows. I can&amp;rsquo;t use VIC-II sprites for this. How can I draw characters &lt;em&gt;on top of other characters?&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;ncm-hot-topics&#34;&gt;NCM hot topics&lt;/h2&gt;
&lt;p&gt;Tactical Strike uses Nibble Character Mode (NCM) for its tiles. We got an NCM example working in &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/&#34;&gt;the last Digest&lt;/a&gt;, but we left out a few important topics to focus the discussion. Let&amp;rsquo;s clear those up now.&lt;/p&gt;
&lt;h2 id=&#34;hot-registers&#34;&gt;Hot registers&lt;/h2&gt;
&lt;p&gt;You can think of the MEGA65&amp;rsquo;s VIC-IV as a superset of the VIC-II and VIC-III. While the VIC-III did introduce new features above the VIC-II, it retained nearly all of the behaviors of the original VIC-II registers for backwards compatibility. With the VIC-IV, we wanted to go a bit further, including enhancing some features of VIC-II registers. This poses an interesting conundrum: how can the VIC-IV expand an existing VIC-II feature, while still allowing the VIC-II registers to retain their original behavior?&lt;/p&gt;
&lt;p&gt;A notable example: We&amp;rsquo;ve been playing with the VIC-IV CHARPTR register, which tells the VIC the precise address where in memory to find the character set. The VIC-II also has a way to relocate the character set, but it works differently, using a combination of banking bits on the 2nd CIA chip and four bits at address $D018 (register CB) to select a region on a 1 KB boundary. On the MEGA65, when a program updates these C64-style registers that change the character set location, the VIC-IV calculates the equivalent address and updates CHARPTR automatically.&lt;/p&gt;
&lt;p&gt;$D018 is one of five VIC-II register addresses that behave this way. The others are $D011, $D016, $D031, and the VIC-II bank bits of $DD00 (CIA 2 PORT A). These are the &lt;em&gt;hot registers&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s nice if that&amp;rsquo;s all the VIC-IV did, but there&amp;rsquo;s a catch. If the program writes to &lt;em&gt;any&lt;/em&gt; hot register, &lt;em&gt;all&lt;/em&gt; of the hot registers propagate to their VIC-IV equivalents, not just the one register that was updated. This can sometimes cause unintended behavior.&lt;/p&gt;
&lt;p&gt;Hopefully nobody noticed, but there was a hot register hazard in &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/&#34;&gt;a previous Digest&lt;/a&gt;. We did an experiment involving Low-res Multicolor Mode (MCM), and another experiment involving updating CHARPTR. The MCM register is bit 4 of address $D016, a hot register. If you set CHARPTR to a custom address, then activate MCM, you may be surprised to see CHARPTR get reset to the equivalent of the VIC-II registers as the hot registers propagate.&lt;/p&gt;
&lt;p&gt;The easiest way to prevent confusion is to disable the VIC-IV hot register behavior. To do this, clear the HOTREG register, bit 7 of address $D05D.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CLRBIT $D05D,7&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is sufficient for most programs that know how to use the VIC-IV. In exchange, you have to know which VIC-II registers no longer propagate.&lt;/p&gt;
&lt;p&gt;See the &amp;ldquo;Hot Registers&amp;rdquo; section of the VIC-IV appendix in &lt;a href=&#34;https://files.mega65.org?id=d668168c-1fef-4560-a530-77e9e237536d&#34;&gt;the Compendium&lt;/a&gt; for a complete explanation.&lt;/p&gt;
&lt;h2 id=&#34;correcting-for-a-vic-iii-pixel-offset-bug&#34;&gt;Correcting for a VIC-III pixel offset bug&lt;/h2&gt;
&lt;p&gt;The H640 register, bit 7 of $D031, selects the horizontal resolution of the screen: 320 pixels (40 text columns) or 640 pixels (80 text columns). The original Commodore 65 VIC-III has a bug where characters are drawn shifted slightly to the left in H640 mode. To compensate, manipulating the H640 register also sets the VIC-II horizontal scrolling register, known as XSCL at $D016.0-2. The MEGA65 implementation reproduces this bug and the compensation for compatibility reasons, which means programs have to work around it. (We&amp;rsquo;ll cover text scrolling another time. For now, just know that there are registers that can nudge the screen horizontally by a number of pixels. Try messing with them!)&lt;/p&gt;
&lt;p&gt;$D016 is a hot register. The VIC-IV has a more powerful horizontal scrolling register called TEXTXPOS ($D04C), and with hot registers enabled, a hot register update propagates XSCL to TEXTXPOS. In the full sequence of events, changing H640 sets XSCL to 1, which results in a TEXTXPOS of either 2 pixels for 80-column mode or 1 pixel for 40-column mode.&lt;/p&gt;
&lt;p&gt;In most cases, the easiest way to account for this is to disable HOTREG, set H640 as desired, then reset TEXTXPOS to its proper default of 80 pixels. With HOTREG disabled, the program has full control over the VIC-IV text position, and doesn&amp;rsquo;t have to account for the VIC-III bug or its compensation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CLRBIT $D05D,7 : REM Disable hot registers.
CLRBIT $D031,7 : REM Select 40-column mode.
POKE $D04C,80  : REM Reset TEXTXPOS to the standard 80 real pixels.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are other ways around this for unusual cases where you might want to keep HOTREG enabled or use VIC-II registers. If you think you have such a case, ask about it in the Discord.&lt;/p&gt;
&lt;h2 id=&#34;disabling-character-attributes&#34;&gt;Disabling character attributes&lt;/h2&gt;
&lt;p&gt;As you may recall, VIC-III character attributes add effects to text characters using the upper four bits of color memory: blink (bit 4), reverse (bit 5), bold (bit 6), and underline (bit 7). Low-res Multicolor Mode (MCM) disables these automatically to use those bits for another purpose, but the other modes keep them available.&lt;/p&gt;
&lt;p&gt;This includes the Super-Extended Attribute Modes. We were able to ignore this in our demonstrations of Full Color Mode (FCM), because color memory only stores the highest-value color for each character ($FF) and we left this unused and set to zero. You can, in fact, use the four text attributes in Full Color Mode by setting the appropriate bits of the high byte of color memory.&lt;/p&gt;
&lt;p&gt;In Nibble Color Mode, the four attribute bits serve a dual purpose—and we pretty much never want them to. When NCM is enabled for a character (bit 3 of the low byte of color memory), bits 4 through 7 of the high byte of color memory select one of the 16 sub-palettes used by the nibble values of the character. By default, these bits &lt;em&gt;also&lt;/em&gt; enable text effects.&lt;/p&gt;
&lt;p&gt;Thankfully, the VIC-III has a system-wide switch to disable text effects: the ATTR register, $D031 bit 5. Clearing this bit suppresses the text effects, so these bits can be used exclusively for sub-palette selection in Nibble Color Mode.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CLRBIT $D031,5&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;chrcount-and-linestep&#34;&gt;CHRCOUNT and LINESTEP&lt;/h2&gt;
&lt;p&gt;Recall that the LINESTEP register ($D058-$D059) tells the VIC how much screen and color memory is used for each character row. In normal text mode, an 80-column text screen uses 80 bytes of screen memory per row, one byte per character, so LINESTEP is 80. Enabling CHR16 doubles the amount of screen memory per character, so an 80-column screen needs a LINESTEP of 160.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s another register that tells the VIC how many characters are on each row. The CHRCOUNT register is 10 bits, with the lower 8 bits at $D05E, and the upper 2 bits at $D063.4-5. When the VIC draws a row, it counts the characters it is drawing left to right, then stops drawing once it sees CHRCOUNT characters.&lt;/p&gt;
&lt;p&gt;You can have more memory reserved per row by LINESTEP than is needed for CHRCOUNT characters—and we&amp;rsquo;ll see a reason why later in this article. You &lt;em&gt;cannot&lt;/em&gt; have a CHRCOUNT higher than the amount of memory reserved by LINESTEP; this causes the VIC to overrun each line&amp;rsquo;s memory. (I mean, you &lt;em&gt;can&lt;/em&gt; do this if you&amp;rsquo;re designing some oddball special effect. Don&amp;rsquo;t let some bossy newsletter stop you.)&lt;/p&gt;
&lt;p&gt;We didn&amp;rsquo;t need to address CHRCOUNT in previous experiments because we kept it at the default of 80, and always used a LINESTEP of either 80 with CHR16 disabled, or 160 with CHR16 enabled, so there was always enough memory for all 80 characters.&lt;/p&gt;
&lt;h2 id=&#34;tactical-strike-screen-settings&#34;&gt;Tactical Strike screen settings&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-redsoldier-ncm.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-redsoldier-ncm.png&#34;
            width=&#34;409&#34;
            height=&#34;226&#34;
            alt=&#34;The Tactical Strike red solider tile, as two NCM characters&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Tactical Strike red solider tile, as two NCM characters.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Here&amp;rsquo;s the full set-up sequence for drawing the Tactical Strike tile set on the screen, using a resolution of 320 x 200 (H640=0), SEAM enabled, and 20 NCM characters per row:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 CLRBIT $D05D,7 : REM Disable HOTREG
110 POKE $D04C,80  : REM Ensure TEXTXPOS is 80
120 CLRBIT $D031,5 : REM Disable ATTR
130 CLRBIT $D031,7 : REM Select 40-column mode (H640=0)
140 SETBIT $D054,0 : REM Enable SEAM (CHR16)
150 SETBIT $D054,2 : REM Enable FCLRHI
160 WPOKE $D058,40 : REM LINESTEP = 20 x 2
170 POKE $D05E,20  : REM CHRCOUNT = 20
180 WPOKE $D060,$0000 : WPOKE $D062,$05 : REM SCRNPTR = $5.0000&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For this simple demonstration of the tile set, the entire screen is filled with NCM characters. Each character is 16 pixels wide, and on a 320 x 200 display, that allows for 20 NCM characters per row. I can set CHRCOUNT to 20 and LINESTEP to 20 x 2 = 40 (two bytes per character), for a total of 25 rows = 40 x 25 = 1,000 bytes of screen and color memory. (Each tile is two rows tall, so I have a tile grid of 20 x 12, with one spare row.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-chrcount20.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-chrcount20.png&#34;
            width=&#34;519&#34;
            height=&#34;211&#34;
            alt=&#34;A full screen of 20 NCM characters, CHRCOUNT = 20, LINESTEP = 40&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A full screen of 20 NCM characters, CHRCOUNT = 20, LINESTEP = 40.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For an actual game, I&amp;rsquo;d probably declare some rows as the tile-based game board, and use other rows for 40-column text. Recall that FCLRLO and FCLRHI control which screen memory values refer to the character set indexes (screen codes) vs. FCM/NCM character addresses. By leaving FCLRLO clear, I can use the first 256 screen memory values to refer to the character set, either the default PETSCII set or a custom set that I can define in the usual ways.&lt;/p&gt;
&lt;p&gt;If I am going to use 40-column text for some rows, then I need to set LINESTEP and CHRCOUNT accordingly. The easiest thing to do is establish 40 characters per row, and just let the extra screen memory on the 20-character tile rows go unused.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-chrcount40.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-chrcount40.png&#34;
            width=&#34;590&#34;
            height=&#34;243&#34;
            alt=&#34;Rows of 20 NCM characters and 40 text/FCM characters, CHRCOUNT = 40, LINESTEP = 80&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Rows of 20 NCM characters and 40 text/FCM characters, CHRCOUNT = 40, LINESTEP = 80.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;tactical-strike-tiles-and-colors&#34;&gt;Tactical Strike tiles and colors&lt;/h2&gt;
&lt;p&gt;Tile set data will live at $4.0000. As we did last time, I have tile set and palette data in data files that I &lt;code&gt;BLOAD&lt;/code&gt; into appropriate memory locations. We can&amp;rsquo;t &lt;code&gt;BLOAD&lt;/code&gt; directly into palette registers, so I stash palette data temporarily then copy it in with a loop.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;190 BACKGROUND 1:BORDER 0
200 BLOAD &amp;#34;MPDATA.DAT,S&amp;#34;,R,P($40000) : REM Load char data
210 BLOAD &amp;#34;MPPAL.DAT,S&amp;#34;,R,P($1E000) : REM Load palette data
220 FOR I=0 TO 767:POKE $D100+I,PEEK($1E000+I):NEXT&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Recall that we don&amp;rsquo;t need to set CHARPTR for FCM/NCM characters: the screen memory value is an address, not a screen code. Specifically, the address is 64-byte aligned and divided by 64, so with NCM characters stored at $4.0000, the screen memory values are the tile character number plus $1000. Color #1 is the color of grass, so I set that to be the background color for now.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-ts-screenmem.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-ts-screenmem.png&#34;
            width=&#34;802&#34;
            height=&#34;300&#34;
            alt=&#34;A Tactical Strike tile in screen and character memory&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A Tactical Strike tile in screen and character memory.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I used my own Python script to convert the tile set from a PNG file to NCM character set data, and did some planning around the palette. Recall that each NCM character can only use one of sixteen sub-palettes of fifteen colors each plus the background color (value $0). The character&amp;rsquo;s color memory value selects the sub-palette used by the character, and also sets which color in this sub-palette is used if the character pixel is color 15 (hexadecimal $F).&lt;/p&gt;
&lt;p&gt;This makes it possible to reuse tile definitions with different sets of colors. This could come in handy for Tactical Strike! The tileset has tiles for five &amp;ldquo;teams,&amp;rdquo; each with the same set of vehicles, soldiers, and buildings drawn with different palettes. I only really need one set of vehicles et cetera for all five teams, and one sub-palette per team.&lt;/p&gt;
&lt;p&gt;For this demonstration, I wasn&amp;rsquo;t so clever. The original Kenney tile set uses a total of 36 palette entries, and (luckily) each tile uses fewer than 15 colors from this palette. I organized the tile set into groups that could share sub-palettes, and left it at that. I ended up with 14 tile groups, each using a sub-palette. The tiles don&amp;rsquo;t use the $F foreground color. I don&amp;rsquo;t necessarily recommend this approach, this was just the easiest thing to do given that the tile set was not drawn specifically for the MEGA65.&lt;/p&gt;
&lt;p&gt;In my code, the &lt;code&gt;TP()&lt;/code&gt; array stores the sub-palette ID (0 to 13) for each of the 198 tiles, which I prepare as 26 tiles using sub-palette 0, 18 tiles using sub-palette 1, and so on. This is based entirely on decisions I made in the Python script. When I draw a tile, I will select the tile&amp;rsquo;s color memory value from this array.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;230 DIM TP(198):Y=0
240 FOR P=0 TO 13:READ V
250 FOR I=0 TO V:TP(I+Y)=P:NEXT I
260 Y=Y+V
270 NEXT P
280 DATA 26,18,21,18,10,10,10,10,10,13,13,13,13,13&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;drawing-tactical-strike-tiles&#34;&gt;Drawing Tactical Strike tiles&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;re ready to draw some tiles on our grass-green field. Each tile is two NCM characters stacked vertically, and I made sure that both characters were next to each other in the character set data. To draw the first tile (tile #0), we would draw character #0 on the first row and character #1 on the second row, setting the color memory for each to &lt;code&gt;TP(0)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The following loop draws all 198 tiles in order, in rows left to right, top to bottom. The subroutine at line 1000 draws tile &lt;code&gt;T&lt;/code&gt; at tile position &lt;code&gt;(X,Y)&lt;/code&gt;. Remember that each SEAM character uses two bytes of both screen and color memory; 20 tiles (CHRCOUNT=20) require 40 bytes (LINESTEP=40). Read the subroutine carefully and try to figure out what each number represents.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;290 FOR T=0 to 197
300 Y=INT(T/20):X=MOD(T,20)
310 GOSUB 1000
320 NEXT T

325 REM Fill the rest with tile 0.
330 FOR P=198 TO 239
340 Y=INT(P/20):X=MOD(P,20):T=0
350 GOSUB 1000
360 NEXT P

999 GOTO 999

1000 O = Y*40*2 + X*2
1010 WPOKE $50000+O,$1000+T*2
1020 WPOKE $50000+O+40,$1000+T*2+1
1030 POKE $FF80000+O,8 : REM NCM bit
1040 POKE $FF80000+O+1,TP(T)*16 : REM Sub-palette for tile
1050 POKE $FF80000+O+40,8
1060 POKE $FF80000+O+40+1,TP(T)*16
1070 RETURN&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is enough to draw any tile at any position on the 20 x 12 grid. We could use this to draw a terrain map for the battle. We could also draw foreground tiles Ultima-style, with foreground replacing background, using the same subroutine. But we can do better.&lt;/p&gt;
&lt;h2 id=&#34;introducing-the-raster-rewrite-buffer&#34;&gt;Introducing the Raster Rewrite Buffer&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s time to pull back the curtain on the final major component of VIC-IV character graphics!&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re used to thinking of character graphics as a single field of character tiles arranged in a grid. The contents of screen memory describes which character in a character set appears at each grid location, arranged in memory as consecutive rows of equal length. As the raster beam marches down the screen, the VIC considers one row at a time, figuring out what color to set each pixel based on the screen code, the corresponding pixel data in the character set, and color memory. After the eighth line, the VIC moves on to the next row in screen and color memory.&lt;/p&gt;
&lt;p&gt;In normal text modes, it&amp;rsquo;s easy to imagine that the VIC sees in screen memory roughly what we see on the screen, arranged in a grid. When we introduced NCM characters, we got a hint that the VIC might be doing more than we think: each NCM character is 16 pixels wide instead of 8, and you can mix 16-wide NCM characters with 8-wide characters on the same row. The VIC isn&amp;rsquo;t just looking at 40 bytes for 40 characters in a row. It&amp;rsquo;s looking at CHRCOUNT characters at a time, and figuring out from each character on the row how to draw the line. Each character may have a different width, pushing the horizontal draw position a different amount for each character.&lt;/p&gt;
&lt;p&gt;You can think of the screen and color memory bytes as instructions that the VIC is following to draw the line: get character data from here, color data from there, use that to paint each pixel, then advance to the right by a certain amount. The VIC performs these instructions in order for the current row, and draws its calculated results into a &lt;em&gt;raster buffer.&lt;/em&gt; When it reaches the end of the row&amp;rsquo;s character count, the VIC feeds the raster buffer to the raster beam to draw the final image.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-flowers-and-soldier.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-flowers-and-soldier.png&#34;
            width=&#34;681&#34;
            height=&#34;427&#34;
            alt=&#34;Flowers and soldier&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Flowers and soldier.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So, how do we draw a soldier standing on a flower tile? We give the VIC a different kind of instruction! So far we&amp;rsquo;ve only seen screen and color values that describe a character to draw. You can also spend a character&amp;rsquo;s worth of screen and color memory to tell the VIC to change its state for drawing subsequent characters on the row. This non-character instruction identifies itself by setting a reserved bit of its SEAM color memory. When this bit is set, all 32 bits of screen and color memory for the non-character instruction tell the VIC what to do next.&lt;/p&gt;
&lt;p&gt;One of several things this non-character can tell the VIC to do is to &lt;em&gt;change the horizontal position&lt;/em&gt; of where characters are drawn in the raster buffer. This feature is so cool that the reserved bit is named after it: &lt;em&gt;the GOTOX flag.&lt;/em&gt; Because GOTOX can tell the VIC to go back and re-draw previous pixels on a line, the raster buffer is also known as the &lt;em&gt;Raster Rewrite Buffer&lt;/em&gt; (RRB).&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a way we can tell the VIC to draw a soldier tile on top of a flower terrain tile, in three character instructions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Draw the NCM character for the flower terrain tile.&lt;/li&gt;
&lt;li&gt;GOTOX: set the buffer write position back to the left edge of the flower terrain tile, and treat color $0 as transparent in subsequent characters.&lt;/li&gt;
&lt;li&gt;Draw the NCM character for the soldier tile.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-soldier-on-flowers.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-soldier-on-flowers.png&#34;
            width=&#34;737&#34;
            height=&#34;425&#34;
            alt=&#34;Soldier on flowers&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Soldier on flowers.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When the $0 pixels in the soldier tile are treated as transparent, they do not change the buffer contents. The flower tile appears &amp;ldquo;below&amp;rdquo; the soldier.&lt;/p&gt;
&lt;h2 id=&#34;gotox-horizontal-draw-position-and-transparency&#34;&gt;GOTOX, horizontal draw position, and transparency&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s see this in action. We will draw the flower terrain tile (tile #1) in the upper left corner. This will be followed by a GOTOX non-character instruction, then the red soldier tile (tile #183).&lt;/p&gt;
&lt;p&gt;We already know how to draw the NCM characters for instruction #1 and #3. For these characters, the GOTOX bit is clear, and the NCM bit (color memory byte 0 bit 3) is set.&lt;/p&gt;
&lt;p&gt;The GOTOX flag is color byte 0 bit 4. Setting this bit says this is a GOTOX instruction, not a character. The VIC does not draw a character for this instruction, even though the instruction occupies two bytes of screen memory and two bytes of color memory. All of the other bits in screen and color memory for a GOTOX instruction have new meaning.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-gotox-colmem.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-gotox-colmem.png&#34;
            width=&#34;614&#34;
            height=&#34;141&#34;
            alt=&#34;Color memory with GOTOX enabled: GOTOX flag, transparency flag&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Color memory with GOTOX enabled: GOTOX flag, transparency flag
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The horizontal position is a pixel coordinate, from the left border. This is a 10-bit value: screen byte 0 is the lower eight bits, and bits 0 and 1 of screen memory byte 1 are the two high bits.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-gotox-screenmem.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-gotox-screenmem.png&#34;
            width=&#34;584&#34;
            height=&#34;164&#34;
            alt=&#34;Screen memory with GOTOX enabled: X position (10 bits)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Screen memory with GOTOX enabled: X position (10 bits)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For this demonstration, we&amp;rsquo;re keeping tiles aligned with the tile grid, but we could easily use this horizontal pixel coordinate for more precise placement on the screen, or smooth movement animations. (And yes, there is a way to offset the draw position vertically. We&amp;rsquo;ll cover that in another Digest.)&lt;/p&gt;
&lt;p&gt;The last GOTOX property we&amp;rsquo;ll look at here is the transparency bit, color byte 0 bit 7. When set, this causes subsequent characters to not draw anything for pixels of color $0, allowing whatever was previously written into the buffer to shine through. When transparency is off, the screen background color is drawn for these pixels. Remember that this setting remains enabled for all subsequent characters on the row, or until it is changed by another GOTOX instruction.&lt;/p&gt;
&lt;p&gt;This code draws the solider on the flowers. (Note that CHRCOUNT and LINESTEP are not set correctly in this case: the GOTOX instruction is eating one of the 20 character slots! We&amp;rsquo;ll discuss this in a moment.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;290 REM Fill the tile 0.
300 FOR P=0 TO 239
310 Y=INT(P/20):X=MOD(P,20):T=0
320 GOSUB 1000
330 NEXT P

340 REM FLOWERS
350 WPOKE $50000,$1004
360 WPOKE $50028,$1005
370 WPOKE $FF80000,$0008
380 WPOKE $FF80028,$0008

390 REM GOTOX
400 WPOKE $50002,$0000
410 WPOKE $5002A,$0000
420 WPOKE $FF80002,$0090
430 WPOKE $FF8002A,$0090

440 REM RED SOLDIER
450 WPOKE $50004,$116E
460 WPOKE $5002C,$116F
470 WPOKE $FF80004,$C008
480 WPOKE $FF8002C,$C008&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;gotox-and-layers&#34;&gt;GOTOX and layers&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-composite_tiles.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-composite_tiles.png&#34;
            width=&#34;400&#34;
            height=&#34;333&#34;
            alt=&#34;A row of layered tiles&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A row of layered tiles: six terrain tiles, a red soldier with indicator, and a blue plane.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This simple example implies one way to draw the Tactical Strike playfield with background and foreground tiles: for each position, draw the entire stack of desired tiles, with a GOTOX to rewind back one tile position between each tile in the stack.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-layer-strat-1.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-layer-strat-1.png&#34;
            width=&#34;807&#34;
            height=&#34;107&#34;
            alt=&#34;Layer strategy 1: draw the entire tile stack at each position&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Layer strategy 1: draw the entire tile stack at each position.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This produces the result that we want, but has some disadvantages. For starters, this method is difficult for the program to manage. Tactical Strike will keep the background mostly the same, then move foreground objects around on the field. With GOTOX instructions scattered throughout, the program would have to recalculate the entire row for simple changes.&lt;/p&gt;
&lt;p&gt;Another method is to define a number of layers, allocate enough characters for each layer to span the entire playfield, then insert a GOTOX instruction between each layer (on each row) to reset the X position to 0 and enable transparency. The background fills the bottommost (first) layer, and other layers are filled with empty spaces and foreground objects.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-layer-strat-2.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-layer-strat-2.png&#34;
            width=&#34;475&#34;
            height=&#34;307&#34;
            alt=&#34;Layer strategy 2: draw each layer, padded with transparent spaces&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Layer strategy 3: draw each layer, padded with transparent spaces.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This is much easier on the program code: it can locate the memory for any tile at any position on any layer using simple math. In exchange, it uses a bunch of memory on empty spaces. Many games are similar to Tactical Strike in this way: the background layer is full, but foreground layers are sparse.&lt;/p&gt;
&lt;p&gt;For Tactical Strike specifically, I might go with a hybrid approach: for each row, draw the entire background, then follow it with a &amp;ldquo;draw list&amp;rdquo; of GOTOX instructions and tile characters. The program has to re-calculate the draw list on each row when stuff changes, but it can leave the large background layer alone, and locate each draw list with a simple multiplication.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-layer-strat-3.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/rrb-layer-strat-3.png&#34;
            width=&#34;811&#34;
            height=&#34;107&#34;
            alt=&#34;Layer strategy 3: draw the background, then draw foreground stacks&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Layer strategy 3: draw the background, then draw foreground stacks.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;allocating-memory-with-chrcount-and-linestep&#34;&gt;Allocating memory with CHRCOUNT and LINESTEP&lt;/h2&gt;
&lt;p&gt;To draw all of the tiles in a single layer 20 tiles across, I set CHRCOUNT to 20, and LINESTEP to 40 bytes = 2 bytes per tile for each of screen and color memory. Non-character instructions consume screen and color memory just like characters, and we&amp;rsquo;re piling more characters onto the row in layers, which also need more memory. I need to increase both CHRCOUNT and LINESTEP to account for all of these bytes, up to the maximum I expect to need for any given row.&lt;/p&gt;
&lt;p&gt;Say we have 20 tiles across, 12 tiles down, and 3 layers = 720 tile positions. Each row needs two bytes of screen memory per tile and per GOTOX instruction, and this would use two GOTOX instructions in addition to sixty tiles, for a total LINESTEP of 20 x 3 x 2 + 2 x 2 = 124. Each tile is two character rows, for a total of 2,976 bytes of screen memory and 2,976 bytes of color memory for the entire display.&lt;/p&gt;
&lt;p&gt;What about CHRCOUNT? CHRCOUNT must be at least the maximum number of characters and non-character GOTOX instructions in a row. 20 characters per layer plus one GOTOX instruction between each of three layers is 62 characters, so CHRCOUNT is 62.&lt;/p&gt;
&lt;p&gt;For SEAM graphics modes where each such character takes two bytes of screen memory, LINESTEP is twice as much as CHRCOUNT. Once again, we can ask: why is LINESTEP a register, and not calculated automatically from CHRCOUNT and CHR16? This is so the program can request a LINESTEP that makes addresses easier to calculate. For example, with our CHRCOUNT of 62, LINESTEP must be at least 124, but setting LINESTEP to 128 (and wasting a few bytes of memory per row) would allow each row to start at an address that&amp;rsquo;s a multiple of a large power of two: $5.0000, $5.0080, $5.0100, $5.0180, etc. This makes character addresses faster to calculate, especially in assembly language.&lt;/p&gt;
&lt;p&gt;In general:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;maximum characters + GOTOX per row = CHRCOUNT &amp;lt;= LINESTEP/2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I can minimize the amount of memory required for each row by designing my program carefully. The Tactical Strike playfield might be 20 tiles across, but if I limit the number of foreground objects and layered icons, I don&amp;rsquo;t need to allocate a full 20 tiles for each possible layer. The draw list method can be made to use less memory than the full-size layer method.&lt;/p&gt;
&lt;h2 id=&#34;rrb-cycle-cost-and-double-buffering&#34;&gt;RRB cycle cost and &amp;ldquo;double buffering&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;Why are we worrying so much about memory? CHRCOUNT is a 10-bit register, so there&amp;rsquo;s a logical maximum of 1,024 characters and GOTOX instructions on a row. That seems like plenty. But there&amp;rsquo;s another limit we need to consider. The VIC only has so much time during which it can mess with the Raster Rewrite Buffer before it has to start drawing to the screen. This limit is influenced by a couple of factors.&lt;/p&gt;
&lt;p&gt;The RRB has the option to use what the MEGA65 documentation calls &amp;ldquo;double buffering.&amp;rdquo; This isn&amp;rsquo;t double buffering in the sense of full animation frames, it just means that the VIC will prepare the buffer for a later line while an earlier line is being drawn to the screen. You can disable this if you&amp;rsquo;re doing something fancy, but in most cases it is sensible to leave it enabled. The register NORRDEL, $D051.7, should be clear to keep double buffering enabled.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;181 CLRBIT $D051,7&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&amp;rsquo;re using the lower vertical resolution of 200 pixels (as I am), you can double the amount of RRB mess-around time, in four steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set V400, $D031.3. Normally this enables a vertical resolution of 400 pixels, but we&amp;rsquo;re about to reverse this effect.&lt;/li&gt;
&lt;li&gt;Set CHRYSCL $D05B to 0. This scales text vertically back to size.&lt;/li&gt;
&lt;li&gt;Set the DBLRR register bit, $D051.6. This tells the VIC to spend twice as much time drawing into the RRB, drawing half as many lines. This brings the V400 resolution back down to 200 lines, and gets us the extra RRB time we need.&lt;/li&gt;
&lt;li&gt;Shift the start of text rendering up by two pixels: set TEXTYPOS $D04E to 102. With the extra draw time, the RRB needs text rendering to start underneath the top border, so it&amp;rsquo;s ready with the first line when the raster reaches the drawing area. I notice that with DBLRR enabled, TEXTYPOS must be an even number.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;182 SETBIT $D031,3
183 POKE $D05B,0
184 SETBIT $D051,6
185 POKE $D04E,102&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There have been multiple discussions in the MEGA65 Discord about how to measure and maximize RRB use—and work around bugs or unexpected behaviors. The most general advice is to experiment: figure out early what you want your program to do, then write short programs to determine what you can get away with.&lt;/p&gt;
&lt;p&gt;I did a brief test of the full-layer method using twelve rows of twenty NCM characters. I allocated a number of layers with CHRCOUNT and LINESTEP, then filled each layer with random tiles, one at a time. It handled 11 such layers without difficulty. Starting at 12 layers, my display started missing lines it didn&amp;rsquo;t have enough time to finish drawing. I would expect different results using FCM characters, or other modes or screen resolutions.&lt;/p&gt;
&lt;h2 id=&#34;a-quick-word-about-xemu&#34;&gt;A quick word about Xemu&lt;/h2&gt;
&lt;p&gt;Important note: You will see different edge case behaviors on a real MEGA65 vs. the Xemu emulator, so be sure to run your experiments on both. Xemu handled 12 layers fine, and saw a different failure mode at 13. With all of the above settings, I get &lt;em&gt;almost&lt;/em&gt; identical behavior on both real hardware and Xemu.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re in a jam trying to get things to look right on both platforms, there&amp;rsquo;s no shame in reading the REALHW register at $D60F.5, which is set to 1 on a real MEGA65 and 0 on Xemu, then changing settings accordingly. For example, you might want to tweak the top and bottom border positions, $D048 and $D04A respectively, based on which platform is running. I&amp;rsquo;ve noticed a one pixel difference between them in my tests.&lt;/p&gt;
&lt;h2 id=&#34;end-every-row-beyond-the-right-border&#34;&gt;End every row beyond the right border&lt;/h2&gt;
&lt;p&gt;There&amp;rsquo;s an important caveat when using GOTOX to position foreground objects on a playfield.&lt;/p&gt;
&lt;p&gt;When it&amp;rsquo;s time for the VIC to draw the raster buffer to the screen, it assumes that the last horizontal draw position it encounters is the end of the line. With the draw list method, the last character drawn might be somewhere in the middle of the screen. If we do nothing else, the VIC will assume that&amp;rsquo;s the right-hand border—and decline to copy the rest of the buffer to the screen. None of the characters at any layer will appear to the right of this position.&lt;/p&gt;
&lt;p&gt;The solution is to end the draw list with a GOTOX to the right border. Also, MEGA65 developers discovered that the GOTOX must be followed by a character for this to work consistently in both the MEGA65 and the Xemu emulator. Note that the program still has to fill the unused memory on a row with dummy characters when it calculates the draw list, otherwise a leftover GOTOX instruction might mess everything up.&lt;/p&gt;
&lt;hr&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/ts-gameplay-demo.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/ts-gameplay-demo.png 640w, https://dansanderson.com/mega65/raster-rewrite-buffer/ts-gameplay-demo_hu_2d2a5ada1ef0f18e.png 600w, https://dansanderson.com/mega65/raster-rewrite-buffer/ts-gameplay-demo_hu_590023b8c7ef023e.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/raster-rewrite-buffer/ts-gameplay-demo.png&#34;
        alt=&#34;Mock-up of Tactical Strike gameplay, rendered on the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Mock-up of Tactical Strike gameplay, rendered on the MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;That&amp;rsquo;s a good start! We now know enough to draw characters on top of other characters, which makes possible all kinds of graphics techniques. A simple version of Tactical Strike sticks to the character grid, but with pixel positioning and GOTOX, clearly more is possible. There&amp;rsquo;s more to explore!&lt;/p&gt;
&lt;p&gt;Tactical Strike also benefits from being a turn-based strategy game, so we could probably finish a pretty fun game written entirely in BASIC. Larger or faster games may need to be built in assembly language for speed. Eventually, we may need to tap in another MEGA65 feature we haven&amp;rsquo;t discussed in the Digest yet: the DMA.&lt;/p&gt;
&lt;p&gt;Thanks to everyone for your patience on the Digest release schedule. I&amp;rsquo;ll try to get this thing back on the monthly cadence, or at least come up with a new regular schedule so everyone knows what to expect.&lt;/p&gt;
&lt;p&gt;See you next time, and happy coding!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/raster-rewrite-buffer/M65Digest_2026Mar.mp3" length="" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>2561</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/raster-rewrite-buffer/roguecraft1.png"/>
      
    </item>
    
    <item>
      <title>Every Pixel a Color</title>
      <link>https://dansanderson.com/mega65/every-pixel-a-color/</link>
      <pubDate>Sat, 29 Nov 2025 17:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/every-pixel-a-color/</guid>
      <description>&lt;p&gt;Every Pixel a Color. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for November 2025.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Every Pixel a Color. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for November 2025.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/M65Digest_2025Nov.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/M65Digest_2025Nov.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Every Pixel a Color.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/everypixel.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/everypixel.png&#34;
            width=&#34;382&#34;
            height=&#34;428&#34;
            alt=&#34;A Commodore-style at symbol, with every pixel a different color.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A colorful @.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s November, and you know what that means: it&amp;rsquo;s time to level up our MEGA65 graphics knowledge! In this Digest, we reach another major milestone in our VIC-IV journey: full color character graphics. Type-ins galore, so warm up those coding fingers.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with the news, then get right at it.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;dans-mega65-digest-2025&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest 2025&lt;/h2&gt;
&lt;figure class=&#34;youtube-player&#34;&gt;
&lt;iframe
    width=&#34;600&#34;
    height=&#34;337&#34;
    src=&#34;https://www.youtube.com/embed/Rs1JZ4yi9w0&#34;
    title=&#34;Dan&amp;#39;s MEGA65 Digest 2025&#34;
    frameborder=&#34;0&#34;
    allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#34;
    allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;p&gt;Dan&amp;rsquo;s MEGA65 Digest 2025&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;My talk from Vintage Computer Festival Midwest 2025, &lt;a href=&#34;https://www.youtube.com/watch?v=Rs1JZ4yi9w0&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest 2025&lt;/a&gt;, is now online. This one looks at the MEGA65 through the lens of this very newsletter over the last few years. It&amp;rsquo;s a haphazard introduction to the platform, its capabilities, and its community (that&amp;rsquo;s you!).&lt;/p&gt;
&lt;p&gt;I tend to give these talks to audiences that still haven&amp;rsquo;t heard about us, so there&amp;rsquo;s always quite a bit of introductory overlap. Hopefully there&amp;rsquo;s enough new stuff, or at least enthusiastic review, for you to enjoy.&lt;/p&gt;
&lt;h2 id=&#34;spring-a-limited-edition-boxed-release&#34;&gt;Spring, a limited edition boxed release&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/spring_small_box_knick_knacks.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/every-pixel-a-color/spring_small_box_knick_knacks.jpg 824w, https://dansanderson.com/mega65/every-pixel-a-color/spring_small_box_knick_knacks_hu_908668b5bb9adcf0.jpg 600w, https://dansanderson.com/mega65/every-pixel-a-color/spring_small_box_knick_knacks_hu_348e8e8b2772f111.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/spring_small_box_knick_knacks.jpg&#34;
        alt=&#34;Spring, a limited edition boxed release by Gurce&amp;amp;#39;s family&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Spring, a limited edition boxed release by Gurce&amp;rsquo;s family.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Gurce&amp;rsquo;s artistic family is producing a limited edition boxed title for the MEGA65. Entitled &lt;em&gt;Spring&lt;/em&gt;, the game is designed by Gurce&amp;rsquo;s daughter, and will be distributed on floppy disk, with boxes and add-ons by Gurce&amp;rsquo;s sister.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Spring&lt;/em&gt; will be available to the MEGA65 community in strictly limited quantities. If you&amp;rsquo;d like one, contact Gurce on &lt;a href=&#34;https://discord.gg/tVpG4yx9Yu&#34;&gt;the Discord&lt;/a&gt;. Check out &lt;a href=&#34;https://gurce.net/spring/&#34;&gt;the game&amp;rsquo;s website&lt;/a&gt; for more information, poster art, and a guide to the game.&lt;/p&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/woods_of_peril.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/every-pixel-a-color/woods_of_peril.png 705w, https://dansanderson.com/mega65/every-pixel-a-color/woods_of_peril_hu_3b06dcc981285d0.png 600w, https://dansanderson.com/mega65/every-pixel-a-color/woods_of_peril_hu_ec4d961336b07deb.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/woods_of_peril.png&#34;
        alt=&#34;The Woods of Peril, by Lipi&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The Woods of Peril, by Lipi.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=533ca664-0661-4ff7-8c2d-4b41f6966d4c&#34;&gt;The Woods of Peril&lt;/a&gt; by Lipi, an original text and graphics adventure game. Music by Gurce. Navigate the forest with cursor keys: rotate left and right, move forward or backward. Follow on-screen prompts in villages and during battle.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=517596e7-aa25-459c-bd97-a12090857f9e&#34;&gt;Overlord&lt;/a&gt; by Drex. Navigate the maze and avoid the Overlord. Listen for his footsteps, avoid his line of sight, and try to make it to the end. Based on Drex&amp;rsquo;s own &lt;a href=&#34;https://files.mega65.org?id=08d0a958-d8a7-4f40-9fd8-2981584f3db9&#34;&gt;Alpha Maze&lt;/a&gt;. Use keyboard controls to move: W, A, S, D, and Q and E to rotate.&lt;/p&gt;
&lt;p&gt;Yet another core for your home arcade from muse, &lt;a href=&#34;https://files.mega65.org?id=b115db76-d9a9-4a93-b751-da34c80cfe1c&#34;&gt;Mr. Do!&lt;/a&gt; is now available. Collect cherries, avoid monsters, and defend yourself by pushing giant apples and throwing your ball.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;recap-two-and-four-colors-per-character&#34;&gt;Recap: Two and four colors per character&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/&#34;&gt;In the September Digest&lt;/a&gt;, we introduced Super-Extended Attribute Mode (SEAM) and the CHR16 register, a feature that allowed us to commit more memory to graphics to access more features. So far, we only got more screen codes out of the deal, but that&amp;rsquo;s a pretty big step up! We were able to fill screen memory with ascending screen codes to make a screen-wide bitmap quilt of monochromatic tiles.&lt;/p&gt;
&lt;p&gt;I left all of the foreground colors white in that example, but we could have proceeded to assign different foreground colors to each 8x8 patch, within the first 32 palette entries. Clever pixel artists know how to hide the color transitions between character boundaries. This gets especially interesting in combination with Low-res Multicolor Mode, like so:&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/mcm_stripes.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/mcm_stripes.png&#34;
            width=&#34;778&#34;
            height=&#34;433&#34;
            alt=&#34;Hiding character boundaries in MCM mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Hiding character boundaries in MCM mode.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In this example, the background color and two MCM colors are the same for every character on the screen, requiring careful planning to blend them with individual character foreground colors. And MCM doubles the visible width of the character pixels, potentially giving those characters a chunky look. Four possible colors per character provides more options, within these limitations.&lt;/p&gt;
&lt;h2 id=&#34;introducing-full-color-mode&#34;&gt;Introducing Full Color Mode&lt;/h2&gt;
&lt;p&gt;The MEGA65 can take this to the next level. In Full Color Mode (FCM), the VIC-IV can assign a different palette entry to each high resolution pixel of a character in a character set. Instead of one bit per pixel selecting between the character&amp;rsquo;s foreground color or the screen&amp;rsquo;s background color, FCM uses one &lt;em&gt;byte&lt;/em&gt; per pixel. Value $00 is still the background color, and $FF is the character foreground color. Values $01 to $FE select the corresponding colors directly off the palette.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/fcm_hex.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/fcm_hex.png&#34;
            width=&#34;695&#34;
            height=&#34;429&#34;
            alt=&#34;An FCM character, in 64 bytes&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An FCM character, in 64 bytes, with a custom palette
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We started &lt;a href=&#34;https://dansanderson.com/mega65/character-study/&#34;&gt;this series on character graphics&lt;/a&gt; with the observation that assigning a 23-bit color value to every pixel would be impractical. It uses too much memory, and by extension is too slow to update. A 640 x 200 screen with 23 bits for every pixel would require 359.375 kilobytes—nearly all of the MEGA65&amp;rsquo;s chip RAM for a single screen.&lt;/p&gt;
&lt;p&gt;Full Color Mode strikes a balance: it&amp;rsquo;s still character graphics, and it&amp;rsquo;s still indirectly specifying the 23-bit color with an 8-bit palette. A program like a game looking to update the display quickly can still do so with minimal memory changes, using references to character tiles. To perform our full-screen bitmap trick with 80 x 25 = 2,000 character codes, FCM would demand 64 bytes per character, or 128,000 bytes (125 kilobytes) of character set graphics data. That&amp;rsquo;s still a lot of memory, but it&amp;rsquo;s doable.&lt;/p&gt;
&lt;h2 id=&#34;important-facts-about-full-color-mode&#34;&gt;Important facts about Full Color Mode&lt;/h2&gt;
&lt;p&gt;There are two important things to know about Full Color Mode. The first is that FCM is a feature of Super-Extended Attribute Mode, and requires that CHR16 be enabled.&lt;/p&gt;
&lt;p&gt;The second important thing to know is that in Full Color Mode, screen memory does &lt;em&gt;not&lt;/em&gt; store screen codes. Instead, it stores the absolute address of the 64 bytes of character data. CHARPTR is &lt;em&gt;ignored&lt;/em&gt; for characters referenced in this way. For example, a screen code of $1000 (4096 decimal) refers to 64 bytes at address $1000 x $40 = $4.0000.&lt;/p&gt;
&lt;p&gt;A character address must be aligned to a 64-byte boundary: screen memory stores the address divided by 64. With CHR16 enabled, there are 13 bits of screen memory per character, with a maximum character address of $1FFF x 64 = $7FFC0 – $7FFFF. MEGA65 chip RAM only goes up to $5FFFF, so you effectively have all of chip RAM to store full-color graphics character tiles.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/chr16_screen.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/chr16_screen.png&#34;
            width=&#34;587&#34;
            height=&#34;114&#34;
            alt=&#34;A reminder of the 13 bits of screen memory in CHR16 mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
With FCM enabled, the 13 bits of screen memory store an absolute address divided by 64.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;m calling this out as important because it&amp;rsquo;s a common tripping point for developers learning FCM for the first time. This absolute address behavior is described in the manual, but the current state of this information is a series of brief paragraphs, so it&amp;rsquo;s easy to miss.&lt;/p&gt;
&lt;h2 id=&#34;fclrhi-and-fclrlo&#34;&gt;FCLRHI and FCLRLO&lt;/h2&gt;
&lt;p&gt;To enable FCM for screen codes 0 to 255, set register FCLRLO bit 1 of address $D054. To enable it for screen code 256 and higher, set register FCLRHI $D054 bit 2. Enabling FCM changes the interpretation of the affected screen codes to absolute 64-byte-aligned addresses.&lt;/p&gt;
&lt;p&gt;Having separate FCM switches for lower and upper screen codes makes it easy to support both traditional character sets and full-color graphics on the same screen. A common configuration is to keep FCLRLO clear and only set FCLRHI. This way, screen codes 0 to 255 continue to refer to a monochrome character set pointed to by the CHARPTR register, and screen codes 256 and above refer to absolute addresses $4000 and above.&lt;/p&gt;
&lt;p&gt;FCLRLO is therefore not particularly useful. All it does is enable the ability to refer to full-color character data at addresses $0.0000-$0.3FFF, which is not typically where a program would keep graphics data. And it trades away access to a monochrome font, such as the PETSCII font or a custom text font.&lt;/p&gt;
&lt;h2 id=&#34;implementing-full-color-mode&#34;&gt;Implementing Full Color Mode&lt;/h2&gt;
&lt;p&gt;FCM is a feature of SEAM, and requires that CHR16 be enabled: set bit 0 of $D054. As we saw &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/&#34;&gt;last Digest&lt;/a&gt;, this doubles the screen memory and color memory for each character to two bytes each. This also requires setting LINESTEP D058-D059 to twice the number of characters in each line (e.g. 160 bytes for 80 characters). We can&amp;rsquo;t reliably use the KERNAL screen editor&amp;rsquo;s default memory location for this, so we set SCRNPTR D060-D063 to somewhere more useful.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 REM === Enable CHR16. Set LINESTEP to 80 x 2 = 160.
110 SETBIT $D054,0
120 WPOKE $D058,160

130 REM === Set SCRNPTR to $5.0000. Remember previous setting.
140 S1 = WPEEK($D060) : S2 = WPEEK($D062)
150 WPOKE $D060,$0000 : WPOKE $D062,$05&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For this example, let&amp;rsquo;s use FCLRHI only, and leave FCLRLO clear, so we get the best of both worlds. Set bit 2 of $D054.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;160 REM === Set FCLRHI.
170 SETBIT $D054,2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&amp;rsquo;s the colorful &lt;code&gt;@&lt;/code&gt; symbol, written to address $4.0000.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;180 REM === FCM character
190 RESTORE 1000
200 FOR I=0 TO 63
210 READ V
220 POKE $40000+I,V
230 NEXT I

1000 DATA 0, 0, 1, 2, 3, 4, 0, 0
1010 DATA 0, 5, 6, 0, 0, 7, 8, 0
1020 DATA 0, 9,10, 0,11,12,13, 0
1030 DATA 0,14,15, 0,16,17,18, 0
1040 DATA 0,19,20, 0, 0, 0, 0, 0
1050 DATA 0,21,22, 0, 0,23,24, 0
1060 DATA 0, 0,25,26,27,28, 0, 0
1070 DATA 0, 0, 0, 0, 0, 0, 0, 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here&amp;rsquo;s a custom palette that matches my diagrams above. If you&amp;rsquo;re following along, you can skip this part, and just see the result in the default system palette.&lt;/p&gt;
&lt;p&gt;Remember that 8-bit color component values need the nibbles swapped before storing. Here, I&amp;rsquo;m swapping them in the &lt;code&gt;POKE&lt;/code&gt; statement, so that my &lt;code&gt;DATA&lt;/code&gt; statements look like the actual RGB values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;240 REM === Custom palette
250 RESTORE 1100
260 FOR C=0 TO 28
270 READ R,G,B
280 POKE $D100+C,((R AND 15) &amp;lt;&amp;lt; 4) OR (R &amp;gt;&amp;gt; 4)
290 POKE $D200+C,((G AND 15) &amp;lt;&amp;lt; 4) OR (G &amp;gt;&amp;gt; 4)
300 POKE $D300+C,((B AND 15) &amp;lt;&amp;lt; 4) OR (B &amp;gt;&amp;gt; 4)
310 NEXT C

1100 DATA 255,255,255
1110 DATA  82, 75, 36,  75,105, 47
1120 DATA 143,151, 74, 106,190, 48
1130 DATA  50, 60, 57, 102, 57, 49
1140 DATA  55,148,110, 217, 87, 99
1150 DATA  34, 32, 52,  69, 40, 60
1160 DATA 223,113, 38, 251,242, 54
1170 DATA 238,195,154,  63, 63,116
1180 DATA  48, 96,130, 172, 50, 50
1190 DATA 217, 87, 99, 215,123,186
1200 DATA  91,110,225,  99,155,255
1210 DATA 105,106,106,  95,205,228
1220 DATA  69, 40, 60,  63, 63,116
1230 DATA 132,126,135, 155,173,183
1240 DATA 203,219,252, 118, 66,138&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clear screen and color memory at our custom SCRNPTR location of $5.0000, remembering that both screen and color codes are two bytes now. Screen code 32 still refers to a PETSCII space, because FCLRLO is clear.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;320 REM === Clear screen
330 FOR I=0 TO 3999 STEP 2
340 WPOKE $50000+I,32
350 WPOKE $FF80000+I,0
360 NEXT I
370 REM === Set background and border to color 0,
380 REM === which in this custom palette is white.
390 BACKGROUND 0:BORDER 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly, draw a brief message, and our custom character:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;400 REM === Draw characters
410 RESTORE 1300
420 FOR I=0 TO 18 STEP 2
430 READ C
440 WPOKE $50000+I,C
450 POKE $FF80000+I+1,1 : REM Color bits are in the high byte
460 NEXT I
470 WPOKE $50000+(2*80*2)+4,$1000 : REM $40000/$40

1300 DATA 8, 5, 12, 12, 15, 32, 6, 3, 13, 33&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s round out the program by waiting for a keypress, then restoring the original screen settings.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;480 REM === Wait for spacebar
490 GETKEY A$:IF A$&amp;lt;&amp;gt;&amp;#34; &amp;#34; THEN 350
500 REM ==== Restore palette, FCLRHI, CHR16, LINESTEP, and SCRNPTR.
510 PALETTE RESTORE
520 CLRBIT $D054,2:CLRBIT $D054,0:WPOKE $D058,80
540 WPOKE $D060,S1:WPOKE $D062,S2
550 END&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/hello_fcm.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/hello_fcm.png&#34;
            width=&#34;444&#34;
            height=&#34;314&#34;
            alt=&#34;Display of the example program: a hello message and a single full-color character&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A monochrome message and a full-color character.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;nibble-color-mode-the-search-for-more-memory&#34;&gt;Nibble Color Mode: The Search for More Memory&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/ncm1.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/ncm1.png&#34;
            width=&#34;770&#34;
            height=&#34;568&#34;
            alt=&#34;A single character in Nibble Color Mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A single character in Nibble Color Mode.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;256 colors is a luxury, but sometimes memory is a luxury we can&amp;rsquo;t afford. And yet it is still useful to be able to use many colors in a single character. What else can we trade?&lt;/p&gt;
&lt;p&gt;In Nibble Color Mode (NCM), four bits describe a pixel, instead of eight. That gives us a respectable 16 colors to choose from for each pixel in a given character. Each pixel uses half as much memory as Full Color Mode.&lt;/p&gt;
&lt;p&gt;Hang onto your butts, because there&amp;rsquo;s a lot to know about Nibble Color Mode. We&amp;rsquo;ll take this one thing at a time.&lt;/p&gt;
&lt;h3 id=&#34;ncm-is-a-feature-of-a-character&#34;&gt;NCM is a feature of a character&lt;/h3&gt;
&lt;p&gt;Nibble Color Mode is not a system mode. It is a feature of an individual character, while in Full Color Mode. You tell a character to interpret its character set data as NCM instead of FCM by setting bit 3 of its color RAM value.&lt;/p&gt;
&lt;p&gt;Combined with keeping FCLRLO clear, this means you can mix monochrome (lower non-FCM chars), full color (upper FCM chars, color bit 3 clear), and nibble color (upper FCM chars, color bit 3 set) characters, all on the same screen.&lt;/p&gt;
&lt;h3 id=&#34;the-low-nibble-is-the-left-pixel&#34;&gt;The low nibble is the left pixel&lt;/h3&gt;
&lt;p&gt;With a character in Nibble Color Mode, each byte represents two horizontally adjacent pixels. The &amp;ldquo;lower&amp;rdquo; nibble in bits 0-3 of the character data is the &lt;em&gt;left&lt;/em&gt; pixel, and the &amp;ldquo;upper&amp;rdquo; nibble in bits 4-7 is the &lt;em&gt;right&lt;/em&gt; pixel. This is backwards from how we normally think of pixel order in monochrome pixel data, where the most significant bit is the left-most pixel.&lt;/p&gt;
&lt;h3 id=&#34;ncm-characters-are-16-pixels-wide&#34;&gt;NCM characters are 16 pixels wide&lt;/h3&gt;
&lt;p&gt;A character in Nibble Color Mode still uses 64 bytes to describe all of its pixels, 8 bytes per row. With two nibbles per byte, an NCM character is 16 pixels wide instead of 8! These are normal-sized pixels, not halved or doubled. The NCM character simply takes up more space on screen because it has more horizontal pixels. The character at the subsequent screen and color memory location starts at the horizontal position where the previous character left off.&lt;/p&gt;
&lt;p&gt;This is wild! For the first time in this series, we have to think of a character taking up a variable amount of space on a row depending on its properties. No longer can you say for sure that a character described at a given memory address has a given horizontal coordinate: its actual position depends on previous characters in the row.&lt;/p&gt;
&lt;p&gt;And here is our first clue as to the usefulness of the LINESTEP register. Each row takes up LINESTEP number of bytes in memory. In normal text mode, a row of 80 characters needs one byte per character, so LINESTEP = 80. In CHR16 mode with monochrome or FCM characters, a row of 80 characters needs two bytes per character, so LINESTEP = 160.&lt;/p&gt;
&lt;p&gt;If you have a screen full of &lt;em&gt;NCM&lt;/em&gt; characters, 640 pixels per row and 16 pixels per character means you have &lt;em&gt;40&lt;/em&gt; characters per row, each taking two bytes. In this case, you could set LINESTEP to 80, and avoid leaving a bunch of unused memory at the end of each row. You could even mix character modes on a row, and as long as you have a reliable maximum number of non-NCM characters, you could set LINESTEP accordingly.&lt;/p&gt;
&lt;p&gt;In later Digests, we will see other amazing things that the VIC-IV can do with its row-wise rendering, and find other uses for LINESTEP.&lt;/p&gt;
&lt;h3 id=&#34;ncm-can-pick-colors-from-any-group-of-16&#34;&gt;NCM can pick colors from any group of 16&lt;/h3&gt;
&lt;p&gt;The actual color of a pixel is a combination of the four-bit pixel data and the color value for the character in color RAM. The upper four bits of the color data for the character (bits 4-7 of color byte 1) are used as the upper four bits of the color value, and the character data nibble is the lower four bits. This allows multiple NCM characters to access all 256 colors of the palette on the same screen, with the limitation that only 16 at a time can be used for a given 16 x 8 NCM character.&lt;/p&gt;
&lt;p&gt;If the nibble value is $F, the color of the pixel is the full 8-bit color RAM value for the character.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/ncm_memory.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/ncm_memory.png&#34;
            width=&#34;698&#34;
            height=&#34;362&#34;
            alt=&#34;Calculating an NCM pixel color from the nibble and color value&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Calculating an NCM pixel color from the nibble and color value.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;That sounds complicated, but it&amp;rsquo;s quite powerful. We can use techniques similar to the VIC-II Low-res Multicolor Mode (MCM) blending trick we saw earlier to hide differences between characters, with many more color options at our disposal.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/hello_ncm.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/hello_ncm.png&#34;
            width=&#34;432&#34;
            height=&#34;340&#34;
            alt=&#34;Display of the example program: a hello message and a single nibble-color-mode character, repeated&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A monochrome message and two NCM characters, separated by a single space.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;converting-png-images-to-character-sets&#34;&gt;Converting PNG images to character sets&lt;/h2&gt;
&lt;p&gt;More powerful graphics features demand richer graphics data. You&amp;rsquo;re more than welcome to stick with the old-school methods of graph paper and &lt;code&gt;DATA&lt;/code&gt; statements. To fill a screen with color, you&amp;rsquo;re more likely to want to use graphics editing tools and image data converters.&lt;/p&gt;
&lt;p&gt;By far the most popular graphics editor for retro-style pixel graphics is &lt;a href=&#34;https://aseprite.org/&#34;&gt;Aseprite&lt;/a&gt;. It&amp;rsquo;s available for Windows, macOS, and Linux, for a lean one-time $20 purchase that&amp;rsquo;s worth every penny. Alternatively, you can opt for the free &lt;a href=&#34;https://libresprite.github.io/&#34;&gt;LibreSprite&lt;/a&gt;, which has a common origin with Aesprite. Aesprite gives you fine control over pixels and palettes, and allows you to animate your creations and export animation frames in a sprite sheet.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/aseprite.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/every-pixel-a-color/aseprite.png 1140w, https://dansanderson.com/mega65/every-pixel-a-color/aseprite_hu_f4bb2d497bb1e46a.png 600w, https://dansanderson.com/mega65/every-pixel-a-color/aseprite_hu_d0c3ea4515077d9f.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/aseprite.png&#34;
        alt=&#34;Aseprite, the venerable pixel graphics editor for Windows, macOS, and Linux.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Aseprite, the venerable pixel graphics editor for Windows, macOS, and Linux.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Tips for using Aseprite for MEGA65 graphics, and for conversion to other vintage or retro-style computers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set color mode to &amp;ldquo;indexed.&amp;rdquo; This tells Aseprite to save pixel data as palette entry numbers, and not RGB values for each pixel. Open the Sprite menu, Color Mode, then select Indexed.&lt;/li&gt;
&lt;li&gt;Set up your palette to match your desired MEGA65 graphics mode. If you&amp;rsquo;re using Full Color Mode, it&amp;rsquo;s easiest to establish a 256-color palette directly in Aseprite, and use the same palette for everything. You can save and load palettes from the Options button-menu above the palette on the lefthand side.&lt;/li&gt;
&lt;li&gt;Set image dimensions in multiples of 8, and draw tiles and sprites on 8-pixel boundaries, so you know your images align to characters.&lt;/li&gt;
&lt;li&gt;Export using the &lt;a href=&#34;https://en.wikipedia.org/wiki/PNG&#34;&gt;PNG&lt;/a&gt; file format, a &lt;a href=&#34;https://en.wikipedia.org/wiki/Lossless_compression&#34;&gt;lossless&lt;/a&gt; format that includes palette and image data in one file, when in indexed color mode.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;d love to nerd out on the PNG file format here like I did &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/&#34;&gt;with IFF&lt;/a&gt;, but you can read &lt;a href=&#34;https://en.wikipedia.org/wiki/PNG&#34;&gt;the Wikipedia article&lt;/a&gt; for details. Instead, we&amp;rsquo;ll use the &lt;a href=&#34;https://pypng.readthedocs.io/en/latest/&#34;&gt;PyPNG Python library&lt;/a&gt; to extract the data. To install this library from PyPI using &lt;code&gt;pip&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 -m pip install pypng&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Python, access the image data of the PNG exported from Aseprite like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import png

reader = png.Reader(filename=&amp;#39;Sprite-0001-export.png&amp;#39;)
width, height, pixels, metadata = reader.read()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If everything exported as expected, &lt;code&gt;metadata[&#39;palette&#39;]&lt;/code&gt; contains the RGB values for each palette entry, in order, as a tuple of three byte values. You can confirm that &lt;code&gt;metadata[&#39;bitdepth&#39;]&lt;/code&gt; is 8, which says each of the color values in the palette is a byte.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;pixels&lt;/code&gt; value is a list of pixel rows, where each row is &lt;code&gt;bytearray&lt;/code&gt; of palette entry numbers the width of the image. This is where most of the conversion work needs to happen: for FCM characters, the bytes need to be rearranged as 8-by-8 character tiles, where each tile&amp;rsquo;s bytes are organized row-wise top to bottom.&lt;/p&gt;
&lt;h2 id=&#34;a-simplified-png-conversion-example&#34;&gt;A simplified PNG conversion example&lt;/h2&gt;
&lt;p&gt;Here is my attempt at the simplest possible logic to convert a photograph to an almost-full-screen FCM display. I resized the photo to 640 x 192 image, so there&amp;rsquo;s enough room in banks 4 and 5 for both the FCM character data (640 x 192 = 122,880 bytes) and the CHR16 screen data (80 x 25 x 2 = 4,000 bytes). I exported the image with 8-bit indexed color and 256 palette entries.&lt;/p&gt;
&lt;p&gt;Then I used the following Python script to prepare the palette and image data as separate binary files. The &lt;code&gt;png&lt;/code&gt; library provides palette data as 256 &lt;code&gt;(r, g, b)&lt;/code&gt; tuples; the script swaps the nibbles for each value, then stores them as 256 reds, 256 greens, and 256 blues, to the file &lt;code&gt;mppal.dat&lt;/code&gt;. This is the format expected by the palette registers starting at $D100.&lt;/p&gt;
&lt;p&gt;To convert 192 pixel rows of 640 palette entries into FCM data, the script considers each 8 x 8 rectangle in character rows, writing the character image data in order to the file &lt;code&gt;mpdata.dat&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import png

FNAME_INPUT = &amp;#39;megaphoto.png&amp;#39;
FNAME_PAL = &amp;#39;mppal.dat&amp;#39;
FNAME_DATA = &amp;#39;mpdata.dat&amp;#39;

reader = png.Reader(filename=FNAME_INPUT)
width, height, rows, info = reader.read()
rows_lst = list(rows)

def nibble_swap(v):
  return ((v &amp;amp; 0x0f) &amp;lt;&amp;lt; 4) | ((v &amp;amp; 0xf0) &amp;gt;&amp;gt; 4)

reds = [nibble_swap(t[0]) for t in info[&amp;#39;palette&amp;#39;]]
greens = [nibble_swap(t[1]) for t in info[&amp;#39;palette&amp;#39;]]
blues = [nibble_swap(t[2]) for t in info[&amp;#39;palette&amp;#39;]]
with open(&amp;#39;mppal.dat&amp;#39;, &amp;#39;wb&amp;#39;) as f:
  f.write(bytes(reds))
  f.write(bytes(greens))
  f.write(bytes(blues))

with open(&amp;#39;mpdata.dat&amp;#39;, &amp;#39;wb&amp;#39;) as f:
  for ychar in range(height // 8):
    for xchar in range(width // 8):
      for y in range(8):
        for x in range(8):
          b = rows_lst[ychar * 8 + y][xchar * 8 + x]
          f.write(bytes([b]))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I put &lt;code&gt;mppal.dat&lt;/code&gt; and &lt;code&gt;mpdata.dat&lt;/code&gt; onto a D81 disk image, along with the following BASIC program. I&amp;rsquo;m using &lt;code&gt;BLOAD&lt;/code&gt; to load the data files. &lt;code&gt;BLOAD&lt;/code&gt; does not support loading data directly into registers, so I load the palette file into a temporary memory location first then copy the data into the registers. The character data is loaded to address $4.0000, with just enough room for screen memory at address $5.F060.&lt;/p&gt;
&lt;p&gt;The program fills screen memory with consecutive character addresses starting at $4.0000—similar to the monochrome bitmap example from the last Digest. It fills color memory with $FF00, so that any pixel from the image using color $FF actually uses palette entry $FF. Recall that a pixel valued as $FF is actually colored with the palette entry in color memory for the character, so color memory needs to be filled with high bytes of $FF to match the intent of the image.&lt;/p&gt;
&lt;p&gt;Because some color memory bits are treated as character attributes (blink, underline, reverse) by default, you must disable character attributes in this mode. You can do this by setting the ATTR register, bit 5 of $D031. All registers at this address trigger the &amp;ldquo;hot register&amp;rdquo; mechanism, so it&amp;rsquo;s important to do this early in the program, or disable hot registers per the instructions in the Compendium. (To save space here, we&amp;rsquo;ll discuss hot registers another time.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 REM === Set ATTR to enable 8-bit color memory (no attributes).
110 SETBIT $D031,5
120 REM === Enable CHR16. Set LINESTEP to 80 x 2 = 160.
130 SETBIT $D054,0
140 WPOKE $D058,160
150 REM === Set SCRNPTR to $5.F060. Remember previous setting.
160 S1 = WPEEK($D060) : S2 = WPEEK($D062)
170 WPOKE $D060,$F060 : WPOKE $D062,$05
180 REM === Set FCLRHI.
190 SETBIT $D054,2
200 REM === Load image chars to $4.0000.
210 BLOAD &amp;#34;MPDATA.DAT&amp;#34;,R,P($40000)
220 REM === Load palette to temp location, then copy.
230 BLOAD &amp;#34;MPPAL.DAT&amp;#34;,R,P($1E000)
240 FOR I=0 TO 767:POKE $D100+I,PEEK($1E000+I):NEXT I
250 REM === Fill screen.
260 FOR I=0 TO 1919 : REM Stop at 24 rows.
270 WPOKE $5F060+I*2,$1000+I
280 WPOKE $FF80000+I*2,$FF00
290 NEXT I
300 FOR I=1920 TO 1999 : REM Fill row 25 as empty.
310 WPOKE $5F060+I*2,32
320 WPOKE $FF80000+I*2,0
330 NEXT I
340 REM === Set background and border to color 0.
350 BACKGROUND 0:BORDER 0
360 REM === Wait for keypress, then reset.
370 GETKEY A$:IF A$&amp;lt;&amp;gt;&amp;#34; &amp;#34; THEN 370
380 PALETTE RESTORE
390 CLRBIT $D054,2:CLRBIT $D054,0:WPOKE $D058,80
400 WPOKE $D060,S1:WPOKE $D062,S2
410 END&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/every-pixel-a-color/fcmphoto_result.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/every-pixel-a-color/fcmphoto_result.png&#34;
            width=&#34;674&#34;
            height=&#34;429&#34;
            alt=&#34;A photograph displayed as FCM character graphics.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A photograph displayed as FCM character graphics, converted from a PNG file.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Of course, both the Python script and the BASIC loader could be expanded to accommodate images of any dimension and palette size. You could even invent a file format that includes dimensions, palette, and image data in a single file, ready to use with a general purpose image viewer based on FCM character graphics.&lt;/p&gt;
&lt;p&gt;A general purpose image converter would be nice, but I find it useful to know how to customize the conversion process. For example, a program using NCM graphics would need to know more about what should go into color memory, or how 16 x 8 NCM characters are organized on screen. A game with tiles or animations would need to know how the sprite sheet is arranged. Tools like Aseprite combined with custom data management are a part of a powerful retro gamedev workflow.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;We&amp;rsquo;re making great progress on our character graphics series, but there&amp;rsquo;s still some ground to cover! The MEGA65 has more tricks up its sleeve for more colors, fancier text rendering, and arcade graphics techniques. It&amp;rsquo;ll take a few more issues to cover it all.&lt;/p&gt;
&lt;p&gt;A quick note about the newsletter schedule. You may have noticed that I haven&amp;rsquo;t quite kept up a monthly cadence over the last few months. I know you&amp;rsquo;re OK with it, and I&amp;rsquo;m OK with it too, I just want to acknowledge it. As long as this Digest is a community resource, I owe it to you to at least send out community news on a regular basis. I&amp;rsquo;m planning one more issue in the 2025 calendar year. For 2026, I&amp;rsquo;m considering adjusting the format to post community news and feature articles separately. Expect some experimentation.&lt;/p&gt;
&lt;p&gt;This Digest is supported by cool people. If you&amp;rsquo;re a cool person, consider becoming a supporter for the new year. Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thanks all!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/every-pixel-a-color/M65Digest_2025Nov.mp3" length="" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1428</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/every-pixel-a-color/everypixel.png"/>
      
    </item>
    
    <item>
      <title>Super Extended Attribute Mode</title>
      <link>https://dansanderson.com/mega65/super-extended-attribute-mode/</link>
      <pubDate>Wed, 01 Oct 2025 00:18:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/super-extended-attribute-mode/</guid>
      <description>&lt;p&gt;Super Extended Attribute Mode. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for September 2025.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Super Extended Attribute Mode. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for September 2025.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/M65Digest_2025Sept.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/M65Digest_2025Sept.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Super Extended Attribute Mode.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color.png 1030w, https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color_hu_2b0a1cc6034e745d.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color_hu_ee2c7916654d0941.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color.png&#34;
        alt=&#34;All PETSCII characters and more, in all 32 colors and attribute combinations&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An assortment.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I just got back from the Vintage Computer Festival Midwest 2025 in Schaumburg, Illinois, USA. I ran another two-day MEGA65 exhibit, this time in collaboration with YouTuber &lt;a href=&#34;https://www.youtube.com/@retroCombs&#34;&gt;retroCombs&lt;/a&gt;. I also gave another talk, which was recorded and will be uploaded soon. It was great to meet up with friends old and new, and talk to many people interested in the MEGA65.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d make this Digest issue another trip review, but I have tarried too long on the next article in our character graphics series, and I shall tarry no longer! We&amp;rsquo;ll save the VCF photos for next month.&lt;/p&gt;
&lt;p&gt;That said, we have some major project announcements this month. It&amp;rsquo;s a jam-packed Digest, so let&amp;rsquo;s get started!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;who-remembers-the-commodore-65&#34;&gt;Who Remembers the Commodore 65?&lt;/h2&gt;
&lt;figure class=&#34;youtube-player&#34;&gt;
&lt;iframe
    width=&#34;600&#34;
    height=&#34;337&#34;
    src=&#34;https://www.youtube.com/embed/y8hUXd9Wmzg&#34;
    title=&#34;Who Remembers the Commodore 65?&#34;
    frameborder=&#34;0&#34;
    allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#34;
    allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;p&gt;Who Remembers the Commodore 65?&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The talk I gave at Vintage Computer Festival West 2025 in Mountain View, California, &lt;a href=&#34;https://youtu.be/y8hUXd9Wmzg?si=pwQDp9EkwQ2Vfvnw&#34;&gt;Who Remembers the Commodore 65?&lt;/a&gt;, is now up on YouTube. I had a good time with this, and hope to explore this thesis in more detail someday. I hope you like it!&lt;/p&gt;
&lt;h2 id=&#34;mega-ip&#34;&gt;Mega-IP&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/megaip.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/megaip.png 349w, https://dansanderson.com/mega65/super-extended-attribute-mode/megaip_hu_9df38610be4fea1.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/megaip_hu_b80199399bb15702.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/megaip.png&#34;
        alt=&#34;The BBS client from Mega-IP, by xlar54, connected to the RetroCampus.com BBS&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Mega-IP, by xlar54&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;xlar54 has released an initial version of &lt;a href=&#34;https://files.mega65.org?id=f5c206da-9fef-4a07-a54d-6149d8105a44&#34;&gt;Mega-IP&lt;/a&gt;, a TCP/IP networking stack for the MEGA65 intended for use from BASIC 65 programs. This release includes a simple telnet BBS client using the library. Mega-IP even supports &lt;em&gt;incoming&lt;/em&gt; connections, for potentially hosting a BBS or other services from a MEGA65. See &lt;a href=&#34;https://github.com/mega65-c65/mega-ip&#34;&gt;the Github repo&lt;/a&gt; for instructions and source code.&lt;/p&gt;
&lt;p&gt;Amazing work and thoughtfully designed. Looking forward to what else comes from this!&lt;/p&gt;
&lt;h2 id=&#34;super-mega-assembler&#34;&gt;Super Mega Assembler&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/sma.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/sma.png 1024w, https://dansanderson.com/mega65/super-extended-attribute-mode/sma_hu_339987e85eee6820.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/sma_hu_ade2ba2720b1344.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/sma.png&#34;
        alt=&#34;Super Mega Assembler, by Bobby Tables&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Super Mega Assembler, by 0x30507DE&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Bobby Tables (aka 0x30507DE) has released the first edition of &lt;a href=&#34;https://files.mega65.org?id=245e6201-bb18-4385-a932-7daf3a301c22&#34;&gt;Super Mega Assembler&lt;/a&gt;, a fork of Mega Assembler by grubi, using an all-new assembler engine implemented in machine code for speed. SMA is &amp;ldquo;self-hosting,&amp;rdquo; a milestone for any assembler or compiler written in its own language that says it is capable of building its own code. This on-device assembly language programming environment includes the original text editor.&lt;/p&gt;
&lt;p&gt;Visit the &lt;a href=&#34;https://discord.com/channels/719326990221574164/1398179170172928050&#34;&gt;#super-mega-assembler&lt;/a&gt; channel in the Discord to ask questions, or to read Bobby&amp;rsquo;s developer notes.&lt;/p&gt;
&lt;h2 id=&#34;megapet&#34;&gt;MegaPET&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/megapet.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/megapet.png 1000w, https://dansanderson.com/mega65/super-extended-attribute-mode/megapet_hu_71571ef9ed093df0.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/megapet_hu_d273019c1b34ce2.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/megapet.png&#34;
        alt=&#34;MegaPET, a Commodore PET core for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MegaPET, a Commodore PET core for the MEGA65&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Rhialto&amp;rsquo;s Commodore PET core &lt;a href=&#34;https://files.mega65.org?id=468325ae-7e27-475d-80e7-a0f0af409446&#34;&gt;MegaPET&lt;/a&gt; is now officially released! The core supports every known version of the PET, and comes packed with features. Check out &lt;a href=&#34;https://github.com/Rhialto/MegaPET/blob/rhialto/README.md&#34;&gt;the documentation&lt;/a&gt; for details.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s been a real pleasure watching Rhialto&amp;rsquo;s steady updates of this project on the Discord. Congrats on the launch!&lt;/p&gt;
&lt;h2 id=&#34;kings-quest-on-the-mega65&#34;&gt;King&amp;rsquo;s Quest on the MEGA65&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/kingsquest.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/kingsquest.png 705w, https://dansanderson.com/mega65/super-extended-attribute-mode/kingsquest_hu_591783cebda122e0.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/kingsquest_hu_4ea8516118c7f01a.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/kingsquest.png&#34;
        alt=&#34;King&amp;amp;#39;s Quest I, running on the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;King&amp;rsquo;s Quest I, running on the MEGA65&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;King&amp;rsquo;s Quest&lt;/em&gt;, the 1984 classic graphic adventure game by Roberta Williams and published by Sierra On-Line, runs on a game engine known as Adventure Game Interpreter (AGI). AwesomeDolphin has developed &lt;a href=&#34;https://files.mega65.org?id=315349e1-83e2-4be5-90ae-756b76c5a086&#34;&gt;Mega65-AGI&lt;/a&gt;, a MEGA65 version of the engine. You can now play the first game in the &lt;em&gt;King&amp;rsquo;s Quest&lt;/em&gt; series on your MEGA65!&lt;/p&gt;
&lt;p&gt;Similar to kibo&amp;rsquo;s &lt;a href=&#34;https://files.mega65.org?id=744279a9-7ee4-40c7-b34d-26d4c06d4685&#34;&gt;MEGASPUTM&lt;/a&gt;, which plays &lt;em&gt;Maniac Mansion&lt;/em&gt; by LucasArts, Mega65-AGI requires that you obtain the original &lt;em&gt;King&amp;rsquo;s Quest&lt;/em&gt; data files to play the game. You can purchase &lt;a href=&#34;https://www.gog.com/en/game/kings_quest_1_2_3&#34;&gt;the original game from GOG.com&lt;/a&gt;, and use the included Python script to merge the resource files into a playable D81 disk image.&lt;/p&gt;
&lt;p&gt;Congrats to AwesomeDolphin on this major accomplishment!&lt;/p&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;More that&amp;rsquo;s new on Filehost:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Speaking of MEGASPUTM, there&amp;rsquo;s &lt;a href=&#34;https://files.mega65.org?id=744279a9-7ee4-40c7-b34d-26d4c06d4685&#34;&gt;a new version&lt;/a&gt; that can play the Spanish language version of Maniac Mansion with the appropriate game data files.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Even more arcade cores from muse! Check &amp;rsquo;em out: &lt;a href=&#34;https://files.mega65.org?id=d1dce404-d484-472a-87ab-21755979d2fa&#34;&gt;Pitfall 2&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=77da28bd-99e0-4853-bd38-5e880078bc6d&#34;&gt;Wonder Boy in Monster Land&lt;/a&gt;, and &lt;a href=&#34;https://files.mega65.org?id=3c51011a-f228-49e7-b795-2b8afe6db5fa&#34;&gt;Choplifter&lt;/a&gt;. (Yes, there were arcade cabinet versions of these games!)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=08d0a958-d8a7-4f40-9fd8-2981584f3db9&#34;&gt;Alpha Maze&lt;/a&gt;, by Drex. A 3D maze generator with nice color gradients.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=6803dc2a-7989-41d0-814c-e1c6b2dcbedf&#34;&gt;Slidepuzzle 65&lt;/a&gt;, by BOBELE, the classic sliding tile puzzle.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=8322a9e6-96f9-4204-a73e-81882c2cb31e&#34;&gt;Heli-Demo&lt;/a&gt;, by SirGeldi, a short demo of a helicopter flying over smooth scrolling text. Use a joystick in port 2 to move the helicopter, and press the button to fire, Choplifter-style!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=d44e9cce-0a18-4857-8302-cf81f720b9ce&#34;&gt;Haiku - The Duel&lt;/a&gt;, by mk9. Select from a library of lines to construct a haiku, and try to outscore your computer opponent with the best poem.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;is-that-a-new-release-package&#34;&gt;Is that a new release package?&lt;/h2&gt;
&lt;p&gt;Filehost watchers have noticed that we have uploaded a new version of the MEGA65 platform. This is not a new release that you need to care about: the MEGA65 team is making a routine update to the mainboard to adjust for parts availability, and this inevitably requires small changes to the core. Neither the mainboard nor the release package have new features or bug fixes, and you don&amp;rsquo;t need to upgrade. We just do a new release when any supported board needs a change.&lt;/p&gt;
&lt;p&gt;We are hoping to do a new major platform release sometime soon. Watch the usual spaces for updates.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;eight-million-colors&#34;&gt;Eight million colors&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/green16.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/green16.png 312w, https://dansanderson.com/mega65/super-extended-attribute-mode/green16_hu_47725ed9eb928be6.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/green16_hu_1fc81b50d1cfd5f.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/green16.png&#34;
        alt=&#34;16 levels of green, from none to most&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
16 levels of green, from none to most.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/&#34;&gt;Back in July&lt;/a&gt;, we played with mixing red, green, and blue light to make new colors in the system palette. We saw that we could use 16 possible amounts of each component, from none (0) to most (15), for a total of 16 x 16 x 16 = 4,096 possible colors.&lt;/p&gt;
&lt;p&gt;Here are all of the colors we can make with 16 levels of green, and none of the red or blue:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 BACKGROUND 0:BORDER 0:SCNCLR
20 SA=WPEEK($D060)+WPEEK($D062)*65536
30 CA=$1F800
40 FOR C=0 TO 15
50 PALETTE COLOR C,0,C,0
60 POKE SA+C,160 : REM solid block character
70 POKE CA+C,C
80 NEXT C
90 GETKEY A$
100 PALETTE RESTORE&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;SA&lt;/code&gt; and &lt;code&gt;CA&lt;/code&gt; are the starting addresses for &lt;a href=&#34;https://dansanderson.com/mega65/character-study/&#34;&gt;screen and color memory&lt;/a&gt;, respectively. The &lt;code&gt;FOR&lt;/code&gt; loop populates the first 16 palette entries with the 16 possible green colors, and draws rectangles in the first 16 character positions, one for each color. We&amp;rsquo;re using BASIC 10&amp;rsquo;s &lt;code&gt;PALETTE&lt;/code&gt; command, which accepts the values 0 to 15 for each of the red, green, and blue amounts. &lt;code&gt;PALETTE RESTORE&lt;/code&gt; brings back the default system palette before exiting.&lt;/p&gt;
&lt;p&gt;The MEGA65 improves upon the Commodore 65&amp;rsquo;s 4,096 colors by allowing you to add fractional amounts of each color component. To each of these possible greens, you could add just a smidge more green to get a new shade, up to 16 possible smidgens of green, for a total of 256 possible green values in roughly the same range.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 BACKGROUND 0:BORDER 0:SCNCLR
20 SA=WPEEK($D060)+WPEEK($D062)*65536
30 CA=$1F800
35 SETBIT $D063,6:SETBIT $D016,4
40 FOR C=0 TO 15:FOR S=0 TO 15
50 POKE $D100+(C*16)+S,0
51 POKE $D200+(C*16)+S,(S*16)+C : REM see explanation
52 POKE $D300+(C*16)+S,0
60 POKE SA+(C*80)+S,160 : REM solid block character
70 POKE CA+(C*80)+S,(C*16)+S
80 NEXT S:NEXT C
90 GETKEY A$
95 CLRBIT $D063,6:CLRBIT $D016,4
100 PALETTE RESTORE&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/green256.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/green256.png 303w, https://dansanderson.com/mega65/super-extended-attribute-mode/green256_hu_58442e35e9a115e.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/green256_hu_9ba9404aefcf9401.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/green256.png&#34;
        alt=&#34;All 256 possible greens, from none to most &amp;#43; most smidgens&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
All 256 possible greens, from none to most + most smidgens.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There&amp;rsquo;s a lot going on in this example, but take a moment to notice that this displays 16 intermediate shades of green above each of the major 16 green values. In line 40, the &lt;code&gt;C&lt;/code&gt; variable is the major shade as before, and the &lt;code&gt;S&lt;/code&gt; is the smidgen of green that we&amp;rsquo;re adding. The brightest green in this example is just a bit brighter than the brightest green in the previous example, because we&amp;rsquo;ve added 15 smidgens.&lt;/p&gt;
&lt;p&gt;We can&amp;rsquo;t use the BASIC 10 &lt;code&gt;PALETTE&lt;/code&gt; command here, because it only supports the &amp;ldquo;major&amp;rdquo; values 0 to 15. Instead, this example POKEs directly to palette memory. The greens of the palette entries are at addresses $D200-$D2FF. Each value is an 8-bit byte: 4 bits for the major value, and 4 bits for the minor value.&lt;/p&gt;
&lt;p&gt;The MEGA65 has to do something clever to stay backwards compatible with the C65, which only supports the major value POKEd to the palette as the numbers 0 to 15. The MEGA65 stores the fractional (minor) color value in the upper bits of the byte. For example, if you want a palette entry to be 7 smidgens above the 3rd major green, you would store the 7 in the upper four bits (the upper &amp;ldquo;nybble&amp;rdquo;) and the 3 in the lower four bits:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3 = %0011
7 = %0111

%0111 0011 = $73 = 115

POKE $D200+P, $73&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This explains the unusual &lt;code&gt;(S*16)+C&lt;/code&gt; in line 51: &lt;code&gt;(S*16)&lt;/code&gt; pushes the smidgen value four binary places to the left, and &lt;code&gt;+C&lt;/code&gt; adds the major value to the lower four binary places. Doing this for every possible major value (&lt;code&gt;FOR C=0 TO 15&lt;/code&gt;) and every possible minor value (&lt;code&gt;FOR S=0 TO 15&lt;/code&gt;) gets us every possible green.&lt;/p&gt;
&lt;p&gt;Another way to think of this is, there are 256 possible green values, stored as a byte value 0 to 255, with the two nybbles swapped. The green of magnitude $37 (= 55) is stored in palette memory as the value $73 (= 115).&lt;/p&gt;
&lt;p&gt;There are 4 fractional bits available for green and blue, and 3 fractional bits available for red. The &amp;ldquo;least significant&amp;rdquo; red bit, in bit position 4 after the nybble swap, is reserved for a different purpose. With 23 bits to describe a color, that&amp;rsquo;s 2^23 or 8,388,608 possible colors, for each palette entry.&lt;/p&gt;
&lt;h2 id=&#34;about-that-reserved-red-bit&#34;&gt;About that reserved red bit&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/realnews.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/realnews.png 1243w, https://dansanderson.com/mega65/super-extended-attribute-mode/realnews_hu_4388eb6a45ea50c.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/realnews_hu_fa15e57317cb4fa7.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/realnews.png&#34;
        alt=&#34;A modern example of title compositing in a news broadcast&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A modern example of title compositing in a news broadcast.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Commodore 65 was intended to have a feature where its video output could be combined with another video signal, using an analog video synchronization technique called &lt;em&gt;genlock&lt;/em&gt;. Back in the day, this technique was used to generate titles or graphics that appeared over a video camera recording or live broadcast.&lt;/p&gt;
&lt;p&gt;Imagine using a Commodore 65 to generate the text that appears at the bottom of the screen of the nightly news. The C65 would produce a full screen image with the text at the bottom and the rest of the screen painted in a palette entry with this &amp;ldquo;transparency&amp;rdquo; bit set. When merged with the video camera signal, the news anchors would appear in the transparent portion.&lt;/p&gt;
&lt;p&gt;We actually do have a future use for the transparency bit on the MEGA65, specifically for the MEGAphone project. In general, for the most future-proofed results, keep bit 4 of red palette values written to $D100-$D1FF clear.&lt;/p&gt;
&lt;h2 id=&#34;full-palette-low-res-multicolor-mode&#34;&gt;Full-palette Low-res Multicolor Mode&lt;/h2&gt;
&lt;p&gt;In &lt;a href=&#34;https://dansanderson.com/mega65/character-study/&#34;&gt;Character Study&lt;/a&gt;, we said that each character can be assigned a five-bit value that identifies the color of the character from the first 32 entries of the palette. But if characters can only use up to 32 possible colors, how did the example above display 256 different shades of green?&lt;/p&gt;
&lt;p&gt;By using a new character graphics mode, of course! The magic is on line 35, and the original text mode is restored on line 95. Let&amp;rsquo;s take a closer look.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;35 SETBIT $D063,6:SETBIT $D016,4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/&#34;&gt;Taste the Rainbow&lt;/a&gt; we introduced Low-res Multicolor Character Mode, or MCM. In this mode, characters can be either in high resolution (8 pixels across) with a single foreground color, or in low resolution (4 double-wide pixels across) with a choice of a character-specific foreground color or two screen-wide alternate colors for each pixel. MCM is enabled by setting bit 4 of register $D016.&lt;/p&gt;
&lt;p&gt;For the character-specific foreground color, Low-res Multicolor Mode ignores color bits 4 through 7, and character attributes are disabled. In this new Full-palette Low-res Multicolor Mode, all eight color bits identify the foreground palette entry, from 0 to 255. To enable Full-palette Low-res Multicolor Mode, set bit 6 of register $D063 (FCOLMCM), in addition to bit 4 of register $D016.&lt;/p&gt;
&lt;p&gt;One oddity of this mode is that it still behaves like MCM: if color bit 3 is set, the character image is rendered in bit-pair low resolution. This means that half of the palette entries render in low-res mode, and the other half in hi-res mode. In the greens example, we used the block glyph at screen code 160, which looks the same in both modes. To see the difference color bit 3 makes, change line 60 to replace the 160 screen code with, say, 65. Half of the shapes look different.&lt;/p&gt;
&lt;p&gt;I can&amp;rsquo;t think of a reason why we couldn&amp;rsquo;t also have a full-palette non-MCM mode, using just the FCOLMCM register bit 6 of $D063, replacing attribute bits for color bits without the MCM feature. I filed this as &lt;a href=&#34;https://github.com/MEGA65/mega65-core/issues/916&#34;&gt;a feature request&lt;/a&gt;. (I could be forgetting a detail that prevents this from being a good idea. It&amp;rsquo;s difficult to keep track of all of the video mode combinations!)&lt;/p&gt;
&lt;h2 id=&#34;introducing-super-extended-attribute-mode&#34;&gt;Introducing Super-Extended Attribute Mode&lt;/h2&gt;
&lt;p&gt;All of the character graphics modes we&amp;rsquo;ve seen so far have given us new ways to draw pictures, but they have insisted that we trade away features such as resolution or available characters in exchange for more colors. Tradeoffs are necessary because all of these modes use the same amount of memory for a given screen size: one byte of screen memory and one byte of color memory for each character. If we want to go further—and further we must go!—we need a screen mode that lets us exchange &lt;em&gt;memory&lt;/em&gt; for features.&lt;/p&gt;
&lt;p&gt;Super Extended Attribute Mode (or &amp;ldquo;SEAM&amp;rdquo;) is one of the VIC-IV&amp;rsquo;s big upgrades to Commodore character graphics. Enabling it doubles the amount of memory used for each character: 16 bits (or two bytes) of screen memory and 16 bits of color memory. This both expands the possible size of the character set and makes room for additional rendering features on a character-by-character basis (the &amp;ldquo;super-extended&amp;rdquo; attributes).&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll stay in BASIC for the rest of this Digest just to make it easy to experiment. Similar to other ways we&amp;rsquo;ve tried messing with the VIC-IV registers, the KERNAL screen editor doesn&amp;rsquo;t know anything about SEAM, so you can&amp;rsquo;t use its cursor-like printing features in these modes. The only way to take advantage of SEAM is to write directly to screen and color memory. In practice, these modes are easier to use from machine language, where we can do high-speed manipulation of memory.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-seam&#34;&gt;Setting up SEAM&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s set up a program that enables SEAM, waits for a keypress, then disables SEAM and returns to the READY prompt. We can put our experiments in the middle.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Set the CHR16 register, bit 0 of register D054. The VIC-IV reads two consecutive bytes per character, of both screen memory and color memory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SETBIT $D054,0

900 GETKEY A$

990 CLRBIT $D054,0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Set the &lt;em&gt;line step&lt;/em&gt; according to the desired horizontal resolution. The LINESTEP register at D058-D059 is the number of bytes that make up each line of characters. In normal 80-column text mode, this value is 80, one byte per character. SEAM doubles the number of bytes per character, so if we&amp;rsquo;re staying in 80-column mode, the new value is 160. This may feel superfluous, but the LINESTEP register will come back in a big way in a later Digest!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;20 WPOKE $D058,160

980 WPOKE $D058,80&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Recall that 80-column text mode is controlled by the H640 register, D031 bit 7. You could switch to 40-column mode by clearing this bit, then set LINESTEP to 80, for forty columns of 16-bit screen and color codes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Set SCRNPTR D060-D063 to a memory location where we can put 80x25x2 bytes of screen memory. Let&amp;rsquo;s use $4.0000 for now.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;30 O1=WPEEK($D060):O2=WPEEK($D062)
40 WPOKE $D060,$0000:WPOKE $D062,$0004

970 WPOKE $D060,O1:WPOKE $D062,O2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Recall that the &lt;code&gt;WPEEK()&lt;/code&gt; function takes an address, and returns the 16-bit value stored in two bytes, in little endian format. Similarly, the &lt;code&gt;WPOKE&lt;/code&gt; command takes an address and a 16-bit value, then writes the value as two bytes. Line 30 uses two &lt;code&gt;WPEEK()&lt;/code&gt; calls to read the 32-bit SCRNPTR address into two variables. Line 40 sets SCRNPTR to address $0004.0000, using two &lt;code&gt;WPOKE&lt;/code&gt; calls. The original SCRNPTR setting is restored in line 970, as the program is exiting.&lt;/p&gt;
&lt;p&gt;If you run this program now (and you should!), you&amp;rsquo;ll see whatever is sitting in screen and color memory, interpreted as two bytes per character. Press a key to restore normal text mode and the original SCRNPTR value.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Clear the screen. We&amp;rsquo;ll explain how this works in a moment, but for now, add this to the program to start from a clean slate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;50 FOR P=0 TO 80*25*2-1 STEP 2
60 WPOKE $40000+P,32  : REM SCREEN CODE
70 POKE $FF80000+P,0
80 POKE $FF80000+P+1,1 : REM COLOR + ATTR
90 NEXT P

960 FOR P=0 TO 80*25-1:POKE $FF80000+P,1:NEXT P&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;FOR&lt;/code&gt; loop visits every character position in memory: 80 columns, 25 rows, 2 bytes per character.&lt;/p&gt;
&lt;p&gt;Line 60 writes a space character (screen code 32) to each character position in screen memory, which we relocated to $4.0000. It uses &lt;code&gt;WPOKE&lt;/code&gt; to treat &amp;ldquo;32&amp;rdquo; as two bytes, with the least significant byte (32) first and the most significant byte (0) second.&lt;/p&gt;
&lt;p&gt;Line 70 and 80 write two bytes to color memory: the first byte is a 0, and the second byte is the color white (1) with no character attributes.&lt;/p&gt;
&lt;p&gt;On exit, line 960 revises color memory for our normal text display, with all white text. We&amp;rsquo;re reusing the same color memory for both our normal display and the CHR16 display, but they use different data formats, so we need to put things back in order before switching off CHR16. Another option would be to relocate color memory the way we did screen memory to preserve the colors of the original normal-text display.&lt;/p&gt;
&lt;h2 id=&#34;using-chr16-screen-codes&#34;&gt;Using CHR16 screen codes&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_screen.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_screen.png 587w, https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_screen_hu_4d33d1fa8118b816.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_screen_hu_602f5bee4b9b63c3.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_screen.png&#34;
        alt=&#34;The 13 screen code bits in CHR16 mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The 13 screen code bits in CHR16 mode
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In CHR16 mode, each character gets two bytes of screen memory. This includes 13 bits for the screen code, and 3 bits for another feature that we&amp;rsquo;ll ignore for now. The screen code bits are arranged with the 8 least significant bits in the first byte, and the 5 most significant bits at the bottom of the second byte. As long as you&amp;rsquo;re not using the unmentioned feature, you can treat this as a 13-bit number stored in little endian format, and leave the last three bits set to zero.&lt;/p&gt;
&lt;p&gt;In normal text mode, screen codes are 8 bits (one byte) wide, for a character set of 256 possible characters. In CHR16 mode, you can write any byte value from 0 to 255 to the first byte, with zero as the second byte, to see these characters as usual. Here&amp;rsquo;s our familiar PETSCII uppercase set, as four rows of 64 characters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 FOR R=0 TO 3
110 FOR C=0 TO 63
120 WPOKE $40000+(R*80+C)*2,R*64+C
130 NEXT C
140 NEXT R&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii256.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii256.png 1033w, https://dansanderson.com/mega65/super-extended-attribute-mode/petscii256_hu_6cc1aa8b2d7cfd68.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/petscii256_hu_36444eb931cbd09f.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii256.png&#34;
        alt=&#34;The familiar PETSCII uppercase character set, in 256 screen codes&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The familiar PETSCII uppercase character set, in 256 screen codes.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Notice that we can&amp;rsquo;t use the BASIC &lt;code&gt;T@&amp;amp;&lt;/code&gt; special array as we did &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/&#34;&gt;last month&lt;/a&gt;, because BASIC knows nothing about custom screen memory locations or CHR16 mode. Instead, we calculate the address and screen code for each location. We used a similar technique to &lt;code&gt;POKE&lt;/code&gt; the PETSCII screen codes in &lt;a href=&#34;https://dansanderson.com/mega65/character-study/&#34;&gt;an earlier Digest&lt;/a&gt;. Here, we use &lt;code&gt;WPOKE&lt;/code&gt; and increment two bytes at a time to write the full CHR16 screen memory value.&lt;/p&gt;
&lt;p&gt;8-bit screen codes can describe 256 possible characters. SEAM expands this to 13 bits, for a whopping 8,192 characters in a single character set! The easiest way to see this in action is to update the program to display more rows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 FOR R=0 TO 24&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512.png 1027w, https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_hu_dd7b451de3b75dd8.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_hu_2369a533ffc38622.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512.png&#34;
        alt=&#34;Both uppercase and lowercase character sets on the same screen, and a whole lot more&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Both uppercase and lowercase character sets on the same screen, and a whole lot more.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Check it out: lowercase letters and PETSCII graphics characters on the same screen! As usual, the VIC uses the character set memory pointed to by CHARPTR D068-D06A, and locates the image data for a given character by counting up by 8 bytes per character, up to the given screen code. With CHARPTR pointing at the PETSCII font, screen codes 0 to 255 refer to the PETSCII uppercase + graphic characters, and codes 256 to 511 refer to PETSCII lowercase + uppercase, because both sets are next to each other in memory.&lt;/p&gt;
&lt;p&gt;But that&amp;rsquo;s not all! There are plenty more characters available beyond 511. For now, the memory the VIC sees is filled with non-character data, so it looks like random snow. A game or application can install all manner of game graphics, alternate typefaces, or frames of animation in this memory. Thanks to CHR16 mode, they can all live happily on the same screen.&lt;/p&gt;
&lt;p&gt;That is, if you&amp;rsquo;re willing to spend the memory. To use all 8,192 possible characters in a single character set, you need to dedicate 8,192 x 8 = 65,536 bytes—the entire available RAM of a Commodore 64—to character set data. If you don&amp;rsquo;t need that much, just don&amp;rsquo;t use all of the screen codes.&lt;/p&gt;
&lt;h2 id=&#34;using-chr16-color-and-attribute-codes&#34;&gt;Using CHR16 color and attribute codes&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_color.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_color.png 585w, https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_color_hu_77534aae5aa2fc75.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_color_hu_636873ad2094442b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/chr16_color.png&#34;
        alt=&#34;The 8 color and attribute bits in CHR16 mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The 8 color and attribute bits in CHR16 mode
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Similar to screen memory, CHR16 mode doubles the amount of color memory used to describe each character. Only the second of the two bytes is used for actual color and attribute data, and this byte alone provides no additional color or character attribute features. This may be disappointing to hear at first, but the remaining eight bits are used for graphics features &lt;em&gt;so powerful&lt;/em&gt; that we&amp;rsquo;ll have to discuss them in a later Digest.&lt;/p&gt;
&lt;p&gt;As with normal text mode, the second byte of character memory can select from the first 32 palette entries for a character&amp;rsquo;s foreground color, using bits 0, 1, 2, 3, and 6. And as with normal text mode, bit 4 is a blink effect, bit 5 is a reverse effect, and bit 7 gives the character an underline.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a quick way to see all of the characters displayed in 32 colors with all of the attribute combinations. It&amp;rsquo;s a bit garish, but it gets the point across.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;121 POKE $FF80000+((R*80)+C)*2,0
122 POKE $FF80000+((R*80)+C)*2+1,R*64+C AND 255

950 PALETTE RESTORE&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color.png 1030w, https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color_hu_2b0a1cc6034e745d.png 600w, https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color_hu_ee2c7916654d0941.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color.png&#34;
        alt=&#34;32 colors and all combinations of three attributes, in CHR16 mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
32 colors and all combinations of three attributes, in CHR16 mode.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Note that this cannot be combined with the Full-palette Low-res Multicolor Mode we used for the 256 greens earlier. There&amp;rsquo;s another way to get more color in SEAM. We&amp;rsquo;ll take a good look at that in the next Digest.&lt;/p&gt;
&lt;h2 id=&#34;the-mega65s-not-so-secret-bitmap-mode&#34;&gt;The MEGA65&amp;rsquo;s not-so-secret bitmap mode&lt;/h2&gt;
&lt;p&gt;With as many as 8,192 screen codes at our disposal, we can have all manner of graphics tiles on the screen in any combination. Imagine &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/&#34;&gt;Crossroads&lt;/a&gt; with &lt;em&gt;hundreds&lt;/em&gt; of enemy types.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s another thing we can do with such a large character set. On a screen 80 characters across and 25 characters down, there are 2,000 characters visible at any time. With CHR16 mode, we can put a different character in every screen location.&lt;/p&gt;
&lt;p&gt;Our test program was displaying characters 64 per row just to keep the PETSCII character set tidy. To completely fill the screen with unique characters requires only a modest change to the loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 FOR R=0 TO 24
110 FOR C=0 TO 79
120 WPOKE $40000+(R*80+C)*2,R*80+C
130 NEXT C
140 NEXT R&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What&amp;rsquo;s the big deal? With the screen filled with the first 2,000 characters of the character set, the character set &lt;em&gt;is the screen.&lt;/em&gt; We can draw individual pixels onto the display by updating the character set!&lt;/p&gt;
&lt;p&gt;One more flashback to &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/&#34;&gt;the previous Digest&lt;/a&gt;: The character set describes what each character looks like as a monochrome set of pixels. Each character is eight pixels across and eight pixels down, represented as eight bytes from top to bottom, most significant bit on the left. You can store the character set anywhere in the first 384 KB of memory. The CHARPTR register D068-D06A stores the starting address.&lt;/p&gt;
&lt;p&gt;For a character set of 2,000 characters and eight bytes per character, we need 16,000 bytes, or 15 KB. We&amp;rsquo;ve put 2,000 x 2 = 4,000 bytes of screen memory for our tapestry at address $4.0000, so we can put the character set immediately after it at address $4.0FA0.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;150 WPOKE $D068,$0FA0:POKE $D06A,$04

940 WPOKE $D068,$1000:POKE $D06A,$00&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&amp;rsquo;s one way to clear the character set so every character is an empty space:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;160 FOR I=0 TO 15999:POKE $40FA0+I,0:NEXT I&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now for the tricky bit. This 640 x 200 pixel screen is organized into little 8 x 8 pixel stacks. To light up a specific pixel, we need to figure out which bit in which byte represents the pixel, then update that byte. Feel free to try this little math problem on your own.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what I came up with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;190 X = 300
200 Y = 100
210 AD = $40FA0 + ((Y &amp;gt;&amp;gt; 3) * 80 + (X &amp;gt;&amp;gt; 3)) * 8 + (Y AND 7)
220 SETBIT AD, 7-(X AND 7)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If this looks confusing, notice that &lt;code&gt;Y &amp;gt;&amp;gt; 3&lt;/code&gt; is the same as &lt;code&gt;INT(Y / 8)&lt;/code&gt;, that is, divide Y by 8 and drop the remainder. &lt;code&gt;Y AND 7&lt;/code&gt; is the same as the remainder that was dropped when dividing Y by 8. With 8 as the divisor, it&amp;rsquo;s faster to do this with bitwise math, and is how you would do it in machine language. &lt;code&gt;7-(X AND 7)&lt;/code&gt; is the bit number of the byte to change, with 7 being the leftmost bit.&lt;/p&gt;
&lt;p&gt;Now that we can draw a dot at a given set of coordinates, we can do something fun, like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;190 FOR X = 0 TO 639
200 Y = INT(SIN(X/640 * 2 * π) * 100) + 100

230 NEXT X&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;ve filled the screen with the entire character set, and are drawing pixels directly onto the character set, for a bitmap graphics display. Pretty neat!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Thanks for sticking with me through this series on character graphics. Each new concept is built on the last, and we still have at least two more major topics to cover.&lt;/p&gt;
&lt;p&gt;This marks the &lt;em&gt;40th issue&lt;/em&gt; and the &lt;em&gt;three year anniversary&lt;/em&gt; of Dan&amp;rsquo;s MEGA65 Digest. I&amp;rsquo;m grateful to everyone for their support throughout this project. I couldn&amp;rsquo;t do this without you.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re finding this newsletter valuable, and I hope you are, consider becoming a supporter of the Digest. Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t touch that dial! More to come!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/super-extended-attribute-mode/M65Digest_2025Sept.mp3" length="" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1542</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/super-extended-attribute-mode/petscii512_color.png"/>
      
    </item>
    
    <item>
      <title>So Many Things</title>
      <link>https://dansanderson.com/mega65/so-many-things/</link>
      <pubDate>Fri, 15 Aug 2025 18:00:49 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/so-many-things/</guid>
      <description>&lt;p&gt;So Many Things. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for August 2025.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;So Many Things. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for August 2025.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/so-many-things/M65Digest_2025Aug.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/M65Digest_2025Aug.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
So Many Things.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/mega_vcfw.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/mega_vcfw.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/mega_vcfw_hu_62884f2e6cbbce0e.jpeg 600w, https://dansanderson.com/mega65/so-many-things/mega_vcfw_hu_3db47be3b4850f.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/mega_vcfw.jpeg&#34;
        alt=&#34;MEGA65 at VCF West 2025&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGA65 at VCF West 2025.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I haven&amp;rsquo;t been slacking, I swear! In fact, so much MEGA65 stuff has been going on in the last couple of months that I haven&amp;rsquo;t had time to work on feature articles for the Digest. I&amp;rsquo;m excited to have had the opportunity to contribute to both the Commodore International and Compute!&amp;rsquo;s Gazette revival projects. And I was able to present a talk &lt;em&gt;and&lt;/em&gt; run an exhibit at Vintage Computer Festival West at the Computer History Museum in Mountain View, California.&lt;/p&gt;
&lt;p&gt;Meanwhile, multiple talented people have released MEGA65 games and videos in the last month, so many that I haven&amp;rsquo;t had a chance to play them all until now. Let&amp;rsquo;s catch up a bit! We&amp;rsquo;ll pick up our color graphics series next issue, fingers crossed.&lt;/p&gt;
&lt;h2 id=&#34;the-new-commodore-international&#34;&gt;The new Commodore International&lt;/h2&gt;
&lt;figure class=&#34;youtube-player&#34;&gt;
&lt;iframe
    width=&#34;600&#34;
    height=&#34;337&#34;
    src=&#34;https://www.youtube.com/embed/S2fGP59mJ5M&#34;
    title=&#34;New Commodore 64 Ultimate: The Best-Selling Home Computer Ever Is Back&#34;
    frameborder=&#34;0&#34;
    allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#34;
    allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;
New Commodore 64 Ultimate: The Best-Selling Home Computer Ever Is Back
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We&amp;rsquo;ve all thought about it. What would you do if you could rescue the original Commodore name from getting mired in the portfolios of private equity firms? Would you found a company with the community&amp;rsquo;s best interests at heart? Would you help foster the creativity of hundreds, and bring the joys of recreational computing to thousands? Would you take the best modern retro computing has to offer, and make it more accessible to the world?&lt;/p&gt;
&lt;p&gt;Perifractic of &lt;a href=&#34;https://www.youtube.com/@RetroRecipes&#34;&gt;the YouTube series Retro Recipes&lt;/a&gt; has gone and done just that. After many months of intense effort, &lt;a href=&#34;https://www.commodore.net/&#34;&gt;Commodore International&lt;/a&gt; is now live. Not only that, they&amp;rsquo;re taking pre-orders for the &lt;strong&gt;Commodore 64 Ultimate,&lt;/strong&gt; a modern all-in-one C64 with a vintage feel and modern conveniences. (Kind of like another project I&amp;rsquo;m rather fond of.) They&amp;rsquo;ve also got some pretty neat logo merch.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.commodore.net/team&#34;&gt;The team&lt;/a&gt; is a real who&amp;rsquo;s-who of Commodore veterans and modern retro developers. I&amp;rsquo;m grateful to be listed as a partner, though my contributions are all volunteer in my off hours.&lt;/p&gt;
&lt;p&gt;Peri is gradually releasing a series of teaser-heavy videos laying the groundwork for the project, with more to come. Check these out if you haven&amp;rsquo;t already:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/lN8r4LRcOXc?si=J7O-hYT_Q-ePzdK5&#34;&gt;June 7, 2025&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/ke-Ao-CpI7E?si=O3oC-NtIi122by1i&#34;&gt;June 28, 2025&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=S2fGP59mJ5M&#34;&gt;July 12, 2025&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Congratulations to Perifractic and the team on this initial launch, and best wishes for the company&amp;rsquo;s success!&lt;/p&gt;
&lt;h2 id=&#34;the-new-computes-gazette&#34;&gt;The new COMPUTE!&amp;rsquo;s Gazette&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/gazette.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/gazette.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/gazette_hu_ccc45335ea7eff9a.jpeg 600w, https://dansanderson.com/mega65/so-many-things/gazette_hu_9269a521d1294b41.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/gazette.jpeg&#34;
        alt=&#34;The new COMPUTE!&amp;amp;#39;s Gazette magazine, issue 1&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The new COMPUTE!&#39;s Gazette magazine, issue 1.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;COMPUTE!&amp;rsquo;s Gazette&lt;/em&gt;, the venerable home computing magazine from the &amp;rsquo;80s and &amp;rsquo;90s, is also &lt;a href=&#34;https://www.computesgazette.com/&#34;&gt;being reborn&lt;/a&gt;. Edwin Nagle acquired the rights to the name, and has started a new magazine all about modern retro computing across multiple platforms, old and new. The new &lt;em&gt;Gazette&lt;/em&gt; has published its first issue, including a feature article on the new Commodore. You can buy the single issue as either a print + digital bundle or digital-only, or you can &lt;a href=&#34;https://www.computesgazette.com/subscribe-to-computes-gazette-stay-updated-on-the-latest-retro-trends/&#34;&gt;start a subscription&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m thrilled to announce that &lt;em&gt;Gazette&lt;/em&gt; includes a regular column about the MEGA65, by me! I am syndicating &lt;em&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/em&gt; feature articles with the magazine, starting with the first issue. Going forward, the column will include existing and new material, edited for the &lt;em&gt;Gazette&lt;/em&gt; audience. The MEGA65 will have a regular presence in the magazine, in more ways than one.&lt;/p&gt;
&lt;p&gt;Congrats to Edwin, the team at &lt;em&gt;COMPUTE! Publishing&lt;/em&gt;, and contributors for making this happen!&lt;/p&gt;
&lt;h2 id=&#34;retrocombs-video-users-guide-the-final-chapter&#34;&gt;retroCombs video User&amp;rsquo;s Guide, the final chapter&lt;/h2&gt;
&lt;figure class=&#34;youtube-player&#34;&gt;
&lt;iframe
    width=&#34;600&#34;
    height=&#34;337&#34;
    src=&#34;https://www.youtube.com/embed/ZiDGhwyjv4g&#34;
    title=&#34;retroCombs on the MEGA65 User&amp;#39;s Guide chapter 7&#34;
    frameborder=&#34;0&#34;
    allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#34;
    allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;
retroCombs on the MEGA65 User&#39;s Guide chapter 7
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;retroCombs has completed his video series on the MEGA65 User&amp;rsquo;s Guide, with &lt;a href=&#34;https://youtu.be/ZiDGhwyjv4g?si=PnbLkxFE0lLLJflk&#34;&gt;a video all about chapter 7&lt;/a&gt;: transferring files.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/playlist?list=PLRVBh2hjFTomDGwIT7uPMJv4zH9JAUSVG&#34;&gt;The full series&lt;/a&gt; dedicates a video to each chapter of the User&amp;rsquo;s Guide, providing useful video demonstrations and commentary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ch 1: &lt;a href=&#34;https://youtu.be/UUVOtkLP-eY?si=Y3eagho2rZ4qrxW-&#34;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ch 2: &lt;a href=&#34;https://youtu.be/HOJIwK7CqMY?si=-6brkO0NOkcE8pIS&#34;&gt;Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ch 3: &lt;a href=&#34;https://youtu.be/kKGhYTJlSuw?si=Zu1jlTsovMifaPS1&#34;&gt;Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ch 4: &lt;a href=&#34;https://youtu.be/C-PNB9rlzV4?si=co9w8gyhAhRhkTnp&#34;&gt;Configuring Your MEGA65&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ch 5: &lt;a href=&#34;https://youtu.be/XkDss1mj5CU?si=Dzui4WC5gqvGoKFW&#34;&gt;Upgrading the MEGA65&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ch 6: &lt;a href=&#34;https://youtu.be/lw7o2X91Zt4?si=S1TqBlb0eaJEJXAC&#34;&gt;Using Disks and Disk Images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ch 7: &lt;a href=&#34;https://youtu.be/ZiDGhwyjv4g?si=Yui9l9LXcfNH9wJm&#34;&gt;Transferring Files&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Don&amp;rsquo;t miss &lt;a href=&#34;https://www.youtube.com/playlist?list=PLRVBh2hjFTomsrJnQdqFmoZUdT6qHocpo&#34;&gt;more retroCombs MEGA65 videos&lt;/a&gt; for even more fun!&lt;/p&gt;
&lt;h2 id=&#34;level-up-with-jeffrey&#34;&gt;Level Up with Jeffrey&lt;/h2&gt;
&lt;figure class=&#34;youtube-player&#34;&gt;
&lt;iframe
    width=&#34;600&#34;
    height=&#34;337&#34;
    src=&#34;https://www.youtube.com/embed/RI-lCKTXJu8&#34;
    title=&#34;Level Up with Jeffrey: Fixing C64 Frantic Freddie: For MEGA65.&#34;
    frameborder=&#34;0&#34;
    allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#34;
    allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;
Level Up with Jeffrey: Fixing C64 Frantic Freddie: For MEGA65
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The YouTube channel &lt;a href=&#34;https://www.youtube.com/@LevelUpWithJeffrey&#34;&gt;Level Up with Jeffrey&lt;/a&gt; covers vintage and modern retro home computer games, with entertaining playthroughs and discussion. In the last year, Jeffrey has taken a shine to the MEGA65, in particular running Commodore 64 games in the MEGA65&amp;rsquo;s &amp;ldquo;GO64&amp;rdquo; compatibility mode (not just the C64 core). It&amp;rsquo;s great to be reminded that GO64 mode is actually quite capable. I tend to steer people toward &lt;a href=&#34;https://files.mega65.org?id=896a012f-59e4-456c-b91f-7e989b958241&#34;&gt;the C64 core&lt;/a&gt; just to avoid disappointment with the occasional compatibility issue, but GO64 mode has workflow advantages with the MEGA65 Freezer, and is just neat from a technical perspective.&lt;/p&gt;
&lt;p&gt;All of Jeffrey&amp;rsquo;s back catalog is fun to watch. As a programmer, I especially enjoyed his recent diversion from form, &lt;a href=&#34;https://www.youtube.com/watch?v=RI-lCKTXJu8&#34;&gt;Fixing C64 Frantic Freddie: For MEGA65&lt;/a&gt;, in which Jeffrey uses the MEGA65&amp;rsquo;s built-in programming tools to dig into the C64 classic&amp;rsquo;s machine code. This video is a follow-up to &lt;a href=&#34;https://www.youtube.com/watch?v=CoA1R5y3MYg&#34;&gt;8-Bit Show and Tell&amp;rsquo;s recent Frantic Freddie code dive&lt;/a&gt; using Super Snapshot on the C64. Both videos are gold for fans of the game, or of screenfuls of assembly language.&lt;/p&gt;
&lt;h2 id=&#34;advanced-graphics-tutorials&#34;&gt;Advanced graphics tutorials&lt;/h2&gt;
&lt;p&gt;Can&amp;rsquo;t wait for me to get around to finishing my Digest series on advanced graphics? Other MEGA65 developers have been documenting their own journeys for your benefit.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a look ahead at common abbreviations used to describe VIC-IV graphics features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SEAM = Super Extended Attribute Mode&lt;/li&gt;
&lt;li&gt;FCM = Full Color Mode&lt;/li&gt;
&lt;li&gt;NCM = Nybble Color Mode&lt;/li&gt;
&lt;li&gt;RRB = the Raster Rewrite Buffer&lt;/li&gt;
&lt;li&gt;pixies = sprite-like movable graphics objects implemented using the RRB&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RetroCogs, the author of the upcoming side-scrolling shooter &lt;em&gt;First Shot&lt;/em&gt;, has published two new articles on VIC-IV graphics: &lt;a href=&#34;https://retrocogs.mega65.com/2025/08/13/vic-iv-graphics-setting-up-fcm-and-ncm/&#34;&gt;Setting up FCM and NCM&lt;/a&gt; and &lt;a href=&#34;https://retrocogs.mega65.com/2025/08/14/vic-iv-graphics-using-rrb-for-pixies/&#34;&gt;Using RRB for Pixies&lt;/a&gt;. RetroCogs has previously published &lt;a href=&#34;https://retrocogs.mega65.com/&#34;&gt;a few other blog articles&lt;/a&gt;, &lt;a href=&#34;https://github.com/RetroCogs/Mega65Tutorials&#34;&gt;MEGA65 graphics tutorials in Github&lt;/a&gt;, and the beginnings of a MEGA65 game development framework called &lt;a href=&#34;https://github.com/RetroCogs/GameShell65&#34;&gt;GameShell65&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;ubik has published a &lt;a href=&#34;https://files.mega65.org?id=7360100f-c559-42a8-8126-778afd1b3cb3&#34;&gt;BASIC65 full-color image demo&lt;/a&gt;, a demonstration of full-screen images rendered with Full-Color Mode character graphics. Also check out &lt;a href=&#34;https://steph72.github.io/fcio-tutorial/&#34;&gt;this nifty tutorial in C for the MEGA65&lt;/a&gt;, with a Python script for converting images from the PNG format for use with this code.&lt;/p&gt;
&lt;p&gt;Gurce has been doing his own &lt;a href=&#34;https://github.com/gurcei/seamlib&#34;&gt;SEAM experiments&lt;/a&gt;, in Eleven/BASIC 65, including the beginnings of a graphics editor and experiments with pixies and bounding box collision detection. Gurce reports that these advanced graphics modes are little bit too CPU intensive for performing large animations in pure BASIC, but BASIC examples are useful to understand the ideas.&lt;/p&gt;
&lt;p&gt;I still intended to document my own journey learning these features here in this Digest. I&amp;rsquo;m grateful to everyone who has published articles and sample code, so I can compare notes.&lt;/p&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/gravman.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/gravman.png 1024w, https://dansanderson.com/mega65/so-many-things/gravman_hu_daab9abcc6210dae.png 600w, https://dansanderson.com/mega65/so-many-things/gravman_hu_9c09d49d068e684d.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/gravman.png&#34;
        alt=&#34;GRAVMAN, by Robhawk.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
GRAVMAN, by Robhawk.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=34891039-6a95-4cb6-a38a-30775126b4c4&#34;&gt;GRAVMAN&lt;/a&gt;, a MEGA65-themed gravity-lander game by Robhawk (RobH on Discord). &lt;code&gt;RUN &amp;quot;GRAVMAN.PRG&amp;quot;&lt;/code&gt; to start. Joystick fire to thrust upward, left and right to thrust sideways. Collect MEGA65 pieces—and pages of this Digest!—and land safely on the green pad. Level editor included (&lt;code&gt;RUN &amp;quot;LEVEL-EDITOR&amp;quot;&lt;/code&gt;), and don&amp;rsquo;t miss the well-commended BASIC source code.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=7f3d1007-6250-44e4-86cb-93444ae669b5&#34;&gt;Commando B65&lt;/a&gt;, by SirGeldi, a tribute game to &lt;a href=&#34;https://www.c64-wiki.com/wiki/Commando&#34;&gt;Commando&lt;/a&gt; for the C64, using character graphics and a scrolling playfield. Music by Gurce. Use a joystick in port 2 to move, and move + fire to shoot in the direction of movement.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=e9241e37-a510-4cb9-9b9b-f23764012a04&#34;&gt;HAMURABI 65&lt;/a&gt;, by BOBELE. A MEGA65 version of a simple economic simulation, based on the game published in &lt;a href=&#34;https://archive.org/details/101basiccomputer0000davi&#34;&gt;101 BASIC COMPUTER GAMES&lt;/a&gt; by David Ahl of Digital Equipment Corporation in 1975.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=4554c0ee-f9a8-4002-8a6f-07e775517d7a&#34;&gt;Mitosis&lt;/a&gt;, by ubik. A strategy board game for two players, similar to &lt;a href=&#34;https://en.wikipedia.org/wiki/Ataxx&#34;&gt;Ataxx&lt;/a&gt;. Claim territory by adding your pieces to the board, and mutate your opponent&amp;rsquo;s neighboring pieces.&lt;/p&gt;
&lt;p&gt;So many people are pushing their projects forward this summer (or winter as the case may be), and sharing updates with the community. Rhialto is making steady progress on &lt;a href=&#34;https://discord.com/channels/719326990221574164/1282765235639549993&#34;&gt;the PET core&lt;/a&gt; (Discord link), including in-progress SuperPET extensions, still in &amp;ldquo;pre-release&amp;rdquo; status; &lt;a href=&#34;https://files.mega65.org?id=468325ae-7e27-475d-80e7-a0f0af409446&#34;&gt;download the latest&lt;/a&gt;. sy2002 has released &lt;a href=&#34;https://discord.com/channels/719326990221574164/801767398675316756/1393177221442572380&#34;&gt;an experimental update to the C64 core&lt;/a&gt; (Discord link) specifically for use with &lt;a href=&#34;https://www.ide64.org/&#34;&gt;IDE64&lt;/a&gt;, a modern mass storage cartridge device. TwoBitRetro continues to revise the beta version of &lt;a href=&#34;https://files.mega65.org?id=d3a2dd0c-f57e-4dcc-9fd0-2f9b880f76ec&#34;&gt;Pascal65&lt;/a&gt;. Boris is keeping &lt;a href=&#34;https://kugelblitz360.github.io/m65-altcores/&#34;&gt;the alternate cores documentation&lt;/a&gt; up to date. xlar54 continues work on an Internet-capable networking library (see &lt;a href=&#34;https://discord.com/channels/719326990221574164/1371596604628275201&#34;&gt;#weeip on Discord&lt;/a&gt;). ctalkobt is working on an assembler with text editor (see &lt;a href=&#34;https://discord.com/channels/719326990221574164/1370255277311660113&#34;&gt;#vim&lt;/a&gt;). Bobby Tables is working on an all-new fast assembler engine for Mega Assembler (see &lt;a href=&#34;https://discord.com/channels/719326990221574164/1398179170172928050&#34;&gt;#super-mega-assembler&lt;/a&gt;). And of course Paul is still working on the MEGAphone and posting updates to &lt;a href=&#34;https://c65gs.blogspot.com/&#34;&gt;his developer blog&lt;/a&gt;. And these are just projects I know about from Discord discussions.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;re all crushing it! Keep up the good work!&lt;/p&gt;
&lt;h2 id=&#34;vcf-west&#34;&gt;VCF West&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been looking forward to the Vintage Computer Festival West all year, and it did not disappoint. This two-day event at the Computer History Museum in Mountain View, California, USA, received over 3,500 attendees. It featured two full days of talks, a large exhibition floor, and three rooms of consignment sales.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_amiga_prototype.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_amiga_prototype.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_amiga_prototype_hu_d767beb36bd8e9fa.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_amiga_prototype_hu_a17f11047d5175c3.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_amiga_prototype.jpeg&#34;
        alt=&#34;An original Amiga prototype, in a makeshift case&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An original Amiga prototype, in a makeshift case.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This year&amp;rsquo;s event celebrated the 40th anniversary of the Amiga with a special exhibit of early Amiga prototypes from 1984, multiple Amiga-related talks, and a special ticketed event recreating &lt;a href=&#34;https://www.youtube.com/watch?v=o3x00Pbs2K8&#34;&gt;the famous Amiga launch event at Lincoln Center&lt;/a&gt;, including a bit of fun with stand-ins for Andy Warhol and Debbie Harry.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_amiga_wirewrap.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_amiga_wirewrap.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_amiga_wirewrap_hu_5a291c5e164bbe56.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_amiga_wirewrap_hu_2779273c3377162e.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_amiga_wirewrap.jpeg&#34;
        alt=&#34;Early prototypes of Amiga custom chips, as wirewrap panels&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Early prototypes of Amiga custom chips, as wirewrap panels.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I had the honor of being the first speaker of the show. I was busy working on the talk all the way up to the last minute, including on breaks during the 14 hour drive down from Seattle. It went pretty well. I wish I had more time to fill out my thesis with research, but it was sufficient for a casual talk at a volunteer event. VCF West will upload talk videos at a later date, and I&amp;rsquo;ll be sure to mention it when they do.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_mega65_firstshot.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_mega65_firstshot.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_mega65_firstshot_hu_71c1c3fe0b00a697.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_mega65_firstshot_hu_e23982920d1107.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_mega65_firstshot.jpeg&#34;
        alt=&#34;Colin Reed&amp;amp;#39;s First Shot is always a big draw at shows&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Colin Reed&#39;s First Shot is always a big draw at shows.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I didn&amp;rsquo;t get to see much of the show otherwise, as I was also an exhibitor, and my booth had almost full-day attendance on both days. I was grateful to meet for the first time in person multiple people I already know from Discord communities, including MEGA65 owners. I also met more than one former Commodore employee, and more than one professional author of 1980&amp;rsquo;s computer books and magazine articles.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_paullassa_dan.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_paullassa_dan.jpg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_paullassa_dan_hu_97eb904cb27f528f.jpg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_paullassa_dan_hu_a54b11a25a99758b.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_paullassa_dan.jpg&#34;
        alt=&#34;Commodore 65 designer Paul Lassa (left) and me (right)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Commodore 65 designer Paul Lassa (left) and me (right).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The highlight of the event for me was meeting Paul Lassa, one of the original developers of the Commodore 65. We talked for a long while about working for Commodore, the challenges of the C65 project, and the present and future of the MEGA65 project. I&amp;rsquo;m very pleased to know that Paul owns a MEGA65 and reads this newsletter. As such, I&amp;rsquo;ll try not to embarrass him further. 😅 I&amp;rsquo;m grateful that Paul sought out my exhibit and was generous with his time. Thank you Paul!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_paullassa.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_paullassa.jpg 4284w, https://dansanderson.com/mega65/so-many-things/vcfw_paullassa_hu_d1fca302e6951bc1.jpg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_paullassa_hu_bb277d0d5cef3590.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_paullassa.jpg&#34;
        alt=&#34;Chatting with Paul Lassa over the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Chatting with Paul Lassa over the MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I was also delighted to briefly meet Kenneth Dyke, a graphics software engineer with a long career at Apple that also worked on the Amiga at Commodore. Kenneth also wrote the 6502 CPU Verilog implementation that the MEGA65 uses to power its Matrix Mode debugger. He was walking around the show wearing a backpack containing &lt;em&gt;two&lt;/em&gt; Commodore 65 prototypes. I&amp;rsquo;m not sure why. We got them out and took some pictures.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_kendyke_paullassa.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_kendyke_paullassa.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_kendyke_paullassa_hu_e3138d67725c2a2e.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_kendyke_paullassa_hu_92dfa4923f2129a6.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_kendyke_paullassa.jpeg&#34;
        alt=&#34;Kenneth Dyke, Paul Lassa, and a Commodore 65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kenneth Dyke, Paul Lassa, and a Commodore 65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_mega_c65.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_mega_c65.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_mega_c65_hu_830b93a631b76fb9.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_mega_c65_hu_fe7d20b9fb727ca3.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_mega_c65.jpeg&#34;
        alt=&#34;The Commodore 65 and the MEGA65, side by side&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Commodore 65 and the MEGA65, side by side.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I had brief moments to run around the floor and take some quick pictures. This is not a good representation of the show overall, but who doesn&amp;rsquo;t love pictures of old computers!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_osborne_vixen.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_osborne_vixen.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_osborne_vixen_hu_6676ad91a385bc5e.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_osborne_vixen_hu_e48d26fc95a5712a.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_osborne_vixen.jpeg&#34;
        alt=&#34;The Osborne Vixen&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Osborne Vixen.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_wyseterm.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_wyseterm.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_wyseterm_hu_dbe6f0da74f5064a.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_wyseterm_hu_dcbc9c3e1d9890c6.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_wyseterm.jpeg&#34;
        alt=&#34;WYSE Terminal displaying a hex dump&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
WYSE Terminal displaying a hex dump. I&#39;m sorry I didn&#39;t notice what this was connected to.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_z80_diag.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_z80_diag.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_z80_diag_hu_894f9abb47a8f9f5.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_z80_diag_hu_3d61c7ec7e2057ab.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_z80_diag.jpeg&#34;
        alt=&#34;Applied Microsystems EM-180B Z80 Diagnostic Emulator&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Applied Microsystems EM-180B Z80 Diagnostic Emulator. Part of a display by Chris Brock, who rewrote the Digital Research MP/M operating system for a modern eZ80 CPU.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_magic1.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_magic1.jpeg 4032w, https://dansanderson.com/mega65/so-many-things/vcfw_magic1_hu_5762c503648b117.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_magic1_hu_75aaf275bd30e241.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_magic1.jpeg&#34;
        alt=&#34;The Magic-1 homebrew computer with TTL-based CPU.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Magic-1 homebrew computer with TTL-based CPU.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;See &lt;a href=&#34;https://www.magic-1.org/&#34;&gt;magic-1.org&lt;/a&gt;, a website served by the Magic-1 homebrew computer.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_heathkit_et3100.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_heathkit_et3100.jpeg 5712w, https://dansanderson.com/mega65/so-many-things/vcfw_heathkit_et3100_hu_40a52eb9dec7c971.jpeg 600w, https://dansanderson.com/mega65/so-many-things/vcfw_heathkit_et3100_hu_557f249af4ea5f4d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/so-many-things/vcfw_heathkit_et3100.jpeg&#34;
        alt=&#34;The Heathkig ET3100 trainer, at consignment&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Heathkig ET3100 trainer, at consignment.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;I love deadlines. I love the whooshing noise they make as they go by.&amp;rdquo; — Douglas Adams&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What&amp;rsquo;s next? I still have a bunch of work to finish for Commodore, which will probably eat up my hobby time for August. Then I&amp;rsquo;m off to Schaumburg, Illinois, for &lt;a href=&#34;https://vcfmw.org/&#34;&gt;VCF Midwest 2025&lt;/a&gt;, September 13 and 14, where I will be giving another talk and running another MEGA65 exhibit. They have &lt;em&gt;two&lt;/em&gt; speaker tracks this year, and thanks to generous volunteers, both tracks will be recorded. My speaker slot for this one is Saturday at 10:30 am in the secondary venue.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m eager to get back to MEGA65 ROM and documentation work, not to mention the Digest. I&amp;rsquo;d love to write a game someday. Man, too much to do.&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/so-many-things/M65Digest_2025Aug.mp3" length="16245376" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>812</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/so-many-things/mega_vcfw.jpeg"/>
      
    </item>
    
    <item>
      <title>Taste the Rainbow</title>
      <link>https://dansanderson.com/mega65/taste-the-rainbow/</link>
      <pubDate>Sun, 06 Jul 2025 23:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/taste-the-rainbow/</guid>
      <description>&lt;p&gt;Taste the Rainbow. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for June 2025.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Taste the Rainbow. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for June 2025.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/M65Digest_2025Jun.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/M65Digest_2025Jun.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Taste the Rainbow.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/mega_mcm.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/mega_mcm.png&#34;
            width=&#34;580&#34;
            height=&#34;358&#34;
            alt=&#34;&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Hey all! I&amp;rsquo;ve been a &lt;em&gt;bit&lt;/em&gt; busier than usual lately, so this Digest is tardy. If we could all pretend that it&amp;rsquo;s still June for just a few moments I&amp;rsquo;d appreciate it.&lt;/p&gt;
&lt;p&gt;A character graphics system limits the amount of memory needed to describe what appears on a raster display, and thus the amount of computation needed to update it. It does this through &lt;em&gt;indirection:&lt;/em&gt; instead of describing every pixel on the screen, it describes a smaller set of repeatable patterns, or &lt;em&gt;characters&lt;/em&gt;, along with a description of where those patterns appear in a grid.&lt;/p&gt;
&lt;p&gt;Such systems typically apply a similar idea to color, finding benefits in describing characters and colors separately. For example, declaring the character to display and its color separately allows a program to reuse the image data in different colors. Flexible color systems such as the MEGA65&amp;rsquo;s VIC-IV also use indirection for defining the colors: color data references entries in a palette (&amp;ldquo;color #2&amp;rdquo;), and each entry describes the color value to use when the entry is referenced (&amp;ldquo;2 = red&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/character-study/&#34;&gt;Last month&lt;/a&gt; (remember we&amp;rsquo;re pretending it&amp;rsquo;s June), we began exploring character graphics using the built-in PETSCII character set and the default system palette. We covered how to describe the display in terms of these presets with data in screen and color memory. This month, we&amp;rsquo;ll look at defining custom colors and custom character images. We&amp;rsquo;ll take this opportunity to explore two color-related alternate display modes from the VIC-II era, and see how different graphics modes make tradeoffs to give us more options.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s do some Features Files, then get right to it.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;muse has &lt;em&gt;three&lt;/em&gt; arcade cores for us this month:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=f024a865-8751-4292-ac66-439daa696ad6&#34;&gt;Galaxian&lt;/a&gt;, Namco, 1979.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=c1486390-3264-4027-8131-552a785cac33&#34;&gt;Gyruss&lt;/a&gt;, Konami, 1983.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=dfadf67d-b55f-4c4d-8cb5-c903161e0668&#34;&gt;Up&amp;rsquo;n&amp;rsquo;Down&lt;/a&gt;, Sega, 1983.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kiwi has given us a beta release of a text editor: &lt;a href=&#34;https://files.mega65.org?id=a820c77b-7c22-4d42-b60b-ac100e8c1ca6&#34;&gt;Mega Edit&lt;/a&gt;. Some features are still in progress. Inspired by Compute!&amp;rsquo;s SpeedScript.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=0eb33347-dc3a-40d7-8f85-b0bfbe652123&#34;&gt;Fifth Wins&lt;/a&gt; by Hanyic Róbert, a two-player logic game. Play against the computer or another player.&lt;/p&gt;
&lt;p&gt;Great work everyone, keep it up!&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;petscii-characters-and-playing-cards&#34;&gt;PETSCII characters and playing cards&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/ace_blue_grid.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/ace_blue_grid.png&#34;
            width=&#34;318&#34;
            height=&#34;454&#34;
            alt=&#34;A PETSCII drawing of a playing card&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A PETSCII drawing of a playing card.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Let&amp;rsquo;s make a card game! The PETSCII character set has symbols for the four playing card suits. You can type these directly onto the screen: hold &lt;kbd&gt;Shift&lt;/kbd&gt;, then type &lt;kbd&gt;A&lt;/kbd&gt;, &lt;kbd&gt;S&lt;/kbd&gt;, &lt;kbd&gt;Z&lt;/kbd&gt;, or &lt;kbd&gt;X&lt;/kbd&gt;. Just as on a Commodore 64, the keys on your MEGA65 have their corresponding graphics symbols printed on the front. Hold &lt;kbd&gt;Mega&lt;/kbd&gt; to type the left-hand symbol, &lt;kbd&gt;Shift&lt;/kbd&gt; for the right-hand symbol.&lt;/p&gt;
&lt;p&gt;To draw the playing card image above, I typed the graphics symbols as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The four corners are &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;D&lt;/kbd&gt;, &lt;kbd&gt;F&lt;/kbd&gt;, &lt;kbd&gt;C&lt;/kbd&gt;, and &lt;kbd&gt;V&lt;/kbd&gt;. These are screen codes 108, 123, 124, and 126, respectively.&lt;/li&gt;
&lt;li&gt;The top edge is &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;I&lt;/kbd&gt;, screen code 98. To draw the bottom edge, I switched to Reverse Mode by typing &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;9&lt;/kbd&gt;, then typed &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;I&lt;/kbd&gt; to produce screen code 98 + 128 = 226. (Use &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;0&lt;/kbd&gt; to exit Reverse Mode.) With the PETSCII character set, adding 128 to the screen code from 0 to 127 refers to its reverse (128 to 255).&lt;/li&gt;
&lt;li&gt;The right edge is &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;K&lt;/kbd&gt;, screen code 118. To draw the left edge, I switched to Reverse Mode, then typed &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;K&lt;/kbd&gt; to produce screen code 118 + 128 = 246.&lt;/li&gt;
&lt;li&gt;The inner characters are reversed versions of the letter &lt;kbd&gt;A&lt;/kbd&gt; (code 1 + 128 = 129), the spade (&lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;A&lt;/kbd&gt;, code 65 + 128 = 193), and the space (code 32 + 128 = 160).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Try drawing your own playing card by typing into the screen editor.&lt;/p&gt;
&lt;p&gt;Remember, a &lt;em&gt;screen code&lt;/em&gt; refers to an entry in the active &lt;em&gt;character set&lt;/em&gt;. When you type &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;A&lt;/kbd&gt;, the screen editor writes screen code 65 to the location in screen memory that corresponds with the cursor position. See &amp;ldquo;Appendix D: Screen Codes&amp;rdquo; in the &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;User&amp;rsquo;s Guide&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/petscii_mega65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/taste-the-rainbow/petscii_mega65.png 526w, https://dansanderson.com/mega65/taste-the-rainbow/petscii_mega65_hu_5f689750dd198f94.png 600w, https://dansanderson.com/mega65/taste-the-rainbow/petscii_mega65_hu_a44b9d15f657b993.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/petscii_mega65.png&#34;
        alt=&#34;The default PETSCII character set&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The default PETSCII character set.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If we wrote our card game in assembly language, we might represent the card images as screen codes in our program data, and draw them by storing these codes directly into screen memory. A BASIC program could do the same with &lt;code&gt;T@&amp;amp;(X,Y) = ...&lt;/code&gt; and &lt;code&gt;C@&amp;amp;(X,Y) = ...&lt;/code&gt;, or use &lt;code&gt;POKE&lt;/code&gt; with the screen memory address as shown in the last Digest.&lt;/p&gt;
&lt;p&gt;Another way to draw the cards is to manipulate the screen editor&amp;rsquo;s cursor. This is what happens when a BASIC program uses the &lt;code&gt;PRINT&lt;/code&gt; command, or when an assembly language program calls the &lt;code&gt;CHROUT&lt;/code&gt; KERNAL routine. Instead of a screen code, the program emits a &lt;em&gt;PETSCII code&lt;/em&gt; that tells the cursor what to do. Some codes print a character at the cursor&amp;rsquo;s position and in the cursor&amp;rsquo;s color. Other codes change the cursor&amp;rsquo;s color or position. We explored PETSCII codes &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/&#34;&gt;in a previous Digest&lt;/a&gt;. The screen editor implements the cursor&amp;rsquo;s behavior by writing screen codes to screen memory and color codes to color memory.&lt;/p&gt;
&lt;h2 id=&#34;custom-colors-everywhere&#34;&gt;Custom colors everywhere&lt;/h2&gt;
&lt;p&gt;So what&amp;rsquo;s the deal with these color codes? Each available color is assigned a number. The number written to color memory for a location on the screen determines the foreground color of that character. The background and screen border also each have a color code, stored in dedicated registers.&lt;/p&gt;
&lt;p&gt;BASIC 65 has commands that can change the background and border colors. Try these with numbers in the range 0 to 31:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BACKGROUND 0
BORDER 2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a list of the default colors of the system palette, see &amp;ldquo;Appendix E: System Palette&amp;rdquo; in the &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;User&amp;rsquo;s Guide&lt;/a&gt;, or refer to this chart:&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/palette.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/palette.png&#34;
            width=&#34;422&#34;
            height=&#34;316&#34;
            alt=&#34;The MEGA65 default palette&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 default system palette.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The C64 has a fixed palette of 16 colors, numbered 0 to 15. I&amp;rsquo;m used to thinking that 0 is always black, 1 is white, 6 is blue, etc., and might be comfortable calling these &amp;ldquo;color codes.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;On the MEGA65, you can change the color of any entry to any of 4,096 possible colors. Here, color codes are probably better known as &amp;ldquo;palette codes.&amp;rdquo; Similar to a painter&amp;rsquo;s palette, you can put any color you want into any palette entry.&lt;/p&gt;
&lt;p&gt;I want the background color for this card game to be a dark green, like the felt of a traditional card table. The default system palette doesn&amp;rsquo;t have a dark green. But no worries, we can make our own:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PALETTE COLOR 22,0,7,0
BACKGROUND 22&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;PALETTE COLOR&lt;/code&gt; command takes a palette code, and a value for how much red, green, and blue to mix into the color, each a number from 0 to 15. The MEGA65 is mixing light, not paint, so the more color you add, the brighter the result. &lt;code&gt;0,0,0&lt;/code&gt; is black, &lt;code&gt;15,0,0&lt;/code&gt; is bright red, &lt;code&gt;15,15,15&lt;/code&gt; is white, and so on. Here, I chose &lt;code&gt;0,7,0&lt;/code&gt; for the green felt. Feel free to adjust this to your taste.&lt;/p&gt;
&lt;p&gt;To set a system palette color from machine code, write the value from 0 to 15 to each of the red, green, and blue palette registers. The reds are at addresses $D100 to $D1FF, the greens are $D200 to $D2FF, and the blues are $D300 to $D3FF. For example, to change palette entry #22 (hexadecimal $16) to felt green, as above:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    lda #0
    sta $d116
    lda #7
    sta $d216
    lda #0
    sta $d316&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A palette actually contains 256 entries, not just the 32 entries accessible by characters in our current text mode. The &lt;code&gt;PALETTE COLOR&lt;/code&gt;, &lt;code&gt;BACKGROUND&lt;/code&gt;, and &lt;code&gt;BORDER&lt;/code&gt; commands support all 256 entries, numbered 0 to 255:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PALETTE COLOR 32,1,3,5
BORDER 32&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are a few ways to give characters access to more of the palette. We&amp;rsquo;re about to see two limited but interesting ways. We&amp;rsquo;ll cover full-color character modes in a later issue.&lt;/p&gt;
&lt;h2 id=&#34;four-palette-banks&#34;&gt;Four palette banks&lt;/h2&gt;
&lt;p&gt;The VIC-IV has four palette banks, each with 256 entries. The character system and the sprite system can use any of the four banks, and you can set characters and sprites to use different banks at the same time. There are not yet BASIC 65 commands for using other palette banks, but this is planned for a future ROM update (see &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues/220&#34;&gt;issue 220&lt;/a&gt;, &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues/221&#34;&gt;221&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Palette bank selection goes through two-bit registers at address $D070. Each bit pair can select palette 0 (%00), 1 (%01), 2 (%10), or 3 (%11).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To change the palette bank used for text, set the two-bit register BTPALSEL D070.4-5.&lt;/li&gt;
&lt;li&gt;To change the palette bank used for sprites, set SPRPALSEL D070.2-3.&lt;/li&gt;
&lt;li&gt;To set or read the colors assigned to palette entries in a given bank, set MAPEDPAL D070.6-7, then use the red, green, and blue registers $D100-$D3FF, as we saw earlier. The color value registers always reflect the selected palette.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s a quick demo. Enable sprite 0, set it to palette entry 7, and move it onto the screen:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRITE 0,1,7
MOVSPR 0,100,100&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, change hardware sprites to use palette bank 1 instead of 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POKE $D070, PEEK($D070) AND %11110011 OR %00000100&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;AND %11110011&lt;/code&gt; clears bits 2 and 3, while preserving the other settings. The &lt;code&gt;OR %00000100&lt;/code&gt; sets SPRPALSEL to palette bank 1, also while preserving the other settings. Yes, you can use &lt;code&gt;SETBIT $D070,2 : CLRBIT $D070,3&lt;/code&gt;, but using &lt;code&gt;POKE&lt;/code&gt; in this way ensures that both bits are set simultaneously with no time for the VIC to get confused while it is drawing.&lt;/p&gt;
&lt;p&gt;Finally, change palette entry 7 of palette bank 1 to aquamarine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POKE $D070, PEEK($D070) AND %00111111 OR %01000000
POKE $D107, 0   : REM RED
POKE $D207, 10  : REM GREEN
POKE $D307, 15  : REM BLUE&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now switch the cursor to palette entry 7: press &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;8&lt;/kbd&gt; (yes, &lt;kbd&gt;8&lt;/kbd&gt;). The cursor switches to yellow, and you can type yellow text. Characters are using palette bank 0 while sprites are using palette bank 1.&lt;/p&gt;
&lt;p&gt;What would happen if you switch characters to palette bank 1? How would you do this with a single BASIC command?&lt;/p&gt;
&lt;h2 id=&#34;understanding-character-sets&#34;&gt;Understanding character sets&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/platformer.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/platformer.png&#34;
            width=&#34;300&#34;
            height=&#34;223&#34;
            alt=&#34;The beginnings of a platform game using a custom character set for the player, ladder, brick, and gold bar&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The beginnings of a platform game using a custom character set for the player, ladder, brick, and gold bar.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So far, we&amp;rsquo;ve been exploring character graphics using the built-in PETSCII character set. We can customize the character set to use any collection of 256 8-by-8 images that we want. This is one of the most powerful ways to add graphics to a game, and many Commodore games use custom character sets for game objects, backgrounds, and alternate text fonts.&lt;/p&gt;
&lt;p&gt;A character set contains 256 character images, and each character image is 8 bytes, for a total of 2,048 bytes (2 kilobytes). The images are ordered by screen code.&lt;/p&gt;
&lt;p&gt;A copy of the PETSCII character set is built into the ROM, starting at address $2.D000. We can find the image data for the suit symbols in this area using the screen code. For example, the spade is screen code 65, so its image data starts at byte offset 65 x 8 = 520 = $0208 from $2.D000, or address $2.D208.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a program that makes it easy to inspect a character of the PETSCII character set. Try changing line 10 to inspect other screen codes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 C = 65 : REM SCREEN CODE
20 PRINT &amp;#34;SCREEN CODE &amp;#34;;C
30 FOR A = $2D000 + C * 8 TO $2D000 + C * 8 + 7
40 V = PEEK(A)
50 PRINT &amp;#34;  &amp;#34;;HEX$(V),STRBIN$(V)
60 NEXT A&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The PETSCII character data in ROM consists of two character sets, one for uppercase and graphics, and another for lowercase and uppercase. When you press &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;Shift&lt;/kbd&gt; to change the letter casing mode, it is just switching between these character sets. The lowercase variant starts at address $2.D800. Try modifying this program to display screen codes from the lowercase character set.&lt;/p&gt;
&lt;h2 id=&#34;pointing-to-custom-character-sets&#34;&gt;Pointing to custom character sets&lt;/h2&gt;
&lt;p&gt;On the Commodore 64, the VIC-II starts in a state that uses the PETSCII character set from the built-in ROM. A program can tell the VIC to use a custom character set instead by setting registers to an address in RAM where the charset is stored. As a kid, I wrote many programs that would copy the PETSCII charset from ROM to RAM, point the VIC to the RAM address, then make changes to certain characters.&lt;/p&gt;
&lt;p&gt;The VIC-II integrates with the C64’s memory system in a somewhat complicated way, with restrictions on what memory the VIC can see and where in memory graphics data can be located. The MEGA65 emulates these methods for backwards compatibility. I won&amp;rsquo;t explain these methods here, because the MEGA65 offers other ways to use custom character sets that are easier to understand.&lt;/p&gt;
&lt;p&gt;The VIC-IV provides a 24-bit pointer register, CHARPTR D068-D06A, that can locate the active character set at any address in the first 384 KB of memory. Here&amp;rsquo;s a simple demonstration that sets CHARPTR to the location in ROM where &lt;code&gt;FONT B&lt;/code&gt; is stored ($3.D000):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;WPOKE $D068,$D000:POKE $D06A,$03&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that as of ROM 920416, &lt;kbd&gt;Run/Stop&lt;/kbd&gt; + &lt;kbd&gt;Restore&lt;/kbd&gt; does not restore CHARPTR to its default. This will be fixed in a later update; see &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues/236&#34;&gt;issue 236&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Similar to changing SCRNPTR to quickly switch between sets of screen memory, a program can use CHARPTR for special graphical effects that require quickly switching between character sets.&lt;/p&gt;
&lt;p&gt;For backwards compatibility with the VIC-II, CHARPTR treats addresses in the ranges $00.1000 - $00.1FFF and $00.9000 - $00.9FFF as special. When looking for character set data, the VIC-IV translates these addresses to a special area of memory, the VIC-IV character set buffer, at $FF7.E000 - $FF7.EFFF. The MEGA65 sets up this buffer with the PETSCII character set that the VIC-II would expect in ROM at these addresses.&lt;/p&gt;
&lt;h2 id=&#34;the-vic-iv-character-set-buffer&#34;&gt;The VIC-IV character set buffer&lt;/h2&gt;
&lt;p&gt;It turns out, the VIC-IV character set buffer is more useful to MEGA65 programs than was originally intended.&lt;/p&gt;
&lt;p&gt;When the MEGA65 starts, it copies the PETSCII font from ROM to the VIC-IV character set buffer at the address range $FF7.E000 - $FF7.EFFF. Similar to a C64, the computer starts with CHARPTR set to $00.1000, so it uses $FF7.E000 for the active character set, uppercase PETSCII.&lt;/p&gt;
&lt;p&gt;Early MEGA65 developers noticed that programs can write directly to the character set buffer. In many cases, you don&amp;rsquo;t have to hassle with copying ROM to RAM or re-pointing CHARPTR just to get a custom character set. You can just poke directly into the buffer to change what it thinks &amp;ldquo;character ROM&amp;rdquo; is. This is totally cheating! Kids today don&amp;rsquo;t know the pain of throwing 2 KB of RAM onto the fire just to customize the font.&lt;/p&gt;
&lt;p&gt;BASIC 65 takes full advantage of this capability. The &lt;code&gt;CHARDEF&lt;/code&gt; command locates the character&amp;rsquo;s image data in the buffer via the screen code (&lt;code&gt;$FF7E000 + C * 8&lt;/code&gt;), then writes the new image data to that location. Similarly, the &lt;code&gt;FONT C&lt;/code&gt; command resets everything back to the PETSCII font by copying the character set from $2.D000 to $FF7.E000.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 REM PLAYER GUY
20 CHARDEF 65,$0C,$1C,$18,$FF,$18,$3C,$66,$C3
30 REM BRICK WALL
40 CHARDEF 66,$FB,$FB,$00,$DF,$DF,$00,$FB,$FB
50 REM LADDER
60 CHARDEF 67,$42,$7E,$42,$42,$42,$7E,$42,$42
70 REM GOLD BAR
80 CHARDEF 68,$00,$00,$00,$00,$3C,$7E,$7E,$00&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&amp;rsquo;s an equivalent program that writes values directly to the character set buffer. This illustrates values in &lt;code&gt;DATA&lt;/code&gt; statements, but this could easily come from a file. (This resembles how you&amp;rsquo;d do this in assembly language.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 FOR I=0 TO 31
20 READ V
30 POKE $FF7E000 + 65 * 8 + I, V
40 NEXT I
50 DATA $0C,$1C,$18,$FF,$18,$3C,$66,$C3 : REM PLAYER GUY
60 DATA $FB,$FB,$00,$DF,$DF,$00,$FB,$FB : REM BRICK WALL
70 DATA $42,$7E,$42,$42,$42,$7E,$42,$42 : REM LADDER
80 DATA $00,$00,$00,$00,$3C,$7E,$7E,$00 : REM GOLD BAR&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&amp;rsquo;s common for games to completely replace the character set with a custom font, as well as with tiles for in-game graphics. On the MEGA65, this is as simple as loading that data into the character set buffer. For a quick experiment, we can find C64 character sets on the Internet that have been extracted from vintage games and various versions of Commodore ROMs.&lt;/p&gt;
&lt;p&gt;Try this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Visit the &lt;a href=&#34;https://home-2002.code-cop.org/c64/font_01.html&#34;&gt;C64 charset gallery by Peter Kofler&lt;/a&gt;, and browse for a character set you&amp;rsquo;d like to try. Click on it to download it. Typically it&amp;rsquo;s a &lt;code&gt;.zip&lt;/code&gt; file, so expand it to get to the contents. The data file is either a &lt;code&gt;.64c&lt;/code&gt; file or &lt;code&gt;.bin&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Use a tool such as M65Connect (see &lt;a href=&#34;https://files.mega65.org/html/main.php&#34;&gt;Filehost&lt;/a&gt;), &lt;a href=&#34;https://style64.org/dirmaster&#34;&gt;DirMaster&lt;/a&gt; (Windows only), or &lt;a href=&#34;https://droid64.sourceforge.net/&#34;&gt;droid64&lt;/a&gt; to create a D81 disk image, and copy the charset file to the disk. Transfer the disk image to your MEGA65&amp;rsquo;s SD card.&lt;/li&gt;
&lt;li&gt;On your MEGA65, mount the disk image.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;BLOAD&lt;/code&gt; command to load the file into the VIC-IV character set buffer.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If the file is a &lt;code&gt;.64c&lt;/code&gt; file, invoke &lt;code&gt;BLOAD&lt;/code&gt; like so, to skip the two-byte address header and load the data into the buffer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BLOAD &amp;#34;FONTNAME.64C&amp;#34;,P($FF7E000)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the file is a &lt;code&gt;.bin&lt;/code&gt; file, provide the &lt;code&gt;,R&lt;/code&gt; argument to tell &lt;code&gt;BLOAD&lt;/code&gt; that the file does not have an address header:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BLOAD &amp;#34;FONTNAME.BIN&amp;#34;,P($FF7E000),R&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See also &lt;a href=&#34;https://www.zimmers.net/anonftp/pub/cbm/firmware/characters/&#34;&gt;Commodore character ROMs at zimmers.net&lt;/a&gt;, and &lt;a href=&#34;https://github.com/patrickmollohan/c64-fonts?tab=readme-ov-file&#34;&gt;C64 fonts by patrickmollohan&lt;/a&gt;. These archives distribute &lt;code&gt;.bin&lt;/code&gt; files, so use &lt;code&gt;BLOAD ..., R&lt;/code&gt; with these.&lt;/p&gt;
&lt;p&gt;When you&amp;rsquo;re done enjoying the custom charset, press &lt;kbd&gt;Run/Stop&lt;/kbd&gt; + &lt;kbd&gt;Restore&lt;/kbd&gt; to return to PETSCII. (&lt;kbd&gt;Run/Stop&lt;/kbd&gt; + &lt;kbd&gt;Restore&lt;/kbd&gt; &lt;em&gt;does&lt;/em&gt; know how to reset the character set buffer.)&lt;/p&gt;
&lt;h2 id=&#34;extended-background-color-mode&#34;&gt;Extended background color mode&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/ace_green.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/ace_green.png&#34;
            width=&#34;359&#34;
            height=&#34;622&#34;
            alt=&#34;The Ace of Spades, on a felt-green background&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Ace of Spades, on a felt-green background
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This playing card looks roughly like the Ace of Spades, but something is off. The characters on the card are drawn with reverse characters, using white for the foreground color and letting the green background through for the card&amp;rsquo;s value and suit. Ideally, we&amp;rsquo;d draw the value and suit of the card in black (spades and clubs) or red (hearts and diamonds) onto the white card surface. Can we do this, and still keep our green background?&lt;/p&gt;
&lt;p&gt;For that, we need to introduce a new graphics mode. &lt;em&gt;Extended Background Color Mode&lt;/em&gt; (ECM) allows us to choose three additional background colors (for a total of four), and select from one of the four background colors for each character individually. ECM works the same way as it does on the Commodore 64&amp;rsquo;s VIC-II chip. With the MEGA65, it also works in the higher resolution text modes and with custom palettes.&lt;/p&gt;
&lt;p&gt;ECM comes at a price. The Commodore 64 did not have additional memory for storing background color selections for each character, so instead, ECM steals the upper two bits of the screen code for this purpose. This leaves fewer bits for selecting a character from the character set, limiting the selection to the first 64 screen codes.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/ecm_screencodes.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/ecm_screencodes.png&#34;
            width=&#34;406&#34;
            height=&#34;345&#34;
            alt=&#34;Screen code structure for normal background color mode vs. extended background color mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Screen code structure for normal background color mode vs. extended background color mode
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To enable ECM, set $D011 bit 6. The registers for the four background colors are $D021 (the normal background color register), $D022, $D023, and $D024. These registers can be set to any of the 256 entries of the selected character graphics palette.&lt;/p&gt;
&lt;p&gt;The following program draws all 256 screen codes onto the screen, waits for a key press, then enables ECM. The selected background colors are blue (6), black (0), red (2), and purple (4).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 BACKGROUND 6
20 SCNCLR:CURSOR 0,4
30 FOR R=0 TO 3:FOR C=0 TO 63
40 T@&amp;amp;(C,R)=R*64+C
50 NEXT C:NEXT R
60 GETKEY A$
70 POKE $D022,0
80 POKE $D023,2
90 POKE $D024,4
100 SETBIT $D011,6 : REM ENABLE ECM
110 GETKEY A$
120 CLRBIT $D011,6 : REM DISABLE ECM&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/ecm_256chars.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/taste-the-rainbow/ecm_256chars.png 685w, https://dansanderson.com/mega65/taste-the-rainbow/ecm_256chars_hu_18222bbe22e5c559.png 600w, https://dansanderson.com/mega65/taste-the-rainbow/ecm_256chars_hu_18219a5259c4d751.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/ecm_256chars.png&#34;
        alt=&#34;All 256 screen codes in extended background color mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
All 256 screen codes in extended background color mode.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Remember how the screen editor&amp;rsquo;s blinking cursor toggles bit 7 on the screen code, which normally goes back and forth between normal and reversed characters? With ECM enabled, this actually flips between two background colors. This is a neat effect—unless the two background colors are the same, in which case the cursor becomes invisible.&lt;/p&gt;
&lt;p&gt;Extended Background Color Mode seems like it would be useful for our card game. The regular background color is our custom felt green color, there&amp;rsquo;s an alternate background color we can set to white for the card background, and the text on the card can be any of the first 32 palette entries, such as black-on-white or red-on-white.&lt;/p&gt;
&lt;p&gt;Maybe you&amp;rsquo;ve already noticed: there&amp;rsquo;s a problem with this plan. ECM denies us access to the characters we were using to draw spades, clubs, hearts, and diamonds, not to mention the snazzy border characters. We only get 64 possible characters in this mode, and they&amp;rsquo;re showing up as letters, numbers, punctuation, and that&amp;rsquo;s about it. What else is there to do?&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/colored_cards.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/colored_cards.png&#34;
            width=&#34;260&#34;
            height=&#34;134&#34;
            alt=&#34;A partial victory: cards with correct colors&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A partial victory: cards with correct colors, punctuation used for suits.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Custom character sets to the rescue! We just need to replace four of the available 64 characters with the images for the suit symbols, and use those characters to draw cards.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/heart_char.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/heart_char.png&#34;
            width=&#34;637&#34;
            height=&#34;347&#34;
            alt=&#34;Character set data for the heart symbol&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Character set data for the heart symbol.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We could figure out the bytes for each symbol and write them into our program as above. In this case, the characters we want are already in the character set, so we could just copy them down. The screen codes for the spade, club, heart, and diamond are 65, 88, 83, and 90, respectively. Let&amp;rsquo;s copy these to slots 27, 28, 29, and 30.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 FOR I=0 TO 3
20 READ A,B
30 FOR J=0 TO 7
40 POKE $FF7E000 + B * 8 + J, PEEK($2D000 + A * 8 + J)
50 NEXT J
60 NEXT I
70 DATA 65,27,88,28,83,29,90,30&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&amp;rsquo;s the updated character set with ECM enabled, with the copied symbols.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/card_syms_charset.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/taste-the-rainbow/card_syms_charset.png 884w, https://dansanderson.com/mega65/taste-the-rainbow/card_syms_charset_hu_6806d252d73fb.png 600w, https://dansanderson.com/mega65/taste-the-rainbow/card_syms_charset_hu_ec186fa02b808d16.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/card_syms_charset.png&#34;
        alt=&#34;The character set after installing the suit symbols, ECM enabled&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The character set after installing the suit symbols, ECM enabled. The new images are in the middle of the row.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;With the appropriate background color settings, we can now draw values and suits in their correct colors, over a white card background, on a green felt tabletop.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/colored_cards_syms.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/colored_cards_syms.png&#34;
            width=&#34;260&#34;
            height=&#34;134&#34;
            alt=&#34;ECM playing cards with correct suit symbols&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
ECM playing cards with correct suit symbols.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To get those nice border characters, I could sacrifice eight more punctuation symbols. Every project has to decide what it needs and what it&amp;rsquo;s willing to give up.&lt;/p&gt;
&lt;h2 id=&#34;low-res-multicolor-character-mode&#34;&gt;Low-res Multicolor Character Mode&lt;/h2&gt;
&lt;p&gt;The VIC-II has another way to get more color into its characters. In Low-res Multicolor Mode (MCM), a character can use any of four possible colors for each pixel. As always, you can&amp;rsquo;t get something from nothing, and this comes with tradeoffs: each pixel is doubled in width, and a character is four such pixels across.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/taste-the-rainbow/mcm_grid.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/taste-the-rainbow/mcm_grid.png&#34;
            width=&#34;702&#34;
            height=&#34;347&#34;
            alt=&#34;Low-res Multicolor Character Mode interprets character set data as four bit pairs per row&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Low-res Multicolor Character Mode interprets character set data as four bit pairs per row.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The character set data is still one byte per row, with each pair of bits selecting the color for that double-wide picture element. These bit-pairs select the following color options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;%00 = background&lt;/li&gt;
&lt;li&gt;%01 = register $D022&lt;/li&gt;
&lt;li&gt;%10 = register $D023&lt;/li&gt;
&lt;li&gt;%11 = character foreground&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As with ECM, the background and colors $D022 and $D023 apply to the entire screen. Bit-pair %11 selects the foreground color, which can be different for each character, as usual.&lt;/p&gt;
&lt;p&gt;You can mix high resolution and low resolution characters on the same screen. This is great if you want to display PETSCII text alongside low-res high color images. But yes, this comes with another tradeoff. With MCM enabled, color bit 3 determines whether the character is hires (0) or lowres (1). You can only use the first 8 palette entries for the foreground color.&lt;/p&gt;
&lt;p&gt;MCM also ignores color bits 4 through 7. Character attributes are disabled with MCM enabled.&lt;/p&gt;
&lt;p&gt;Sound like fun? Let&amp;rsquo;s try it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SCNCLR
20 REM REDEFINE THE @ SYMBOL TO ILLUSTRATE ALL FOUR BIT PAIRS
30 CHARDEF 0,$00,$00,$55,$55,$AA,$AA,$FF,$FF
40 REM ENABLE MCM
50 SETBIT $D016,4
60 REM SET SCREEN COLORS
70 POKE $D022,3
80 POKE $D023,4
90 BACKGROUND 6
100 FOR C=0 TO 15
110 T@&amp;amp;(C,0)=0
120 C@&amp;amp;(C,0)=C
130 NEXT C
140 GETKEY A$
150 CLRBIT $D016,4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This program defines a character pattern using all four bit pairs, then displays eight of these characters in hires mode in the first eight colors, followed by the same eight characters in lowres mode. Press a key to disable MCM to see all sixteen characters in hires mode. Try experimenting with different character patterns, color combinations, and color attribute values.&lt;/p&gt;
&lt;p&gt;If these tradeoffs make Low-res Multicolor Character Mode seem a bit disappointing, consider this: The MEGA65 has customizable palettes, so you have quite a few more color options than on a C64. Also, the MEGA65 has double the horizontal resolution of a C64. If you&amp;rsquo;re willing to give up some space in the character set, you can display a full 40 columns of four-color characters.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SCNCLR
20 SETBIT $D016,4
30 POKE $D022,17
40 POKE $D023,18
50 BACKGROUND 0
110 CHARDEF  1,$14,$2A,$3F,$14,$28,$3C,$14,$00
120 CHARDEF  2,$05,$2A,$FF,$45,$0A,$0F,$05,$00
130 CHARDEF  3,$15,$28,$3C,$15,$28,$3C,$15,$00
140 CHARDEF  4,$54,$00,$00,$40,$00,$00,$54,$00
150 CHARDEF  5,$05,$28,$3C,$14,$28,$3C,$05,$00
160 CHARDEF  6,$50,$28,$00,$54,$28,$3C,$50,$00
170 CHARDEF  7,$01,$0A,$3C,$15,$28,$3C,$14,$00
180 CHARDEF  8,$40,$A0,$3C,$54,$28,$3C,$14,$00
190 CHARDEF  9,$05,$28,$3C,$15,$28,$3C,$05,$00
200 CHARDEF 10,$50,$28,$00,$50,$28,$3C,$50,$00
210 CHARDEF 11,$15,$28,$3F,$00,$00,$3C,$05,$00
220 CHARDEF 12,$54,$00,$F0,$14,$28,$3C,$50,$00
300 FOR R=0 TO 24:FOR X=1 TO 12
310 T@&amp;amp;(X+2*R,R)=X
320 C@&amp;amp;(X+2*R,R)=15
330 NEXT X:NEXT R
340 GETKEY A$
350 CLRBIT $D016,4
360 FONT C&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;Extended background color mode and low-res multicolor character mode are two ways the VIC-II, VIC-III, and VIC-IV give you more options for displaying character graphics. They work by changing the way screen code bits are interpreted, trading off one capability for another, using the same amount of screen memory as normal (hires, low color) text mode. This was critical with the C64, which didn&amp;rsquo;t have more memory to spare.&lt;/p&gt;
&lt;p&gt;The MEGA65 comes bundled with 384 kilobytes of memory usable for graphics. What could the VIC-IV chip do for us if we give it &lt;em&gt;more&lt;/em&gt; memory? We&amp;rsquo;ll find out next month. Er, this month. You know what I mean.&lt;/p&gt;
&lt;p&gt;This Digest is made possible by a group of amazing people making monthly donations. If you&amp;rsquo;d like to join this group, visit &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/taste-the-rainbow/M65Digest_2025Jun.mp3" length="" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1680</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/taste-the-rainbow/mega_mcm.png"/>
      
    </item>
    
    <item>
      <title>Gifts From Ray</title>
      <link>https://dansanderson.com/lab-notes/gifts-from-ray/</link>
      <pubDate>Sun, 15 Jun 2025 16:59:09 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/lab-notes/gifts-from-ray/</guid>
      <description>&lt;p&gt;Enjoy this sloppy collection of photos of vintage computer software, books, and hardware, recently gifted to me by Ray Carlsen.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Enjoy this sloppy collection of photos of vintage computer software, books, and hardware, recently gifted to me by Ray Carlsen.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Back in 2019, I answered an open call from vintage computer repair guru Ray Carlsen to &lt;a href=&#34;https://dansanderson.com/lab-notes/huge-retro-haul-uwcug/&#34;&gt;pick up a large quantity of Commodore hardware and software&lt;/a&gt; that he was shepherding and could shepherd no longer. Most of the collection was the lending library of the University of Washington Commodore User&amp;rsquo;s Group. Many of the floppy disks &lt;a href=&#34;https://dansanderson.com/lab-notes/exploring-the-uwcug-disk-hoard/&#34;&gt;were in mixed condition&lt;/a&gt;, and I&amp;rsquo;m currently holding the collection in the hopes that someday I&amp;rsquo;ll be able to clean and scan the disks for rare or original data files.&lt;/p&gt;
&lt;p&gt;Ray has been through a lot recently, and he has had to pause his vintage computer repair services and sell off his collection. Seattle Commodore community maven Michael Myers helped parlay many fine pieces into a good return for Ray, and in that sale I acquired Ray&amp;rsquo;s personal &lt;a href=&#34;https://www.computinghistory.org.uk/det/7652/Commodore-128D/&#34;&gt;Commodore 128DCR&lt;/a&gt;. I already had a 128DCR, but this was Ray&amp;rsquo;s own machine, outfitted with mods and hand-typed labels. Plus I was glad to have a spare: the 128D—the &amp;ldquo;cost reduced&amp;rdquo; 128DCR specifically—is one of the gems of Commodore&amp;rsquo;s 8-bit era.&lt;/p&gt;
&lt;p&gt;I was happy to hear that Ray recently &lt;a href=&#34;https://portcommodore.com/rcarlsen/&#34;&gt;re-opened his services for repairing Commodore computers and monitors&lt;/a&gt;. My 128DCR (not his) had a failing power supply, and I decided to take him up on doing a replacement, in the hopes that I can keep this thing running for another ten years. I mentioned to Ray that his own 128DCR ended up in my hands, and if he wanted it back, he could have it at any time. Ray was excited that his well-loved machine had not drifted too far, and he offered to replace my power supply and throw in some other goodies in exchange.&lt;/p&gt;
&lt;p&gt;It turned out Ray still had more vintage books, software, and peripherals in need of a new shepherd. I drove my Mazda down to his farmhouse, dropped off my C128, and loaded the car with sixteen boxes. Below are some quick photos of the contents. I have not done a complete inspection of the disks, but from a quick visual check they look to be in better shape than the previous hoard. Some of the software boxes shown don&amp;rsquo;t have disks in them, but many do.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0492.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0492.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0492_hu_698e4722df371e4.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0492_hu_b7132498d19f0d03.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0492.jpeg&#34;
        alt=&#34;The haul stacked up temporarily in my garage&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The haul stacked up temporarily in my garage.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Ray had a stack of appliance service manuals that he no longer wanted. I agreed to haul them, though I&amp;rsquo;m unlikely to keep them. I&amp;rsquo;m not sure how to pass on their value, if any.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0493.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0493.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0493_hu_751f4965986e340f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0493_hu_f552ca1e85446fad.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0493.jpeg&#34;
        alt=&#34;A stack of Panasonic VCR service manuals&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A stack of Panasonic VCR service manuals.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;floppy-disk-condition&#34;&gt;Floppy disk condition&lt;/h2&gt;
&lt;p&gt;One of the challenges of maintaining large collections of magnetic media is keeping it in good condition. Natural degradation with time and varying storage conditions can render floppy disks not just unreadable but hazardous to disk drives. I started with a long box full of well-organized floppies, and tried to assess their condition visually. These look good enough to at least try in a disk drive.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0494.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0494.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0494_hu_3560cd4da809d827.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0494_hu_6bae31498b890898.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0494.jpeg&#34;
        alt=&#34;A ream of floppy disks: duplicates of disk magazines&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A ream of floppy disks: duplicates of disk magazines.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0495.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0495.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0495_hu_1b291b1a6d5baaac.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0495_hu_683d528abe2f746d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0495.jpeg&#34;
        alt=&#34;The ream of disk magazines with labeled tab inserts&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Disk magazines, organized.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0496.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0496.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0496_hu_85a0129b12b806f9.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0496_hu_8199d1457e073d6a.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0496.jpeg&#34;
        alt=&#34;A few of the disks from the ream, with hand-written labels&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A few of the disks from the ream.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0497.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0497.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0497_hu_bd2381912c7d6901.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0497_hu_4a61418316af6e43.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0497.jpeg&#34;
        alt=&#34;Inspection of one of the disk&amp;amp;#39;s magnetic region, showing it to be in good condition&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The disks appear to be in good condition. I have not yet tested them.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0498.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0498.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0498_hu_5316dc1f9fb2e765.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0498_hu_a4d55db8890b3873.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0498.jpeg&#34;
        alt=&#34;More disks from the ream&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
More disks from the ream.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0499.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0499.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0499_hu_c7b7e2ae18bddf84.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0499_hu_589ae6bbd94cd17b.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0499.jpeg&#34;
        alt=&#34;More magnetic surface inspection&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
More magnetic surface inspection.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The other challenge is to decide whether the data is actually worth extracting. If these were unique data disks or rare software, it might be worth the effort. Most of the UWCUG library is software that was popular at the time, and these have all been archived digitally by hobbyists. There&amp;rsquo;s no archival value to extracting the same data from these disks.&lt;/p&gt;
&lt;p&gt;If they&amp;rsquo;re readable, they could be fun to play with, in the sense of recreating the experience of using the original software. Making new disks by writing archived digital data to higher quality vintage media would be another option.&lt;/p&gt;
&lt;h2 id=&#34;boxed-software-set-1&#34;&gt;Boxed software, set 1&lt;/h2&gt;
&lt;p&gt;The first box of boxed software included several games and productivity titles for the Commodore 64. Many but not all of these have their disks. The FastLoad cartridge is not in this box, though I have at least one loose FastLoad from the previous haul.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0500.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0500.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0500_hu_cf4ff161720e0107.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0500_hu_1f6ffc36ed642137.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0500.jpeg&#34;
        alt=&#34;A set of C64 software with boxes and manuals&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A set of C64 software with boxes and manuals.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This box contained a set of Commodore 128 manuals as would be included with the computer, a bit beat up. The &amp;ldquo;system diskettes&amp;rdquo; sleeve is new to me, but alas empty.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0501.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0501.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0501_hu_121ddb6d01ead2fe.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0501_hu_dce9af6db6a4cc35.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0501.jpeg&#34;
        alt=&#34;C128 manuals, as included with the computer&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
C128 manuals, as included with the computer.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0502.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0502.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0502_hu_90be65e0574db521.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0502_hu_81bfd04c0be28796.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0502.jpeg&#34;
        alt=&#34;RUN magazine&amp;amp;#39;s 1986 special issue C64 programmer&amp;amp;#39;s reference chart&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
RUN magazine&#39;s 1986 special issue C64 programmer&#39;s reference chart.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I don&amp;rsquo;t know GameWare or Mastertronic by name, but I&amp;rsquo;m very familiar with inexpensive game multipacks that were available cheaply in software stores. Known affectionately as &amp;ldquo;shovelware,&amp;rdquo; these titles were mostly cheaply produced, but there were some real gems. This &amp;ldquo;Wing Commander&amp;rdquo; is a simple terrestrial flight simulator and has no relationship with the popular space-faring Origin Systems franchise.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0503.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0503.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0503_hu_698d910422be7cdd.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0503_hu_b2739f5b4336f16c.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0503.jpeg&#34;
        alt=&#34;GameWare by Mastertronic: Wing Commander and Skyjet&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
GameWare by Mastertronic: Wing Commander and Skyjet.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0504.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0504.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0504_hu_5cf127743b6c4b96.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0504_hu_7896918d2331801.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0504.jpeg&#34;
        alt=&#34;A page from Typing Tutor IV for the C64 by Kriya Systems, Inc.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A page from Typing Tutor IV for the C64 by Kriya Systems, Inc.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;loadstar-collection&#34;&gt;Loadstar collection&lt;/h2&gt;
&lt;p&gt;The wood-grain-panelled floppy disk organizer is packed with issues of the &lt;a href=&#34;https://www.c64-wiki.com/wiki/Loadstar&#34;&gt;Loadstar&lt;/a&gt; disk magazine, both originals and backups.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0505.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0505.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0505_hu_f8727ec59215e793.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0505_hu_22b78f9c3d476d91.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0505.jpeg&#34;
        alt=&#34;Loadstar back issue catalog disk, a single disk with multiple issues&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Loadstar back issue catalog disk, a single disk with multiple issues.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0509.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0509.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0509_hu_cb073996c38463ce.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0509_hu_5be2a6de8a333e0c.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0509.jpeg&#34;
        alt=&#34;Loadstar issue 74 disk 2, original label&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Loadstar issue 74 disk 2, original label.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0511.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0511.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0511_hu_b4cdc9e878884a1e.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0511_hu_fba55b72dc589a26.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0511.jpeg&#34;
        alt=&#34;Visual inspection of a Loadstar disk&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Visual inspection of a Loadstar disk.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;modems&#34;&gt;Modems&lt;/h2&gt;
&lt;p&gt;One box contained a variety of &lt;a href=&#34;https://en.wikipedia.org/wiki/Modem&#34;&gt;modems&lt;/a&gt; for Commodore 8-bit computers, from various manufacturers. This set includes three complete Commodore 300 baud modem sets that appear to be &lt;em&gt;new in box&lt;/em&gt; except for storage wear on the outermost packaging, including the software disk with the &lt;a href=&#34;https://en.wikipedia.org/wiki/Quantum_Link&#34;&gt;Quantum Link&lt;/a&gt; client on one side and terminal software on the other, along with Quantum Link documentation. Quantum Link would eventually become &lt;a href=&#34;https://en.wikipedia.org/wiki/AOL&#34;&gt;America Online&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;300 baud was painfully slow, noticeable even through the luster of connecting to another computer system over the telephone for the first time. 1200 baud was a godsend by comparison, 2400 baud was extra fancy, and 56.6k bps was living in the future.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0512.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0512.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0512_hu_a37064618205e8e4.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0512_hu_e06f58206230a54d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0512.jpeg&#34;
        alt=&#34;Three complete Commodore modem/300 sets, with boxes, disks, manuals, and hardware&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Three complete Commodore modem/300 sets, with boxes, disks, manuals, and hardware.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0515.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0515.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0515_hu_8d32602d8503c464.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0515_hu_49703b6f1e13e252.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0515.jpeg&#34;
        alt=&#34;One of the Commodore modem/300 sets on display: modem, manual, disk, Q-link keyboard overlay&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
One of the Commodore modem/300 sets on display: modem, manual, disk, Q-link keyboard overlay.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0516.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0516.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0516_hu_5ee22fa4d619ea62.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0516_hu_e7afb7df7163c0f5.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0516.jpeg&#34;
        alt=&#34;More modems in the box: Commodore Automodem, Commodore modem/1200, MasterModem, HesModem II, and others&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
More modems in the box: Commodore Automodem, Commodore modem/1200, MasterModem, HesModem II, and others.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;printer-interfaces&#34;&gt;Printer interfaces&lt;/h2&gt;
&lt;p&gt;While a few printers were made exclusively to work with Commodore computers over the IEC port, most printers were built to work with multiple computers, requiring separate interface hardware. One box in this set was nothing but a variety of such interfaces.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0517.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0517.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0517_hu_bf822972081139b4.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0517_hu_363044b036b62883.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0517.jpeg&#34;
        alt=&#34;A box of Commodore printer interfaces from various manufacturers&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A box of Commodore printer interfaces from various manufacturers.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One I had as a kid was the Super Graphics, which included DIP switches for configuring character modes, and a reset button. Both Super Graphics and Super Graphics Jr. were in one of the boxes.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0518.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0518.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0518_hu_cc28e05de7e14d91.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0518_hu_de7665a3e3722683.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0518.jpeg&#34;
        alt=&#34;More Commodore printer interfaces&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
More Commodore printer interfaces.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;books-set-1&#34;&gt;Books, set 1&lt;/h2&gt;
&lt;p&gt;The first set of books I unboxed included some real gems that I didn&amp;rsquo;t already own. I seem to refer to &lt;em&gt;Inside Commodore DOS&lt;/em&gt; on a regular basis from a downloaded PDF, so I&amp;rsquo;m excited to finally have one in print. Abacus Software&amp;rsquo;s &lt;em&gt;Anatomy of the 1541&lt;/em&gt; will be similarly useful. I never owned &lt;em&gt;The Black Book of C-128&lt;/em&gt;, and this is the first of several copies in this collection.&lt;/p&gt;
&lt;p&gt;This is the second C128 System Guide encountered so far, and of course no set of Commodore books would be complete without yet another copy of the User&amp;rsquo;s Guide and Programmer&amp;rsquo;s Reference, both in good condition except for some cover wear. The older C64 User&amp;rsquo;s Manual is official, and fun to see.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;All About the Commodore 64, Volume One&lt;/em&gt; by Craig Chamberlain is one of the best introductions to Commodore 64 BASIC ever published. I already have one but it&amp;rsquo;s always fun to find in the wild.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0519.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0519.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0519_hu_fd387a42dc1c8e1f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0519_hu_5c1ac7075b67e098.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0519.jpeg&#34;
        alt=&#34;Books: Inside Commodore DOS, Anatomy of the 1541, All About the Commodore Volume 1, The Black Book of C128, and official C64 and C128 user manuals&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Books: Inside Commodore DOS, Anatomy of the 1541, All About the Commodore Volume 1, The Black Book of C128, and official C64 and C128 user manuals.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Just today, my father told me a story. His father had a small electronics hobby, and when he died in 1974, a family friend re-homed his electronics workshop supplies to Lee Felsenstein. Felsenstein would go on to design the Osborne 1 with Adam Osborne, which would release seven years later. Perhaps my father&amp;rsquo;s father&amp;rsquo;s hobby supplies played a small role in vintage computing history. A great Father&amp;rsquo;s Day story to learn the day after acquiring an Osborne 1 User&amp;rsquo;s Reference Guide.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0520.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0520.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0520_hu_2f1731b85c6415b7.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0520_hu_4c02b973fea8c132.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0520.jpeg&#34;
        alt=&#34;Osborne 1 User&amp;amp;#39;s Reference Guide&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Osborne 1 User&#39;s Reference Guide.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Tucked in with the books is a stack of software catalogs from Commodore, and from Softdisk Publishing.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0521.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0521.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0521_hu_d06180ec60a9dce7.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0521_hu_8d42ce98a6455c39.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0521.jpeg&#34;
        alt=&#34;Commodore software and accessories catalogs&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Commodore software and accessories catalogs.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0522.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0522.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0522_hu_28731fe84a3ab4ee.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0522_hu_e8e8ac4ce3469187.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0522.jpeg&#34;
        alt=&#34;Loadstar back issue catalog&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Loadstar back issue catalog.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;binders-set-1&#34;&gt;Binders, set 1&lt;/h2&gt;
&lt;p&gt;One of my favorite kinds of things to find is binders of printouts. I&amp;rsquo;m certainly guilty myself of printing whatever information I could download over slow modem connections, paper and ink being cheap or free, and digital storage being scarce, unreliable, and difficult to browse. It can be difficult to extract the value out of things like these, but they also tend to contain documents that have otherwise completely disappeared from the world. It&amp;rsquo;d be a huge project, but it might actually be worth scanning and OCR&amp;rsquo;ing this stuff. Some of my own binders have useful documents that I have not been able to find online.&lt;/p&gt;
&lt;p&gt;I spot-checked a few of these with Google, and while I could find similar docs in some cases, I could not find the originals.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0523.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0523.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0523_hu_a97f22ba3bbdda85.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0523_hu_83a1b6902ca3e8a8.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0523.jpeg&#34;
        alt=&#34;A stack of binders of printouts and notes&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A stack of binders of printouts and notes.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0524.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0524.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0524_hu_b8510a2f11b1634b.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0524_hu_e20804c51c78eeb6.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0524.jpeg&#34;
        alt=&#34;Printout: Blazin Forth for CBM-64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Printout: Blazin Forth for CBM-64.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0525.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0525.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0525_hu_d2e49d68547215c3.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0525_hu_feef9e02cb839a6e.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0525.jpeg&#34;
        alt=&#34;Printout: Example 8051 Board Design&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Printout: Example 8051 Board Design.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0526.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0526.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0526_hu_f9265a4123cdd855.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0526_hu_3a2ee0c6dadee5e9.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0526.jpeg&#34;
        alt=&#34;Printout: C= Hacking, volume 1, issue 2, April 1992&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Printout: C= Hacking, volume 1, issue 2, April 1992.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Many of these binders make dutiful use of binder tabs, with titles either handwritten or typed. My own binders also have such a feature.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0527.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0527.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0527_hu_cb967fe5a392be2c.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0527_hu_85d487e1bc0a8902.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0527.jpeg&#34;
        alt=&#34;Binder tabs: Comm Programming, Perfect Calc, Z80 Assembler, Power Utility&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Binder tabs: Comm Programming, Perfect Calc, Z80 Assembler, Power Utility.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0534.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0534.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0534_hu_9246dc355200465f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0534_hu_bc5a1b13cf8510e1.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0534.jpeg&#34;
        alt=&#34;Printout: BForth.txt&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Printout: BForth.txt
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0537.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0537.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0537_hu_a84f50fd0d7aaf29.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0537_hu_27c619aefef04a86.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0537.jpeg&#34;
        alt=&#34;Printout: Graphics 52, Interesting Memory Locations&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Printout: Graphics 52, Interesting Memory Locations
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0538.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0538.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0538_hu_15f410ed2b6e0201.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0538_hu_6825b1f39f7c5c7.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0538.jpeg&#34;
        alt=&#34;Printout: documents from the original GEOS disks&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Printout: documents from the original GEOS disks
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0540.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0540.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0540_hu_ab7caa15a71a0270.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0540_hu_3a4a2d88db51fde8.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0540.jpeg&#34;
        alt=&#34;Printout: Abacus Software, Forth-64: Overview of the editor buffer&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Printout: Abacus Software, Forth-64: Overview of the editor buffer.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;handwritten-notes&#34;&gt;Handwritten notes&lt;/h2&gt;
&lt;p&gt;My absolute favorite thing to find in this hobby is &lt;em&gt;evidence of use:&lt;/em&gt; handwritten notes, highlighting and underlining, holes cut into pages, price tags and receipts, and data disks. The binders contain many instances of hand-annotated machine code disassembly listings, and other such program listings.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0533.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0533.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0533_hu_f665ee4652ef19f9.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0533_hu_5468b435cd17fd8e.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0533.jpeg&#34;
        alt=&#34;One of many pages of hand-annotated machine code disassembly&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
One of many pages of hand-annotated machine code disassembly.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0539.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0539.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0539_hu_9d8d100489fa7119.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0539_hu_c0a78f657f1b1659.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0539.jpeg&#34;
        alt=&#34;Annotated printout of musical notation&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Annotated printout of musical notation.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0541.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0541.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0541_hu_d5f3cd4cc256ecfc.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0541_hu_5c48a68267370e63.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0541.jpeg&#34;
        alt=&#34;Annotated Forth-64 source code&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Annotated Forth-64 source code.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;uwcug-newsletters-and-documentation&#34;&gt;UWCUG newsletters and documentation&lt;/h2&gt;
&lt;p&gt;When I last picked up a bunch of stuff from Ray in 2019, I found but foolishly decided not to take thick stacks of University of Washington Commodore User Group original documentation, including newsletters and the lending library checkout history. Luckily, the newsletters binder survived, and it is now in my possession.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0528.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0528.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0528_hu_8586e9979e298fc0.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0528_hu_2849367ee265a658.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0528.jpeg&#34;
        alt=&#34;University of Washington Commodore User Group Newsletters, property of Ray Carlsen&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
University of Washington Commodore User Group Newsletters, property of Ray Carlsen.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0529.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0529.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0529_hu_dc519fe251192b54.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0529_hu_bf18c2153f768f90.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0529.jpeg&#34;
        alt=&#34;&amp;amp;#39;Please do not remove these newsletters... I have no copies! Thanks. Ray C.&amp;amp;#39;&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
&#34;Please do not remove these newsletters... I have no copies! Thanks. Ray C.&#34;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0531.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0531.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0531_hu_9b9b00e7f3b2d02e.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0531_hu_d29aa99b8bb93579.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0531.jpeg&#34;
        alt=&#34;UWCUG newsletter, volume 11, number 10, July 1983&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
UWCUG newsletter, volume 11, number 10, July 1983.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0530.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0530.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0530_hu_47370842d0655441.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0530_hu_42ac25aae73dfc13.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0530.jpeg&#34;
        alt=&#34;UWCUG newsletter, volume 15, number 2, February 1986&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
UWCUG newsletter, volume 15, number 2, February 1986.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0532.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0532.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0532_hu_da06e46b3bbb6f8e.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0532_hu_e47a2c193496f275.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0532.jpeg&#34;
        alt=&#34;UWCUG documentation binder tabs: Legislative Process, Lobbying, Procedures, Reference, &amp;amp;#39;AA&amp;amp;#39; Bills&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
UWCUG documentation binder tabs: Legislative Process, Lobbying, Procedures, Reference, &#34;AA&#34; Bills.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;loadstar-letter&#34;&gt;Loadstar Letter&lt;/h2&gt;
&lt;p&gt;The disk magazine Loadstar published a companion print newsletter, called &lt;em&gt;Loadstar Letter&lt;/em&gt;. One binder was dedicated exclusively to issues of this newsletter.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0535.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0535.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0535_hu_6b3d7cb0bd494889.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0535_hu_f9c0d67cd033cad6.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0535.jpeg&#34;
        alt=&#34;Loadstar Letters, a binder dedicated to the Loadstar print newsletter&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Loadstar Letters, a binder dedicated to the Loadstar print newsletter.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0536.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0536.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0536_hu_8298823a8650acbe.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0536_hu_8caf84ef266ecc4a.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0536.jpeg&#34;
        alt=&#34;Loadstar Letter #20, March 1995&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Loadstar Letter #20, March 1995.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;photocopied-books&#34;&gt;Photocopied books&lt;/h2&gt;
&lt;p&gt;Another popular crime of which I was most certainly guilty: photocopying entire computer books and putting them in binders. There must have been a time when photocopying at the library was cheap because I did a lot of it, instead of just buying the books. At some point, my mother&amp;rsquo;s pharmaceutical sales job entitled her to a photocopier &lt;em&gt;at home&lt;/em&gt; and I would just pirate library books to no end. I suspect the photocopies in these binders were more altruistically intended as backups for club use.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0542.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0542.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0542_hu_9c09d5d0ff43302f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0542_hu_ac60e57241a979d3.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0542.jpeg&#34;
        alt=&#34;Osborne Forth manual, photocopied&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Osborne Forth manual, photocopied.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0543.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0543.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0543_hu_e682bdcef42352b8.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0543_hu_578c241abc4b1894.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0543.jpeg&#34;
        alt=&#34;Osborne Forth manual, side view&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Osborne Forth manual, side view.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;loose-pages&#34;&gt;Loose pages&lt;/h2&gt;
&lt;p&gt;One box contained stacks of loose pages, not currently in binders. I&amp;rsquo;ll have to figure out something to do with these. Some are originals, some are printouts.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0544.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0544.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0544_hu_eade48e3c05b7a4f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0544_hu_a259ad5cacc8ed6.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0544.jpeg&#34;
        alt=&#34;Loose pages: printouts, looseleaf published text&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Loose pages: &#34;Editor Demo v64,&#34; copyright 1982 Commodore Business Machines; &#34;The Commodore 64 Screen Editor,&#34; official looseleaf documentation.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;m always delighted to find direct evidence of Ray&amp;rsquo;s participation in the UWCUG, such as this nametag.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0545.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0545.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0545_hu_f16e20a2b7233add.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0545_hu_c982b7d063dd2389.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0545.jpeg&#34;
        alt=&#34;Ray Carlsen, Computer Club Librarian name tag&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Ray Carlsen, Computer Club Librarian name tag.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;kaypro-cpm-and-software&#34;&gt;Kaypro, CP/M, and software&lt;/h2&gt;
&lt;p&gt;My father owned a Kaypro 4 for his work as an English professor, and I loved playing with it as a kid. When I got into collecting old computers, I told myself I would draw the line at the Kaypro: as nostalgic as it is for me, they&amp;rsquo;re large metal boxes and difficult to store. I bet they&amp;rsquo;re built pretty well, though, but I don&amp;rsquo;t actually know. Anyway, if I ever change my mind, I&amp;rsquo;m now prepared with a rather complete set of books and software. Just having these makes me want one.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0546.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0546.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0546_hu_7701a69f8e063dfa.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0546_hu_12b28640226d463b.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0546.jpeg&#34;
        alt=&#34;Wordstar: CP/M Edition manual, by The New MicroPro&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Wordstar: CP/M Edition manual, by The New MicroPro.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0547.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0547.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0547_hu_5dcee73de0653b5.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0547_hu_827948d1eb5a9404.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0547.jpeg&#34;
        alt=&#34;Kaypro Datastar, Reportstar, Calcstar master disks&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro Datastar, Reportstar, Calcstar master disks.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0548.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0548.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0548_hu_7a1e50b4ab6d39c3.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0548_hu_72a5d12c2b620245.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0548.jpeg&#34;
        alt=&#34;Kaypro Microsoft BASIC-80 master disks&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro Microsoft BASIC-80 master disks.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0577.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0577.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0577_hu_2a9a49882ad16c68.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0577_hu_cf973662390bba11.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0577.jpeg&#34;
        alt=&#34;Kaypro Datastar keyboard overlays, tucked into a book&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro Datastar keyboard overlays, tucked into a book.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I love this Kaypro reference manual for dealerships.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0578.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0578.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0578_hu_77b4c44871350f64.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0578_hu_a3d654d2bb8d1e7d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0578.jpeg&#34;
        alt=&#34;Kaypro Dealer Reference Manual, title page&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro Dealer Reference Manual, title page.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0579.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0579.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0579_hu_7159df2b13b0c379.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0579_hu_342c9772c7958fad.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0579.jpeg&#34;
        alt=&#34;Kaypro Dealer Reference Manual: Keyboard problems troubleshooting flowchart&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro Dealer Reference Manual: Keyboard problems troubleshooting flowchart.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0580.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0580.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0580_hu_ef42d4f3e98b6cf6.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0580_hu_cfc6dea3131cbb35.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0580.jpeg&#34;
        alt=&#34;Kaypro Dealer Reference Manual: schematic&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro Dealer Reference Manual: fold-out schematic.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0581.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0581.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0581_hu_b50c8519d4bf6c14.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0581_hu_ad60ef76f0da2bfa.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0581.jpeg&#34;
        alt=&#34;Kaypro Dealer Reference Manual: Answers to Often-asked Questions About Kaypro Products&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro Dealer Reference Manual: Answers to Often-asked Questions About Kaypro Products.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0582.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0582.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0582_hu_67ad8e35ec1bff1e.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0582_hu_8885e559dd590b16.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0582.jpeg&#34;
        alt=&#34;Kaypro II: Microsoft BASIC manual, photocopied and coil-bound&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro II: Microsoft BASIC manual, photocopied and coil-bound.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0583.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0583.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0583_hu_8624d85c8dd321a4.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0583_hu_fd7f5a6b6d4113fd.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0583.jpeg&#34;
        alt=&#34;Kaypro User&amp;amp;#39;s Guide, photocopied&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro User&#39;s Guide, photocopied; Perfect Writer reference card.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0584.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0584.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0584_hu_c06f975d570d5e35.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0584_hu_fcdebdc7296c5a61.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0584.jpeg&#34;
        alt=&#34;Kaypro II manuals, originals: S-BASIC, user guide, Select, CP/M&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Kaypro II manuals, originals: S-BASIC, user guide, Select, CP/M.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;More Kaypro books got mixed in with other Commodore and TRS-80 books.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0588.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0588.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0588_hu_e70d9820f605bb7d.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0588_hu_555287950ceb696c.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0588.jpeg&#34;
        alt=&#34;Commodore, Kaypro, and TRS-80 programming books&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Commodore, Kaypro, and TRS-80 programming books.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This bright red &lt;em&gt;CP/M Assembly Language Programming&lt;/em&gt; book is a huge find for me. I&amp;rsquo;ve always wanted to know more about CP/M, and this book contains information I&amp;rsquo;ve never seen before. I&amp;rsquo;m far from an expert but this is great.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0589.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0589.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0589_hu_d3cb77f48a6d9b0b.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0589_hu_b898a9a74fdd4d11.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0589.jpeg&#34;
        alt=&#34;More Kaypro books, including an amazing CP/M Assembly Language Programming book&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
More Kaypro books, including an amazing CP/M Assembly Language Programming book.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;commodore-software-set-2&#34;&gt;Commodore software, set 2&lt;/h2&gt;
&lt;p&gt;Next box, back to Commodore software. Some boxed software, and more original software with disks and manuals in plastic bags. I appreciate how most of this came from a club lending library, so instead of being pristine collector&amp;rsquo;s items, they&amp;rsquo;re processed intended for heavy use: backups, photocopies, retail boxes replaced with alternate storage.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0549.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0549.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0549_hu_49cf5aa59ee7ac62.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0549_hu_a96185a2951bc244.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0549.jpeg&#34;
        alt=&#34;More Commodore 64 software, in boxes and bags&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
More Commodore 64 software, in boxes and bags.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0550.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0550.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0550_hu_eeba2be022f217f1.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0550_hu_871666b90d55eb03.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0550.jpeg&#34;
        alt=&#34;Springboard Certificate Maker manual, photocopied&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Springboard Certificate Maker manual, photocopied.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Gotta love ring binder manuals!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0551.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0551.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0551_hu_f81ee24c46d1dd92.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0551_hu_e1cae20ebefc9978.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0551.jpeg&#34;
        alt=&#34;M&amp;amp;#39;File Data Management by M&amp;amp;#39;Soft, ring binder manual&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
M&#39;File Data Management by M&#39;Soft, ring binder manual.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This box has two complete copies of the Commodore 128 Jane office suite, which I&amp;rsquo;ve never heard of before. &lt;a href=&#34;https://en.wikipedia.org/wiki/Jane_(software)&#34;&gt;Jane&lt;/a&gt; was written by Arktronics in 1984, and the Commodore version was published by Commodore directly. Also notable: Spritemaster 64, &amp;ldquo;for ages 8 to adult.&amp;rdquo;&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0552.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0552.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0552_hu_22089f0812b268b8.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0552_hu_728aa264cdf42277.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0552.jpeg&#34;
        alt=&#34;Display of bagged software: Commodore 128 Jane office suite, Spritemaster 64, etc.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Display of bagged software: Commodore 128 Jane office suite, Spritemaster 64, etc.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0553.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0553.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0553_hu_351ad0d56dc0ac9f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0553_hu_4ce2ab1a7ff59b1b.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0553.jpeg&#34;
        alt=&#34;A fully boxed set of Commodore 128 Jane, in good condition&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A fully boxed set of Commodore 128 Jane, in good condition.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0554.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0554.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0554_hu_8348e6b09cc1bdb2.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0554_hu_339c2f13ac4c3f2c.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0554.jpeg&#34;
        alt=&#34;Commodore 128 Jane, box contents&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Commodore 128 Jane, box contents, including disk and manual behind plastic.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;8-inch-floppy-disks&#34;&gt;8-inch floppy disks&lt;/h2&gt;
&lt;p&gt;While I&amp;rsquo;m pretty sure I&amp;rsquo;ve seen an 8-inch floppy disk sometime in my life, I think this is the first time I&amp;rsquo;ve had any in my personal collection. A box had two thick stacks of them, with arcane labels. Naturally I do not have an 8-inch floppy drive, so I&amp;rsquo;m just going to hold them and feel like a hobbit.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not sure what Terak is but there is a folder of documents about it also.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0555.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0555.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0555_hu_d7718e393a502434.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0555_hu_8a922d7304fabe54.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0555.jpeg&#34;
        alt=&#34;8-inch floppy disks: Terak System Acceptance Tests&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
8-inch floppy disks: Terak System Acceptance Tests.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0557.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0557.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0557_hu_3bb00bebb01dec55.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0557_hu_3660adfaf14ff197.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0557.jpeg&#34;
        alt=&#34;8-inch floppy disk out of the sleeve, held in my hand&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
8-inch floppy disk out of the sleeve, held in my hand.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;more-book-finds&#34;&gt;More book finds&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0558.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0558.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0558_hu_bb664bfd0a4f11e9.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0558_hu_5e100ed6c37e1ad7.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0558.jpeg&#34;
        alt=&#34;Books: What Every Kid (and adult) Should Know About Computers; Z80 Technical Manual; Z80 Microcomputer Handbook; Raster Graphics Handbook&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Books: What Every Kid (and adult) Should Know About Computers; Z80 Technical Manual; Z80 Microcomputer Handbook; Raster Graphics Handbook.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0559.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0559.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0559_hu_aa4719409369a3ba.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0559_hu_6eadf399d18183aa.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0559.jpeg&#34;
        alt=&#34;A page from What Every Kid (and adult) Should Know About Computers&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A page from What Every Kid (and adult) Should Know About Computers.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Multiple VIC-20 programming books. Two copies of &lt;em&gt;VIC-20 Programmers Reference Guide&lt;/em&gt; are sealed in plastic, one with coil binding and after-market tabs (!) and another with loose pages with the binding spliced off. The bound and tabbed version is a real find, unique and well preserved. &lt;em&gt;32 VIC-20 Computer Programs&lt;/em&gt; and &lt;em&gt;Get Acquainted with your VIC-20&lt;/em&gt; are in good shape. Two copies of &lt;em&gt;Personal Computing on the VIC-20&lt;/em&gt; are in poor condition, I&amp;rsquo;m going to say water damage even though it doesn&amp;rsquo;t look like water, exactly. 😬&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0568.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0568.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0568_hu_92468165c4258e04.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0568_hu_d3bab6d3a9ed78a3.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0568.jpeg&#34;
        alt=&#34;VIC-20 programming books, in various conditions&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
VIC-20 programming books, in various conditions.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0569.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0569.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0569_hu_a0b96e8bad146a64.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0569_hu_fab90554bf5b2e0d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0569.jpeg&#34;
        alt=&#34;Close-up of VIC-20 Programmers Reference Guide with labelled tabs added&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Close-up of VIC-20 Programmers Reference Guide with labelled tabs added.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0570.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0570.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0570_hu_c4ae60495db1538c.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0570_hu_dec1e50e71f55384.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0570.jpeg&#34;
        alt=&#34;A page from VIC-20 Programmers Reference Guide&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A page from VIC-20 Programmers Reference Guide.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I don&amp;rsquo;t know who sealed these books in plastic, but I&amp;rsquo;m grateful because they&amp;rsquo;re in excellent shape.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0571.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0571.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0571_hu_2bdcfa20a3572a7.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0571_hu_ec7321aea4184f40.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0571.jpeg&#34;
        alt=&#34;Two copies of The Black Book of C-128, sealed in plastic&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Two copies of The Black Book of C-128, sealed in plastic.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This &lt;em&gt;Illustrated Computer Dictionary&lt;/em&gt; is intensely nostalgic for me. I don&amp;rsquo;t know if I owned this specific book but I definitely had other books by this publisher, and/or in this spiral-bound format and title font. Great condition, only a little bent.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0572.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0572.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0572_hu_a3673681dbadb310.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0572_hu_2c96e1ce3e90ff0b.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0572.jpeg&#34;
        alt=&#34;Illustrated Computer Dictionary&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Illustrated Computer Dictionary.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0573.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0573.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0573_hu_7e5833aac6d27257.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0573_hu_f1d9871fba993b31.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0573.jpeg&#34;
        alt=&#34;A page from Illustrated Computer Dictionary&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A page from Illustrated Computer Dictionary.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The rest of the VIC-20 box, with some other Commodore programming books for good measure, titles mostly visible by the spines.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0574.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0574.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0574_hu_d7c3108c9fa0a6b4.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0574_hu_d48104e42abbb378.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0574.jpeg&#34;
        alt=&#34;A box of Commodore VIC-20 and C64 programming books&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A box of Commodore VIC-20 and C64 programming books.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A true gem from my childhood and I suspect well loved by anyone who encountered it, here&amp;rsquo;s &lt;em&gt;The Master Memory Map&lt;/em&gt; for the C64 by Paul Pavelko and Tim Kelly. I might already have one of these but dang it&amp;rsquo;s good to see it again.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0575.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0575.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0575_hu_fd63532a61c4bd2e.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0575_hu_d046d66dc0863f31.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0575.jpeg&#34;
        alt=&#34;The Master Memory Map for the Commodore 64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Master Memory Map for the Commodore 64.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;trs-80-books-and-audio-tapes-not-just-data-tapes&#34;&gt;TRS-80 books and audio tapes (not just data tapes)&lt;/h2&gt;
&lt;p&gt;Two TRS-80 reference manuals in ring binders also included sets of companion cassette tapes. I &lt;em&gt;think&lt;/em&gt; some of these tapes contained software to be loaded from a cassette player connected to the computer, as you would expect. But at least some of these tapes are &lt;em&gt;not&lt;/em&gt; data tapes but actual narrator-driven training material in audio form, to be listened to by a human. (I could be mis-reading the labels and they&amp;rsquo;re all audio tapes.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0561.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0561.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0561_hu_7a2f0216226b8ffe.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0561_hu_59bb22f528e98184.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0561.jpeg&#34;
        alt=&#34;TRS-80 Software Library binder&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
TRS-80 Software Library binder.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0562.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0562.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0562_hu_d3c83d64903a2291.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0562_hu_d8708b9b61a59bb2.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0562.jpeg&#34;
        alt=&#34;TRS-80 Model III Operation and BASIC Language Reference Manual&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
TRS-80 Model III Operation and BASIC Language Reference Manual.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0563.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0563.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0563_hu_5137545ae3464951.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0563_hu_5aada0fc3c96f26.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0563.jpeg&#34;
        alt=&#34;TRS-80 Level I BASIC Instruction Course companion data cassettes&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
TRS-80 Level I BASIC Instruction Course companion data cassettes.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0564.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0564.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0564_hu_f8fa7a984acfdf7d.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0564_hu_8ed03ea448600469.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0564.jpeg&#34;
        alt=&#34;TRS-80 Scripsit Training Program audio tapes&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
TRS-80 Scripsit Training Program audio tapes.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0565.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0565.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0565_hu_4a4ae109080c29fc.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0565_hu_f352107436d90aef.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0565.jpeg&#34;
        alt=&#34;TRS-80 Scripsit Training Program manual&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
TRS-80 Scripsit Training Program manual.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0566.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0566.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0566_hu_c197073ca73bbccd.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0566_hu_1cbca0bc83ac861d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0566.jpeg&#34;
        alt=&#34;Book: Getting Started with TRS-80 BASIC&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Book: Getting Started with TRS-80 BASIC.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0567.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0567.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0567_hu_aeb71a035d57d382.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0567_hu_9cf3fbc8b99c73a7.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0567.jpeg&#34;
        alt=&#34;A page from Getting Started with TRS-80 BASIC&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A page from Getting Started with TRS-80 BASIC.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0576.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0576.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0576_hu_dc3d00cd3fe7f538.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0576_hu_d269cba8fd5ec810.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0576.jpeg&#34;
        alt=&#34;TRS-80 service manual and Model 4 disk system owner&amp;amp;#39;s manual&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
TRS-80 service manual and Model 4 disk system owner&#39;s manual.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;tektronics-650-series-color-monitor&#34;&gt;Tektronics 650-Series Color Monitor&lt;/h2&gt;
&lt;p&gt;An impressive technical manual for an obscure professional monitor, the &lt;a href=&#34;https://w140.com/tekwiki/wiki/650&#34;&gt;Tektronix 650&lt;/a&gt;. This is probably gold to someone, but for me it might end up with the stack of VCR service manuals.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0585.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0585.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0585_hu_2d18167882950bd2.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0585_hu_8eb3c4bbc65fb414.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0585.jpeg&#34;
        alt=&#34;Tekronix 650-Series Color Monitors instruction manual, cover&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Tekronix 650-Series Color Monitors instruction manual, cover.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0586.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0586.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0586_hu_1151357417def260.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0586_hu_59349eabfd3d1bd9.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0586.jpeg&#34;
        alt=&#34;A page from Tekronix 650-Series Color Monitors instruction manual&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A page from Tekronix 650-Series Color Monitors instruction manual.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0587.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0587.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0587_hu_79c5b01509929758.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0587_hu_acbd3d36b9e6a6b2.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0587.jpeg&#34;
        alt=&#34;Tekronix 650-Series Color Monitors instruction manual, chapter navigation tabs&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Tekronix 650-Series Color Monitors instruction manual, chapter navigation tabs.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;one-more-box-of-software&#34;&gt;One more box of software&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0590.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0590.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0590_hu_114e70cc0510ac12.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0590_hu_d91f58314d2404a2.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0590.jpeg&#34;
        alt=&#34;WordWriter 128 box and manual (no disk); GEOS C64 box and manual (no disk); a book on VisiCalc for Science and Engineering&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
WordWriter 128 box and manual (no disk); GEOS C64 box and manual (no disk); a book on VisiCalc for Science and Engineering.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0591.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0591.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0591_hu_eeebcd1f8ef2e5ce.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0591_hu_ef42368f61710f76.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0591.jpeg&#34;
        alt=&#34;TI-99/4A Tunnels of Doom cartridge; Certified Personal Accountant for the C64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
TI-99/4A Tunnels of Doom cartridge; Certified Personal Accountant for the C64.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0592.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0592.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0592_hu_bcbe63a0f7a5da77.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0592_hu_e930c3ab2fb076a1.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0592.jpeg&#34;
        alt=&#34;Close-up of TI-99/4A Tunnels of Doom&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Close-up of TI-99/4A Tunnels of Doom.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0593.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0593.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0593_hu_bbe689c65ec55bd9.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0593_hu_37d31b97e8fb602b.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0593.jpeg&#34;
        alt=&#34;Close-up of Certified Personal Accountant for the C64, by Sundex&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Close-up of Certified Personal Accountant for the C64, by Sundex.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I don&amp;rsquo;t recognize &lt;em&gt;National Lampoon&amp;rsquo;s Chess Maniac 5 Billion and 1&lt;/em&gt;, a &amp;ldquo;rude&amp;rdquo; parody of the Chessmaster games, for PC. It comes on twelve 3-1/2&amp;quot; floppy disks. &lt;a href=&#34;https://www.youtube.com/watch?v=OOCACADBrvE&#34;&gt;Here&amp;rsquo;s a video&lt;/a&gt; featuring some of the humor, including the &amp;ldquo;bawdy&amp;rdquo; chess set, creepy voiceover, and modest full-motion video. (The player in this video chose the name &amp;ldquo;Dan&amp;rdquo; and it&amp;rsquo;s freaking me out.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0594.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0594.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0594_hu_159a25fda6aa672f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0594_hu_a4ea69e09d458c5f.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0594.jpeg&#34;
        alt=&#34;PaperClip word processor manual (box and disks in another photo); National Lampoon&amp;amp;#39;s Chess Maniac 5 Billion and 1 for PC; Super Sunday for C64 box&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
PaperClip word processor manual (box and disks in another photo); National Lampoon&#39;s Chess Maniac 5 Billion and 1 for PC; Super Sunday for C64 box.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0595.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0595.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0595_hu_5b377335d8efbf0f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0595_hu_d81a83288d4f71dd.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0595.jpeg&#34;
        alt=&#34;Close-up of fold-out for Chess Maniac&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Close-up of fold-out for Chess Maniac.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0596.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0596.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0596_hu_3eb6c2212536f94a.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0596_hu_fe5e83e638c29f42.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0596.jpeg&#34;
        alt=&#34;Close-up of contents for Chess Maniac: twelve 3-1/2-inch floppy disks, manual as a parody magazine&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Close-up of contents for Chess Maniac: twelve 3-1/2-inch floppy disks, manual as a parody magazine.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It wouldn&amp;rsquo;t be a vintage software collection without a bit of pornography, and I found a commercial title on a single PC 3-1/2&amp;quot; floppy disk hidden in the Chess Maniac box. I&amp;rsquo;m not posting a photo.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;Super Sunday&lt;/em&gt; box actually has the original game disk, and came with a couple of unintended bonus games also in the box.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0598.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0598.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0598_hu_453523d92a8624b5.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0598_hu_f4c41d23921831c8.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0598.jpeg&#34;
        alt=&#34;Contents of the Super Sunday box: the Super Sunday C64 disk, but also The Great American Cross-Country Road Race and two other disks&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Contents of the Super Sunday box: the Super Sunday C64 disk, but also The Great American Cross-Country Road Race and two other disks.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The PaperClip word processor used a copy protection &lt;a href=&#34;https://en.wikipedia.org/wiki/Dongle&#34;&gt;dongle&lt;/a&gt;, a device that you connect to the C64 joystick port that exists solely to prevent illicit copying. The program doesn&amp;rsquo;t run without the dongle connected, so you can&amp;rsquo;t make copies for your friends.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0599.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0599.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0599_hu_3698d4cb33efb8c4.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0599_hu_c1177a1daa7c6b8.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0599.jpeg&#34;
        alt=&#34;PaperClip word processor for the C64, with license dongles&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
PaperClip word processor for the C64, with license dongles.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0600.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0600.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0600_hu_e540b0bf6bc7b6ab.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0600_hu_2f41901c38141b35.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0600.jpeg&#34;
        alt=&#34;Lovejoy&amp;amp;#39;s Preparation for the SAT for the C64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Lovejoy&#39;s Preparation for the SAT for the C64.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0601.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0601.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0601_hu_d2bd59e666990869.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0601_hu_8cc48bbea49d3372.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0601.jpeg&#34;
        alt=&#34;Paperclip II for the C128, disk, manuals, box, and license dongle&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Paperclip II for the C128, disk, manuals, box, and license dongle.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0602.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0602.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0602_hu_77a68e3c0b711327.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0602_hu_f4af61a503ba1cad.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0602.jpeg&#34;
        alt=&#34;The Print Shop for the C64, box, disks, and some documentation; not including the colored tractor paper&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Print Shop for the C64, box, disks, and some documentation; not including the colored tractor paper. Price sticker: $44.88 at Payless.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0603.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0603.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0603_hu_56f1b161c22df80f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0603_hu_fdf53530722e23e6.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0603.jpeg&#34;
        alt=&#34;C64 software: Adventure Construction Set, two copies of Seven Cities of Gold, Carriers At War; the classic TI-99/4A Beginner&amp;amp;#39;s Guide to BASIC book&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
C64 software: Adventure Construction Set, two copies of Seven Cities of Gold, Carriers At War; the classic TI-99/4A Beginner&#39;s Guide to BASIC book.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0604.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0604.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0604_hu_26d799cfa7ce6e6e.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0604_hu_fd9acc4ef901d9c9.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0604.jpeg&#34;
        alt=&#34;Close-up of Carriers at War for the C64, with original disks&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Close-up of Carriers at War for the C64, with original disks.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0605.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0605.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0605_hu_a4afbec1aeed6b59.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0605_hu_d95ac38817621c72.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0605.jpeg&#34;
        alt=&#34;C64 software: Paperboy, M.U.L.E., Mail Order Monsters&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
C64 software: Paperboy, M.U.L.E., Mail Order Monsters.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0606.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0606.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0606_hu_c95497e7dcc649d0.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0606_hu_b8b54c859d0e50a0.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0606.jpeg&#34;
        alt=&#34;Inspection of the Paperboy disk&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Inspection of the Paperboy disk.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;electronic-servicing-and-technology-magazine&#34;&gt;Electronic Servicing and Technology magazine&lt;/h2&gt;
&lt;p&gt;Closing out this collection is a giant stack of Electronic Servicing &amp;amp; Technology magazines, a long run of a subscription for the University of Washington Instructional Medical Services department. At first glance, this magazine seems targeted at appliance design and repair professionals, and I&amp;rsquo;m not sure how much I&amp;rsquo;ll get out of it as a newb digital electronics hobbyist. They&amp;rsquo;re in great shape and it&amp;rsquo;s a tall stack.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0607.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0607.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0607_hu_a9bda5b46a53dd06.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0607_hu_1e6da486785baebb.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0607.jpeg&#34;
        alt=&#34;Giant stack of Electronic Servicing and Technology magazines&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Giant stack of Electronic Servicing and Technology magazines.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0608.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0608.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0608_hu_1f38ae9a3de54db5.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0608_hu_43ae9e91989551b0.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0608.jpeg&#34;
        alt=&#34;Electronic Servicing and Technology, December 1986&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Electronic Servicing and Technology, December 1986.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The box below the pile is more A/V equipment service manuals, but I decided to take a closer look, and I found a few interesting things.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0616.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0616.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0616_hu_bf5275961d78f32a.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0616_hu_cdf57b633680d893.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0616.jpeg&#34;
        alt=&#34;1983 Software Writer&amp;amp;#39;s Market&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
1983 Software Writer&#39;s Market, a directory of early home computer software publishers.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0617.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0617.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0617_hu_3c2e01c66662dbc5.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0617_hu_f2c14f38506ae62c.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0617.jpeg&#34;
        alt=&#34;A page from the 1983 Software Writer&amp;amp;#39;s Market&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A page from the 1983 Software Writer&#39;s Market.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0618.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0618.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0618_hu_47cee9e33ee3527b.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0618_hu_c7bc3a2c17870b58.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0618.jpeg&#34;
        alt=&#34;Andrew Microwave Antenna System Computer, slide rule calculator&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Andrew Microwave Antenna System Computer, slide rule calculator.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0619.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0619.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0619_hu_70c7db142b92c9de.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0619_hu_415b14aaa0488610.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0619.jpeg&#34;
        alt=&#34;Ampex A/V Systems Price Book, on microfiche&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Ampex A/V Systems Price Book, on microfiche.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0620.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0620.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0620_hu_f1a5afee156bd9ed.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0620_hu_1a1e53e38a39cdba.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0620.jpeg&#34;
        alt=&#34;Close-up of Ampex A/V Systems Price Book microfiche slide&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Close-up of Ampex A/V Systems Price Book microfiche slide (but not close enough).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This box had a whole piece of hardware in it that I didn&amp;rsquo;t notice: a Zenith Space Command TV remote control console. Sadly, this is not the more famous earlier Space Command that &lt;a href=&#34;https://www.theverge.com/23810061/zenith-space-command-remote-control-button-of-the-month&#34;&gt;used a mechanical remote that communicated with ultrasonic sound&lt;/a&gt;. This is a newer model that appears to have used a more conventional battery-powered infrared remote. Also sadly, I do not see the remote that goes with this anywhere in the box. The world has moved on from analog TV signals anyway, so this is dead junk. (I see similar units on eBay, but no.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0621.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0621.jpeg 1280w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0621_hu_c37df5f0b6b9595f.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0621_hu_c9e92f6f8bd805c8.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0621.jpeg&#34;
        alt=&#34;Zenith Space Command TV remote control console&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Zenith Space Command TV remote control console.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0622.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0622.jpeg 960w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0622_hu_8d971dbabdaae396.jpeg 600w, https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0622_hu_a373d20b6e49a888.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/gifts-from-ray/IMG_0622.jpeg&#34;
        alt=&#34;Close-up of Zenith Space Command TV remote control console&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Close-up of Zenith Space Command TV remote control console.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr&gt;
&lt;p&gt;Many thanks to Ray for letting me take on these items! If you have a Commodore 8-bit that needs a bit of love, consider &lt;a href=&#34;https://portcommodore.com/rcarlsen/&#34;&gt;enlisting Ray&amp;rsquo;s services&lt;/a&gt;.&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>Character Study</title>
      <link>https://dansanderson.com/mega65/character-study/</link>
      <pubDate>Fri, 30 May 2025 17:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/character-study/</guid>
      <description>&lt;p&gt;Character Study. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for May 2025.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Character Study. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for May 2025.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/character-study/M65Digest_2025May.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/character-study/M65Digest_2025May.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Character Study.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/charattrs.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/character-study/charattrs.png&#34;
            width=&#34;368&#34;
            height=&#34;182&#34;
            alt=&#34;&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s upgrade season in the MEGA65 community! We partied hearty for the 10th anniversary last month, and the result is an all-new stable release of the MEGA65 platform packed with features and bug fixes, a bug fix update to the C64 core, and a new version of the M65Connect app. We also finished up the Screenful of BASIC compo, with 26 entries!&lt;/p&gt;
&lt;p&gt;For this month&amp;rsquo;s feature article, I&amp;rsquo;m starting my series on MEGA65 character graphics. It&amp;rsquo;s a big subject that we&amp;rsquo;ll cover over multiple issues. We&amp;rsquo;ll probably take breaks to cover other subjects just to mix things up.&lt;/p&gt;
&lt;p&gt;Here we go!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;mega65-platform-v097-released&#34;&gt;MEGA65 platform v0.97 released!&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s here! Over 14 months in the making, the new MEGA65 platform release v0.97 is now available. The MEGA65 team recommends that all owners upgrade to this version.&lt;/p&gt;
&lt;p&gt;Sign in to Filehost with your registered owner account, then download the release package appropriate for your mainboard version:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=a0276005-e71c-4b2d-8d17-2aa92e492c50&#34;&gt;MEGA65 platform v0.97 for R3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=5fddec06-abc1-46a8-8990-342c8d84e11f&#34;&gt;MEGA65 platform v0.97 for R6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Upgrade instructions are &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;in the latest User Guide&lt;/a&gt;. Remember to copy the SD card files to your SD card, including the &lt;code&gt;.M65&lt;/code&gt; system software files and the &lt;code&gt;MEGA65.ROM&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Also remember to install the core in slot 1, then also in slot 0. Upgrading slot 0 is easy if you previously upgraded slot 0 to v0.96: press &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;,&lt;/kbd&gt; (comma) from the core selection menu to start the process. If you have an older core in slot 0, you&amp;rsquo;ll need to start v0.97 from slot 1 then immediately press and hold &lt;kbd&gt;No Scroll&lt;/kbd&gt; to re-open the newer version of the core selection menu, then press &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;,&lt;/kbd&gt; and proceed.&lt;/p&gt;
&lt;p&gt;We reviewed &lt;a href=&#34;https://dansanderson.com/mega65/whats-new-v0-97/&#34;&gt;the changelogs&lt;/a&gt; back in the March Digest. Check out all the new stuff you&amp;rsquo;re getting.&lt;/p&gt;
&lt;h2 id=&#34;c64-core-v52-released&#34;&gt;C64 Core v5.2 released!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/c64_carts.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/character-study/c64_carts.jpg 1024w, https://dansanderson.com/mega65/character-study/c64_carts_hu_cae5f9e1b417972e.jpg 600w, https://dansanderson.com/mega65/character-study/c64_carts_hu_71ee05d9eb31e16a.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/character-study/c64_carts.jpg&#34;
        alt=&#34;Various C64 cartridges tested with the C64 core&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Various C64 cartridges tested with the C64 core.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;While you&amp;rsquo;re updating cores, be sure to pick up &lt;a href=&#34;https://files.mega65.org/html/main.php?id=896a012f-59e4-456c-b91f-7e989b958241&#34;&gt;C64 core v5.2&lt;/a&gt;. This maintenance release fixes several bugs, including the HDMI display bug that has blocked a minority of users with a set of vertical bars. It also adds support for COMAL 80, Simons BASIC, Waterloo Structured BASIC, Mikro Assembler, and BMP-Data Turbo 2000 as CRT files.&lt;/p&gt;
&lt;p&gt;Huge thanks to everyone testing and contributing fixes to the C64 core!&lt;/p&gt;
&lt;h2 id=&#34;m65connect-v24-released&#34;&gt;M65Connect v2.4 released!&lt;/h2&gt;
&lt;p&gt;M65Connect, the essential desktop companion app for the MEGA65, has an update also! Version 2.4 includes richer support for subdirectories, creating new D81 disk images, and many usability improvements. Whether you connect to your MEGA65 via Ethernet or JTAG adapter, or just move a microSD card between your MEGA65 and your PC, M65Connect is the easiest way to manage your files and perform other tasks.&lt;/p&gt;
&lt;p&gt;Starting with M65Connect v2.4, macOS no longer complains that the app is &amp;ldquo;corrupt,&amp;rdquo; thanks to a long-awaited bug fix in a library that the app uses. As with many open source apps, the macOS version is &amp;ldquo;unsigned,&amp;rdquo; and the first time you run it will be blocked by the operating system. In macOS Sequoia, open the app, dismiss the message with the &amp;ldquo;Done&amp;rdquo; button, then open the Privacy &amp;amp; Security panel in macOS settings and scroll down to find the button to give it permission to run (&amp;ldquo;Open Anyway&amp;rdquo;).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=d612d745-360e-4e86-8e15-14af525b6220&#34;&gt;M65Connect for Windows Intel&lt;/a&gt; or &lt;a href=&#34;https://files.mega65.org?id=1b849d0a-2ceb-44aa-beb4-a2cdfa51eb19&#34;&gt;Windows ARM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=5919a8b8-c23c-4616-9a52-37e077076638&#34;&gt;M65Connect for macOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=c1dbc7fe-89ad-4f1d-9e72-ad3f55cf02a1&#34;&gt;M65Connect for Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks as always to Tayger for this great tool.&lt;/p&gt;
&lt;h2 id=&#34;screenful-of-basic-compo-2025-results&#34;&gt;Screenful of BASIC Compo 2025 results!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/screenfulmenu.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/character-study/screenfulmenu.png 663w, https://dansanderson.com/mega65/character-study/screenfulmenu_hu_528466ff461e9a8a.png 600w, https://dansanderson.com/mega65/character-study/screenfulmenu_hu_ac1fa177eac103f4.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/character-study/screenfulmenu.png&#34;
        alt=&#34;Screenful of BASIC Compo 2025 compilation disk menu&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The Screenful of BASIC Compo 2025 compilation disk menu.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;From February to April, the &lt;a href=&#34;https://itch.io/jam/screenful-of-basic-2025&#34;&gt;Screenful of BASIC Compo 2025&lt;/a&gt; challenged us to write a game, demo, or tool using just an 80x25 screenful of BASIC 65 code. There were 26 fabulous entries.&lt;/p&gt;
&lt;p&gt;I put together &lt;a href=&#34;https://files.mega65.org/?id=979509a9-abc3-4b72-b6a2-c5fe357edb39&#34;&gt;a compilation disk&lt;/a&gt; with all of the entries and a browsable menu. Try them all!&lt;/p&gt;
&lt;p&gt;After a friendly round of voting, three winners came out on top:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Sokoban&lt;/em&gt; by johan&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Escape with Puppy&lt;/em&gt; by lochmana&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Dark Horse Tim&lt;/em&gt; by fredrikr&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Want to know more about compact BASIC coding techniques? Check out &lt;a href=&#34;https://youtu.be/TW17VbSQbEI?si=Jka6X_gDhcIsuvVC&#34;&gt;The 8 Bit Theory&amp;rsquo;s YouTube video&lt;/a&gt; explaining his Screenful Compo entry, &amp;ldquo;Screenful Crawler,&amp;rdquo; a 3D maze in just 16 lines.&lt;/p&gt;
&lt;p&gt;Several entries have already had updates and expanded versions published to &lt;a href=&#34;https://files.mega65.org/html/main.php&#34;&gt;Filehost&lt;/a&gt;, so be sure to check those out as well.&lt;/p&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;More amazing things recently uploaded to Filehost:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Two arcade cores from muse this month! &lt;a href=&#34;https://files.mega65.org?id=9c83c178-f55c-4ce2-8d0f-1aacd5ae70b4&#34;&gt;Rush&amp;rsquo;n Attack&lt;/a&gt; (1985) from Konami, and &lt;a href=&#34;https://files.mega65.org?id=4a864fa1-5d65-4dd9-a5ef-dd7ce07114e8&#34;&gt;Moon Patrol&lt;/a&gt; (1982) from Irem / Williams Electronics.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=76ab939c-f3c2-497a-9c4f-c18ade5195a9&#34;&gt;MEGAVOXL&lt;/a&gt; and &lt;a href=&#34;https://files.mega65.org?id=9c1af205-9d99-4a4e-8d24-c502528d24f7&#34;&gt;MEGAVOX2&lt;/a&gt;, two brilliant 3D voxel demos by Mirage.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=8c97a22b-0eea-49b4-8dd6-6574b7ef6ab7&#34;&gt;Tank Versus UFO&lt;/a&gt; by Zhedlas, a faithful port of the BASIC game from the VIC-20 user manual.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=278c69fc-1c76-4a62-93d4-bfdbc4080590&#34;&gt;FTL&lt;/a&gt; by SirGeldi, a brief starfield demo with music, in BASIC.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Don&amp;rsquo;t forget that you can follow the &lt;a href=&#34;https://tilde.zone/@mega65files&#34;&gt;MEGA65Files bot&lt;/a&gt; on Mastodon or your favorite federated social media service. The bot posts about both new files and updates to existing ones. If you don&amp;rsquo;t have a fediverse account, you can also follow the bot&amp;rsquo;s page in your RSS reader.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;why-character-graphics&#34;&gt;Why character graphics?&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/mega65_pixels.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/character-study/mega65_pixels.png 549w, https://dansanderson.com/mega65/character-study/mega65_pixels_hu_ee3e80eb856f08df.png 600w, https://dansanderson.com/mega65/character-study/mega65_pixels_hu_fc7e87affbedf7e7.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/character-study/mega65_pixels.png&#34;
        alt=&#34;Some pixels of the MEGA65 start-up banner&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Some pixels of the MEGA65 start-up banner.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When you first switch on your MEGA65, it shows a screen with a displayable area 640 pixels wide and 200 pixels tall, capable of displaying up to 4,096 possible colors. The MEGA65&amp;rsquo;s VIC-IV video chip determines the color of each pixel by reading graphics data from memory, and generates a video signal that draws the final image to the screen, many times per second.&lt;/p&gt;
&lt;p&gt;If we were designing a graphics system, how would we design the data that describes the image drawn to the screen? One possibility would be to store the color of each pixel. This screen is 640 x 200 = 128,000 pixels. With 4,096 possible colors, each pixel needs to be stored as 12 bits. 128,000 x 12 = 1,536,000 bits = 192,000 bytes, or 187.5 kilobytes. That&amp;rsquo;s a lot of memory to dedicate to graphics data. Even if we could find a place to put it in the MEGA65&amp;rsquo;s RAM, it would require substantial computational power to update this memory to draw or animate objects, or scroll a playfield.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/mega_in_pixels.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/character-study/mega_in_pixels.png&#34;
            width=&#34;572&#34;
            height=&#34;294&#34;
            alt=&#34;Pixels represented as 12-bit color values&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pixel graphics: 12 bits represent one pixel.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The most obvious way to reduce the memory demand of the graphics system is to reduce the quality of the image. Using a pixel resolution that&amp;rsquo;s 320 pixels wide instead of 640 cuts the needed memory by half. Reducing the number of possible colors to 256 (a &lt;em&gt;bit depth&lt;/em&gt; of 8) cuts it by a third. Naturally, these changes diminish the amount of graphics information we can display. Instead of 80 columns of text, we can only display 40 columns. A program that displays a photograph has to settle for less detail or less color accuracy. Space aliens are &lt;a href=&#34;https://en.wiktionary.org/wiki/chonky#English&#34;&gt;chonkier&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are other ways a graphics system can reduce its capabilities without making such obvious sacrifices in image quality—and this is where things get interesting. Many computer applications do not need the ability to set every pixel on the screen to any possible color at any time. By limiting the system&amp;rsquo;s capabilities to just what common applications need, a graphics system can use less memory to describe the full display, and still produce high quality images.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/mega_in_chars.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/character-study/mega_in_chars.png&#34;
            width=&#34;616&#34;
            height=&#34;194&#34;
            alt=&#34;A character graphics scheme&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Character graphics: 16 bits represent 64 pixels.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Character graphics are one such scheme. You probably already have a sense of how this works from typing letters, numbers, and symbols at the &lt;code&gt;READY.&lt;/code&gt; prompt. In the default text mode, each of these symbols — let&amp;rsquo;s call them &lt;em&gt;characters&lt;/em&gt; — is a small image, 8 pixels wide and 8 pixels tall. On our 640 x 200 pixel screen, 80 of these characters fit on a row, and 25 rows fill the screen. The graphics system knows what each character looks like from a &lt;em&gt;character set&lt;/em&gt; stored in memory, containing the images for each of 256 possible characters, including a blank character to represent empty space. By assigning each character a &lt;em&gt;screen code&lt;/em&gt; from 0 to 255, we can describe the entire screen in just 80 x 25 = 2,000 bytes of memory.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/petscii_mega65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/character-study/petscii_mega65.png 526w, https://dansanderson.com/mega65/character-study/petscii_mega65_hu_5f689750dd198f94.png 600w, https://dansanderson.com/mega65/character-study/petscii_mega65_hu_a44b9d15f657b993.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/character-study/petscii_mega65.png&#34;
        alt=&#34;The PETSCII uppercase character set&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The PETSCII uppercase character set.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This scheme uses a &lt;em&gt;monochromatic&lt;/em&gt; character set: each character cell is assigned a single foreground color, and the image in the character set describes which pixels should be set to this color. The graphics system uses another 2,000 bytes to describe attributes of each character cell, including five bits to set the foreground color. Each cell can use a different foreground color for its foreground pixels. All other pixels share a common background color for the entire screen, set in a VIC register.&lt;/p&gt;
&lt;p&gt;Of course, five color bits can only represent up to 32 colors, not 4,096. Just as the graphics system uses a character set of 256 character patterns, it also uses a &lt;em&gt;palette&lt;/em&gt; of 32 colors. Each palette entry is assigned a 12-bit color setting. The MEGA65 starts with a system character set of PETSCII symbols and a system palette of 32 pre-defined colors.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/palette.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/character-study/palette.png&#34;
            width=&#34;422&#34;
            height=&#34;316&#34;
            alt=&#34;The default MEGA65 system palette&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The default MEGA65 system palette.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This character graphics scheme uses very little memory compared to the 12-bit pixel scheme, and allows for much faster updates. In exchange, it trades away flexibility in what images can be represented. The entire screen &lt;em&gt;must&lt;/em&gt; consist of repeated patterns of 8 pixel x 8 pixel characters selected from a set of 256, only a single foreground color can be used for each character, and colors must be selected from a set of 32.&lt;/p&gt;
&lt;p&gt;This trade-off is obviously worth it for text applications, such as the BASIC screen editor, a word processor, or a BBS terminal program. Less obvious, at least at first, is that character graphics are also useful for graphical displays for some games. The default PETSCII character set includes glyphs that can serve as game graphics on their own, such as the heart, diamond, spade, and club for &lt;a href=&#34;https://dansanderson.itch.io/blackjack&#34;&gt;playing card suits&lt;/a&gt;. Some symbols are designed to be combined with others in adjacent cells to draw larger objects. Commodore programmers and artists have been exploiting the default character graphics mode for decades, with spectacular results.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/monstro.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/character-study/monstro.png 640w, https://dansanderson.com/mega65/character-study/monstro_hu_a157dae147bd25b3.png 600w, https://dansanderson.com/mega65/character-study/monstro_hu_8701141b5af34a83.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/character-study/monstro.png&#34;
        alt=&#34;Monstro Giganto, by The Pirates of Zanzibar&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Monstro Giganto, by The Pirates of Zanzibar.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;screen-memory&#34;&gt;Screen memory&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/screenmemory.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/character-study/screenmemory.png&#34;
            width=&#34;974&#34;
            height=&#34;517&#34;
            alt=&#34;Memory layout for an 80x25 screen, the first character in the upper left corner, organized by row&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Memory layout for an 80x25 screen (2,000 characters).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Both screen memory and color memory organize characters by row, starting in the top-left corner and going down the screen. For the default 80 x 25 text mode, each row is 80 bytes, so the first row left-to-right is represented by screen codes in positions 0 to 79, the second row is positions 80 to 159, and so on.&lt;/p&gt;
&lt;p&gt;You can tell the VIC-IV chip to use any address within the first 384 KB of memory as the start address of screen memory. This is a special feature! The Commodore 64&amp;rsquo;s VIC-II, in contrast, has restrictions on which memory can be used as screen memory. With the VIC-IV, the starting address for screen memory is stored as a 28-bit address, in a register called SCRNPTR at addresses $D060 to $D063.&lt;/p&gt;
&lt;p&gt;Here is a simple BASIC program that reads the SCRNPTR register to get the starting address of screen memory, then draws all 256 characters from the default character set in a nice rectangle:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SC=WPEEK($D060) + WPEEK($D062)*65536
20 FOR Y=0 TO 3
30 FOR X=0 TO 63
40 POKE SC+Y*80+X,Y*64+X
50 NEXT X
60 NEXT Y&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;WPEEK()&lt;/code&gt; is a special form of &lt;code&gt;PEEK()&lt;/code&gt; that reads two bytes of memory and interprets them as a 16-bit value stored in little endian order. Line 10 reads all four bytes, and assembles them into a 32-bit number, in this case the address stored in SCRNPTR.&lt;/p&gt;
&lt;p&gt;You can change the location of screen memory at any time by updating this register. This can be used for switching between multiple displays stored in different regions of memory, or for techniques such as screen scrolling.&lt;/p&gt;
&lt;p&gt;Try this. Set the SCRNPTR address to $6000:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;WPOKE $D060,$6000:WPOKE $D062,0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You are now looking at the contents of memory at address $6000, interpreted as screen codes by the VIC-IV chip, one byte per character. If you did this on Xemu, the screen is probably filled with &lt;code&gt;@&lt;/code&gt; symbols, which use a screen code of 0. On the MEGA65, this could be all manner of crazy characters, whatever happens to be in memory at that location.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/scr6000.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/character-study/scr6000.png 542w, https://dansanderson.com/mega65/character-study/scr6000_hu_85ef13c2422e8b6f.png 600w, https://dansanderson.com/mega65/character-study/scr6000_hu_8a0672d34ca13cca.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/character-study/scr6000.png&#34;
        alt=&#34;Memory at address $6000, interpreted as screen memory&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Memory at address $6000, interpreted as screen memory, in Xemu (left) and on the MEGA65 (right).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If you did this just after switching on the computer, you may also see that the characters in the top left corner have retained the colors of the rainbow bar of the welcome banner. The VIC keeps screen codes and color codes in separate areas of memory, and so far all you have done is tell the VIC to look somewhere else for screen codes.&lt;/p&gt;
&lt;p&gt;Another thing to notice: the screen editor&amp;rsquo;s &lt;code&gt;READY.&lt;/code&gt; prompt and cursor have followed you to the new screen location. It&amp;rsquo;s cool that this seems to work, but note that not every feature of the KERNAL, screen editor, and BASIC know how to do this. Some features of the KERNAL still believe screen memory is where it originally put it. Reset the screen editor, including its SCRNPTR, by holding &lt;kbd&gt;Run/Stop&lt;/kbd&gt; and tapping &lt;kbd&gt;Restore&lt;/kbd&gt;. Or just reset the computer.&lt;/p&gt;
&lt;h2 id=&#34;low-and-high-resolution-text-modes&#34;&gt;Low and high resolution text modes&lt;/h2&gt;
&lt;p&gt;The Commodore 64&amp;rsquo;s VIC-II is capable of text in 40 columns and 25 rows. This was extended for the Commodore 65&amp;rsquo;s VIC-III to also support 80 columns. The VIC-III can switch between these two modes. In fact, this is how &lt;code&gt;GO64&lt;/code&gt; mode works: it downshifts the VIC-III into its VIC-II compatibility mode, including adjusting the screen to 40 x 25 text mode.&lt;/p&gt;
&lt;p&gt;The 640-pixel wide 80-column text mode is controlled by the H640 register, bit 7 of address $D031. You can switch to 320-pixel wide 40-column text by clearing this bit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CLRBIT $D031,7&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Naturally, 40-column text uses less screen memory than 80-column text. It&amp;rsquo;s still using the same screen memory location of SCRNPTR, but only reading the first 1,000 bytes to describe the 40 x 25 screen. The memory layout is similar, organized by rows of 40 instead of 80.&lt;/p&gt;
&lt;p&gt;Once again, the KERNAL doesn&amp;rsquo;t know you have changed modes, and still thinks the display is 80 characters wide. Re-enable 80-column mode:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SETBIT $D031,7&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The MEGA65 VIC-IV can also double the vertical resolution from 200 pixels tall (25 rows) to 400 pixels (50 rows). This is controlled by the V400 register, bit 4 of $D031. Try enabling it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SETBIT $D031,3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&amp;rsquo;ve tried the screen editor&amp;rsquo;s 80 x 50 mode before, this might look familiar—except there&amp;rsquo;s a bunch of garbage on the bottom half of the screen. Also, if you try typing multiple lines, it scrolls at line 25. What&amp;rsquo;s going on?&lt;/p&gt;
&lt;p&gt;You guessed it: the KERNAL doesn&amp;rsquo;t know you enabled V400 mode in the video chip. The VIC-IV is now reading 4,000 bytes of screen memory starting at the screen editor&amp;rsquo;s internal location. This space is not meant to hold so many screen codes, and the KERNAL is using the latter 2,000 bytes for something else. Restore sanity by disabling V400 mode:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CLRBIT $D031,3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But wait, we know that the screen editor &lt;em&gt;does&lt;/em&gt; support an 80 x 50 mode. Press &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;5&lt;/kbd&gt; to enter this mode, and notice that the screen is nice and clean, and you can use the full space. How does this work?&lt;/p&gt;
&lt;p&gt;We can get a hint by inspecting the SCRNPTR register while this mode is active:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT HEX$(WPEEK($D060) + WPEEK($D062)*65536)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the address that it prints. Switch back to 80 x 25 mode (&lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;8&lt;/kbd&gt;) and enter the command again.&lt;/p&gt;
&lt;p&gt;The screen editor uses a different SCRNPTR address for 80 x 50 mode, switching to a location with more space to use as screen memory. It also keeps track of which mode you selected, so it knows how many rows and columns it should be using in this space. It does &lt;em&gt;not&lt;/em&gt; check the H640 and V400 registers in case some smart aleck changed them, so it is easily fooled if you don&amp;rsquo;t switch screen editor modes properly.&lt;/p&gt;
&lt;p&gt;Can the VIC-IV display text 40 columns wide and 50 rows tall? Only one way to find out.&lt;/p&gt;
&lt;h2 id=&#34;color-memory&#34;&gt;Color memory&lt;/h2&gt;
&lt;p&gt;Each character on the screen has a corresponding color code assigned to it. The code refers to a color defined in a palette. In the text modes we&amp;rsquo;ve seen so far, the assigned color becomes the foreground color for the character: referring to the character set images, the VIC draws an &amp;ldquo;on&amp;rdquo; pixel in the character&amp;rsquo;s color, and an &amp;ldquo;off&amp;rdquo; pixel in the background color.&lt;/p&gt;
&lt;p&gt;Programming color memory is a bit weird.&lt;/p&gt;
&lt;p&gt;The VIC-IV maintains a whopping 32 kilobytes of color memory from address $FF8.0000 to $FF8.7FFF. By default, color memory starts at the beginning of this range. The memory layout is the same as screen memory. An 80 x 25 text screen uses the first 2,000 bytes of this range for color data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT CHR$(147);&amp;#34;A&amp;#34;   : rem: Put an A in the corner

POKE $FF80000,4       : rem: Make it purple.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can adjust the starting address of color memory, but only within this range. The COLPTR register at $D064 to $D065 stores a 16-bit offset to the start of color memory. Think of it as the last four hexadecimal digits after &amp;ldquo;FF8.&amp;rdquo;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;WPOKE $D064,$07D0     : rem: Color memory starts at FF8.07D0

POKE $FF807D0,7       : rem: Make the A yellow.

WPOKE $D064,$0000     : rem: Color memory starts at FF8.0000.
                      : rem: A is purple again.&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;buffer-switching&#34;&gt;Buffer switching&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/memptrs.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/character-study/memptrs.png&#34;
            width=&#34;387&#34;
            height=&#34;396&#34;
            alt=&#34;Switching between two views&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Switching between two views.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Imagine a program that maintains two screens of 80 x 25 text. Such a program would determine two locations in memory for the 2,000 bytes of screen memory per screen, and set SCRNPTR to the starting address of the screen to be displayed. The program would also determine two locations in color memory for 2,000 bytes per screen, and set COLPTR to the current screen&amp;rsquo;s color data.&lt;/p&gt;
&lt;p&gt;By changing the VIC pointers, a program can make a big change to the display using very little CPU time. While the user is looking at one screen, the program draws the next screen in the other set of memory, then at the last millisecond, it changes the pointers. As soon as the pointers have changed, the VIC immediately starts drawing from the new screen data. From the user&amp;rsquo;s perspective, the screen switch is instantaneous, and they never see any of the computation that goes into updating screen and color memory.&lt;/p&gt;
&lt;p&gt;There is a teensy amount of time after updating SCRNPTR and before updating COLPTR, such that the VIC is drawing from the second screen&amp;rsquo;s screen codes and the first screen&amp;rsquo;s color codes. If this is a concern for your program, you can use &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/&#34;&gt;a VIC raster interrupt&lt;/a&gt; to make sure the switch happens while the VIC is drawing the top or bottom border. By the time the raster beam gets to drawing characters, both pointers are updated.&lt;/p&gt;
&lt;h2 id=&#34;color-memory-windows&#34;&gt;Color memory windows&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/character-study/colptr.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/character-study/colptr.png&#34;
            width=&#34;514&#34;
            height=&#34;300&#34;
            alt=&#34;Other ways to access the top of color memory, for VIC-II and VIC-III compatibility&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Other ways to access the top of color memory, for VIC-II and VIC-III compatibility.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Commodore 64 only supports a 40 x 25 character graphics screen, and so only ever needs 1,000 bytes of color memory. The VIC-II keeps these bytes among the I/O registers, at addresses $D800 to $DBFF (that&amp;rsquo;s dee-bee-eff-eff).&lt;/p&gt;
&lt;p&gt;The Commodore 65 introduced 80-column mode, requiring 2,000 bytes of color memory. To keep this data among the registers and stay compatible with the C64, the VIC-III has a one-bit register, CRAM2K, bit 0 of $D030, that switches the upper I/O registers to act as more color RAM, extending the range: $D800 to $DFFF.&lt;/p&gt;
&lt;p&gt;To make it possible to access all 2,000 bytes of color memory without hiding I/O registers, the C65 also exposes the same memory at $1F800 to $1FFFF. This is outside the first 64 KB of memory, so a program has to use the 4502&amp;rsquo;s indirect addressing modes to access it. (A program could also use the 4502&amp;rsquo;s MAP feature to associate 16-bit addresses with 28-bit addresses. Personally, I only use MAP for executing CPU instructions in upper memory, and use indirect addressing for data. You have to be careful with the MAP feature to not accidentally un-MAP your program while it is running.)&lt;/p&gt;
&lt;p&gt;The MEGA65 supports all of this. $D800 and $1F800 are the beginnings of two equivalent windows into the color memory starting at $FF8.0000. If the first 1,000 or 2,000 bytes of color memory are all you need, you can use these legacy methods, perhaps for the added convenience of $D800 being in the first bank. Remember that 80 x 50 text mode uses 4,000 bytes of color memory, which is more than these windows can see.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s one rather large caveat: these windows &lt;em&gt;always&lt;/em&gt; reflect the top of color memory at $FF8.0000, &lt;em&gt;not&lt;/em&gt; where COLPTR is pointing. If you set COLPTR to $0800, $D800 and $1F800 will continue to represent memory at $FF8.0000, and won&amp;rsquo;t be able to reach any of the memory that the VIC is using to paint color on the screen. The windows don&amp;rsquo;t move, which limits their usefulness.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re not using the windows, there&amp;rsquo;s a neat trick you can do here. By setting COLPTR to $0800, the windows point to memory that&amp;rsquo;s not being used, from $FF8.0000 to $FF8.07FF. With this setting, you can use the windows as regular memory for other purposes. (If you need to be really technical, this memory is slightly slower to access than other memory in banks 0 through 5, but your program might not notice.)&lt;/p&gt;
&lt;h2 id=&#34;color-and-character-attributes&#34;&gt;Color and character attributes&lt;/h2&gt;
&lt;p&gt;Each byte of color memory stores eight bits of information. I mentioned that five of these bits select the color, with the ability to select any of the first 32 colors in the palette. The remaining three bits apply interesting text effects to the character.&lt;/p&gt;
&lt;p&gt;The color bits are 0, 1, 2, 3, and 6. Another way to think of it is, bits 0 to 3 select one of 16 colors, and bit 6 selects either the first 16 colors (0 to 15) or the second 16 colors (16 to 31).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT CHR$(147);&amp;#34;A&amp;#34;      : rem: Put an A in the corner

POKE $FF80000,%00000100  : rem: purple (4)
POKE $FF80000,%00001111  : rem: light grey (15)
POKE $FF80000,%01000000  : rem: &amp;#34;guru meditation&amp;#34; red (16)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C65 documentation and the MEGA65 documentation describe bit 6 as &amp;ldquo;bold.&amp;rdquo; The idea is for a program to set colors 16 to 31 to be &amp;ldquo;bold&amp;rdquo; versions of colors 0 to 15, when such an effect is desired. Neither the C65 nor the MEGA65 have a boldface text effect, it&amp;rsquo;s just using a different set of colors.&lt;/p&gt;
&lt;p&gt;Bit 4 causes the character to blink in a steady pattern. With only this attribute set, the VIC alternates between two states: draw &amp;ldquo;on&amp;rdquo; pixels in the foreground color, or draw all pixels in the background color.&lt;/p&gt;
&lt;p&gt;Bit 5 reverses the character. With a monochrome character set, this means that &amp;ldquo;off&amp;rdquo; pixels are drawn in the character&amp;rsquo;s foreground color, and &amp;ldquo;on&amp;rdquo; pixels are drawn with the background color.&lt;/p&gt;
&lt;p&gt;Bit 7 underlines the character. The bottommost line is drawn with all &amp;ldquo;on&amp;rdquo; pixels, regardless of how the character appears in the character set.&lt;/p&gt;
&lt;p&gt;Things get a little dicey when you turn on more than one character attribute at a time. This was so confusing to me at first that I filed it as a bug years ago, and even submitted a &amp;ldquo;fix&amp;rdquo; to make it more intuitive. I eventually discovered that Commodore explicitly intended it this way, so I removed the &amp;ldquo;fix&amp;rdquo; in favor of &lt;a href=&#34;https://github.com/MEGA65/mega65-core/issues/884&#34;&gt;a backwards-compatible feature request&lt;/a&gt; that we have not yet implemented.&lt;/p&gt;
&lt;p&gt;For starters, &amp;ldquo;reverse&amp;rdquo; does not take effect if the &amp;ldquo;bold&amp;rdquo; palette is selected. There is no way to reverse a character and also set it to a color from 16 to 31.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Blink&amp;rdquo; has a different behavior if any other attribute is set. With no other attributes set, &amp;ldquo;blink&amp;rdquo; causes the foreground pixels to alternate on and off. With any other attribute set, including the &amp;ldquo;bold&amp;rdquo; attribute, &amp;ldquo;blink&amp;rdquo; causes the &lt;em&gt;attributes&lt;/em&gt; to blink on and off, and the character stays visible. Blink + underline: blink just the underline. Blink + reverse: alternate normal and reverse. Blink + bold: alternate between the two sets of colors.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a program that demonstrates every attribute combination and color:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 PRINT CHR$(147); :rem (Notice the semicolon.)
20 FOR Y=0 TO 15
30 PRINT &amp;#34;ABCDEFGHIJKLMNOP &amp;#34;;Y
40 FOR X=0 TO 15
50 POKE $1F800+Y*80+X,Y*16+X
60 NEXT X
70 NEXT Y&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don&amp;rsquo;t like how this makes certain combinations inaccessible, especially the ability to blink a character that&amp;rsquo;s using the &amp;ldquo;bold&amp;rdquo; color set between visible and invisible. But I eventually convinced myself that Commodore had good intentions, and if we want to add more control over the attribute behaviors, we need to preserve Commodore&amp;rsquo;s design as the default. At least it&amp;rsquo;s quirky.&lt;/p&gt;
&lt;p&gt;The blink + reverse effect resembles the blinking cursor of the screen editor. It&amp;rsquo;s interesting to notice that this is not actually how the blinking cursor works. Just as on the C64, the C65 default character set consists of 128 characters, followed by their reversed equivalents, for a total of 256 characters. The cursor blink is actually modifying the screen code, switching between the reversed and non-reversed variants of the character under the cursor. That seems like a waste considering there&amp;rsquo;s a blink + reverse mode that achieves a similar effect. The cursor could just set these attributes, and the default font could contain 128 more useful characters.&lt;/p&gt;
&lt;p&gt;Unfortunately, an attribute-based cursor would be constrained by the unusual way that attributes combine. If an attribute-based cursor were above a character using the &amp;ldquo;bold&amp;rdquo; palette, the cursor would try to set &amp;ldquo;bold&amp;rdquo; and &amp;ldquo;reverse,&amp;rdquo; which cancels the &amp;ldquo;reverse&amp;rdquo; effect. Earlier versions of the MEGA65 ROM attempted this, and we had to go back to the screen code-based cursor because users noticed that the cursor would vanish when using the upper 16 colors.&lt;/p&gt;
&lt;h2 id=&#34;a-look-ahead-video-modes&#34;&gt;A look ahead: video modes&lt;/h2&gt;
&lt;p&gt;In this Digest, we introduced the main idea behind character graphics: representing a screen as a coarse grid of characters, instead of a fine grid of pixels. Restricting the flexibility of the display to a common category of applications saves memory and compute time, an essential resource on microcomputers. We saw how the default text mode of the MEGA65 displays a grid of 80 x 25 characters, selected from a set of 256 characters, each displayed in one of 32 colors. Programs can manage display memory using pointer registers. We also took a brief look at how the text display can be switched between two horizontal resolutions (320 pixels or 640 pixels) and two vertical resolutions (200 pixels or 400 pixels), each combination fitting a different number of characters on the screen.&lt;/p&gt;
&lt;p&gt;Vintage video systems typically support multiple video modes to give programs the opportunity to choose their own tradeoffs of capabilities and costs. Over several Digest articles this year, we&amp;rsquo;ll explore more features of the MEGA65&amp;rsquo;s character graphics system. We&amp;rsquo;ll see that many of these features involve switching modes that adjust specifications and change the way screen and color memory are interpreted by the VIC.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Next month, we&amp;rsquo;ll dive deeper into character sets and color palettes, both of which can be completely customized by a program. We&amp;rsquo;ve visited custom character sets a few times in previous Digest issues, and it&amp;rsquo;s about time we lay all the cards out on the table. We&amp;rsquo;ll also play around with some multi-color character graphics modes from the VIC-II and VIC-III, and work our way up to the crown jewel of MEGA65 VIC-IV character graphics, Super Extended Attribute Mode.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re as excited about this series as I am, please consider supporting this Digest. Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn/&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So much to do, so little time! See you next month.&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/character-study/M65Digest_2025May.mp3" length="" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1952</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/character-study/charattrs.png"/>
      
    </item>
    
    <item>
      <title>MEGA65: The First Ten Years</title>
      <link>https://dansanderson.com/mega65/first-ten-years/</link>
      <pubDate>Tue, 15 Apr 2025 00:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/first-ten-years/</guid>
      <description>&lt;p&gt;MEGA65: The First Ten Years. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for April 2025.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;MEGA65: The First Ten Years. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for April 2025.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/first-ten-years/M65Digest_2025Apr.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/M65Digest_2025Apr.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
MEGA65: The First Ten Years.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/mega65_globe.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/mega65_globe.jpg 791w, https://dansanderson.com/mega65/first-ten-years/mega65_globe_hu_89abb5cca7d97c93.jpg 600w, https://dansanderson.com/mega65/first-ten-years/mega65_globe_hu_268b2b52395d9b71.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/mega65_globe.jpg&#34;
        alt=&#34;MEGAVOXL, by MirageBD&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGAVOXL, by MirageBD
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Ten years ago, Paul Gardner-Stephen and the Museum of Electronic Games and Art &lt;a href=&#34;https://www.m-e-g-a.org/mega65-introduction/&#34;&gt;announced a joint effort to recreate the Commodore 65&lt;/a&gt;. The MEGA65 would be an open-hardware open-source product, based on the original Commodore designs and prototypes, manufactured in Germany and sold worldwide. Instead of fading into obscurity as a historical footnote, the Commodore 65 would achieve new potential as a modern day platform for recreational computing, a revival both familiar and new to thousands of people looking for a way to reconnect with the creativity, stimulation, comfort, and digital sovereignty of the 8-bit era.&lt;/p&gt;
&lt;p&gt;In this special edition of the Digest, we&amp;rsquo;ll review the first ten years of the MEGA65 project through published media, articles, videos, and conference talks. Take your time to click through the links below and experience the project through the eyes of the people that built it and the community around it.&lt;/p&gt;
&lt;p&gt;We also have some exciting announcements to celebrate the anniversary! Don&amp;rsquo;t miss this one!&lt;/p&gt;
&lt;h2 id=&#34;the-great-mega65-egg-hunt-begins&#34;&gt;The Great MEGA65 Egg Hunt begins&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/m65prototype.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/m65prototype.jpg 1000w, https://dansanderson.com/mega65/first-ten-years/m65prototype_hu_2deb6e3fcf8c18b8.jpg 600w, https://dansanderson.com/mega65/first-ten-years/m65prototype_hu_8e82e2ecb8a92ce8.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/m65prototype.jpg&#34;
        alt=&#34;The original MEGA65 prototype&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
This one-of-a-kind original MEGA65 prototype can be yours!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Breaking news from Detlef &amp;ldquo;deft&amp;rdquo; Hastik:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Having used citations and celebrated events from the history of computer nerds, and being fans of the book (not the movie!) Ready Player One, we have hidden an &lt;a href=&#34;https://en.wikipedia.org/wiki/Easter_egg_(media)&#34;&gt;Easter egg&lt;/a&gt; in &lt;em&gt;every&lt;/em&gt; MEGA65! The first person to find it will win an insane piece of MEGA65 history: the very first working and beautifully shaped &lt;a href=&#34;https://www.m-e-g-a.org/mega65-first-prototype/&#34;&gt;&lt;strong&gt;MEGA65 prototype&lt;/strong&gt;&lt;/a&gt;, shown in 2015 at AMIGA 30 in Neuss/Germany, six months after the project was officially announced by Paul Gardner-Stephen (AU) and Detlef Hastik (DE). This unicorn computer has an insurance value of over 15K USD, is signed by &lt;a href=&#34;https://en.wikipedia.org/wiki/Dave_Haynie&#34;&gt;Dave Haynie&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/RJ_Mical&#34;&gt;RJ Mical&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/Chris_Huelsbeck&#34;&gt;Chris Hülsbeck&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/Dino_Dini&#34;&gt;Dino Dini&lt;/a&gt; and other famous people, sports an unprinted (!) original C65 keyboard inside an SLS fabricated C65 case (yes, it&amp;rsquo;s made with lasers!) and - it also works!&lt;/p&gt;
&lt;p&gt;Prepare for an unforgiving hunt through the depths of the MEGA65, through time, and of course, through space! There can be only one person to enter the nerd throne and win this nerd&amp;rsquo;s dream machine. Will it take days, weeks, months - or even years to solve the mind bending puzzles left by the creators and not discovered for years? Will you be the one to earn the crown?&lt;/p&gt;
&lt;p&gt;Friends (and friends of friends) of the MEGA65 core team are not allowed to participate. Be prepared to be questioned. A time stamp will decide who the lucky winner is in case several people find the egg. It is allowed to build clans and search in groups :)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&amp;rsquo;s right, this one-of-a-kind piece of MEGA65 history can be yours—if you know where to look! This multi-step trail has been under our noses for years and has not yet been discovered independently. Best of luck to everyone!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/rjmical.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/rjmical.png 938w, https://dansanderson.com/mega65/first-ten-years/rjmical_hu_3ccfeb99118d5648.png 600w, https://dansanderson.com/mega65/first-ten-years/rjmical_hu_eb49d948dbbcea8a.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/rjmical.png&#34;
        alt=&#34;RJ Mical admiring the MEGA65 prototype, at AMIGA 30 in Neuss/Germany, 2015.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
RJ Mical admiring the MEGA65 prototype, at AMIGA 30 in Neuss/Germany, October 2015.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;intro-disk-4&#34;&gt;Intro Disk #4&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/id4.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/id4.png 936w, https://dansanderson.com/mega65/first-ten-years/id4_hu_22cd587effe262e1.png 600w, https://dansanderson.com/mega65/first-ten-years/id4_hu_870d1bf22fab70.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/id4.png&#34;
        alt=&#34;Intro Disk #4&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Intro Disk #4
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Every MEGA65 comes bundled with a large collection of software produced by the community, browsable by a menu that opens automatically when you first turn on the computer. The Intro Disk collection has added more titles each year since the MEGA65&amp;rsquo;s debut in 2022, and it&amp;rsquo;s time to expand it again!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=all-intros-public&#34;&gt;Intro Disk #4 is now available for download&lt;/a&gt;. MEGA65 owners, sign in to Filehost and use &lt;a href=&#34;https://files.mega65.org?id=all-intros&#34;&gt;this link&lt;/a&gt; for a version with extra licensed content. The new archive has an all-new menu system by MirageBD with music by Hein, and adds 72 new titles and dozens of articles about projects you can download and install. This brings the total size of the Intro Disk collection to 264 games, demos, and tools.&lt;/p&gt;
&lt;p&gt;The entire collection has been revised and tested with the upcoming v0.97 release core, ROM, and system software. ID4 should work with release v0.96, but if you notice issues, I recommend installing the test version of the upcoming release (as discussed in &lt;a href=&#34;https://dansanderson.com/mega65/whats-new-v0-97/&#34;&gt;last month&amp;rsquo;s Digest&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Huge thanks to Gurce, who has spearheaded the Intro Disk project from the very beginning. Thanks to his efforts curating, building, and testing the collection, everyone can experience what the MEGA65 has to offer, right out of the box.&lt;/p&gt;
&lt;h2 id=&#34;screenful-of-basic-compo-last-call&#34;&gt;Screenful of BASIC Compo, last call!&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;ve been waiting until the last minute to enter the Screenful of BASIC Compo, congratulations! It is now the last minute! &lt;a href=&#34;https://itch.io/jam/screenful-of-basic-2025&#34;&gt;The itch.io game jam page&lt;/a&gt; will accept entries until 11:59 pm GMT, April 22, 2025.&lt;/p&gt;
&lt;p&gt;After the deadline, all entries will be revealed for download, and a friendly round of voting will begin. Try out all the entries for yourself, cheer on your fellow competitors in the comments, and boost your favorites.&lt;/p&gt;
&lt;p&gt;If you have any last minute questions or technical issues with your entry, be sure to ask in &lt;a href=&#34;https://discord.com/invite/5DNvESf&#34;&gt;the Discord&lt;/a&gt; or &lt;a href=&#34;https://www.forum64.de/index.php?thread/153945-2025-compo-screenful-of-basic/&#34;&gt;the Forum64.de thread&lt;/a&gt;. Go go go!&lt;/p&gt;
&lt;h2 id=&#34;more-from-deft&#34;&gt;More from deft!&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Another note from deft:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But what’s this? Something stirs behind the curtain - quiet talks, shifting shapes, and a name long thought dormant may soon rise to breathe new life into an extraordinary machine. Could something we all hold dear be wearing new clothes in the future? Those threads are being woven in fractures between past and present, by hands both trusted and unexpected. Something is cooking. What’s on the menu? Nothing is confirmed. Everything is possible. Watch this space.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;commodore-the-final-years&#34;&gt;Commodore: The Final Years&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/vcfmw_c65_4.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/vcfmw_c65_4.jpeg 640w, https://dansanderson.com/mega65/first-ten-years/vcfmw_c65_4_hu_ddde43a2f49088d8.jpeg 600w, https://dansanderson.com/mega65/first-ten-years/vcfmw_c65_4_hu_da3a6081e5ba568b.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/vcfmw_c65_4.jpeg&#34;
        alt=&#34;The Commodore 65, developer unit #23, rev 2A mainboard&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Commodore 65, developer unit #23, rev 2A mainboard. Owned by Jim Brain, photographed at Vintage Computer Festival Midwest 2024, next to MEGA65 materials.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;At the &lt;a href=&#34;https://en.wikipedia.org/wiki/CES_(trade_show)&#34;&gt;Consumer Electronics Show&lt;/a&gt; of 1985 in Las Vegas, Nevada, Commodore Business Machines announced two new computers: the Commodore 128 and the Commodore LCD. The C128 went on to sell 2.5 million units over the next four years. The CLCD was cancelled before it was released.&lt;/p&gt;
&lt;p&gt;That same year, Commodore began developing the 4502 CPU, later rebranded as the &lt;a href=&#34;https://en.wikipedia.org/wiki/CSG_65CE02&#34;&gt;CSG 65CE02&lt;/a&gt;. Originally intended as a more efficient &lt;a href=&#34;https://en.wikipedia.org/wiki/CMOS&#34;&gt;CMOS&lt;/a&gt; version of the &lt;a href=&#34;https://en.wikipedia.org/wiki/MOS_Technology_6502&#34;&gt;6502&lt;/a&gt;, the final design of the 4502 was faster and more featureful, compatible with the documented 6502 instruction set, with new instructions and enhancements for making use of more memory. The new chip would be a drop-in replacement for the 6502, at least in some applications.&lt;/p&gt;
&lt;p&gt;Chip designer Bill Gardei conceived of a new home computer using the new CPU, an 8-bit successor to the C64 and C128 that would eventually be known as the &lt;a href=&#34;https://en.wikipedia.org/wiki/Commodore_65&#34;&gt;Commodore 65&lt;/a&gt;. The C65 would feature the 4502 (packaged with other components as the &amp;ldquo;4510&amp;rdquo;), along with an enhanced VIC-III (4567) graphics chip to follow the VIC-II from the C64 and C128. Like the C128, the C65 would run existing C64 software and support most C64 peripherals. And the faster CPU, improved graphics, and target price would beat the new home game console everyone was talking about: the Nintendo Entertainment System.&lt;/p&gt;
&lt;p&gt;By 1989, Commodore needed the C65 to fill out the low end of its home computer line, something that would capitalize on the popularity of the seven-year-old C64, and be less expensive than the &lt;a href=&#34;https://en.wikipedia.org/wiki/Amiga_500&#34;&gt;Amiga 500&lt;/a&gt; (1987). Three people were tasked with delivering the new system in time for the 1989 holiday season. Gardei continued to work on the chipset. Fred Bowen developed the KERNAL ROM and BASIC 10 language, emboldened by a luxurious 256 KB of ROM space and a budget to hire contractors. Paul Lassa designed the motherboard and hardware layout. Despite the team&amp;rsquo;s best efforts, hopes for a 1989 release of the C65 were dashed by issues with the test chips coming back from the Commodore Semiconductor Group. Only a few prototype systems had been assembled by August 1989, and many bugs remained.&lt;/p&gt;
&lt;p&gt;The delays gave Lassa an opportunity to work on a new feature: a &lt;a href=&#34;https://en.wikipedia.org/wiki/Direct_memory_access&#34;&gt;DMA&lt;/a&gt; chip capable of copying large regions of memory at high speed. Lassa even managed to sneak in Amiga-like features for drawing large graphical objects using the chip. Gardei and others worked on improving the 4502&amp;rsquo;s compatibility with C64 software, made difficult by efficiency improvements that caused legacy programs to run with incorrect timing. By the time chip designs stabilized, 1990 had come and gone.&lt;/p&gt;
&lt;p&gt;While there was still some residual momentum within Commodore to launch the C65 in 1991, North American sales teams were no longer interested, and work had already begun on a low-cost Amiga that would be released as the &lt;a href=&#34;https://en.wikipedia.org/wiki/Amiga_600&#34;&gt;Amiga 600&lt;/a&gt; the following year. Commodore leadership de-staffed the already under-staffed teams, and the C65 project was cancelled. In the throes of financial difficulty, Commodore began selling off the contents of its warehouses in 1993, including an unknown number of C65 prototypes, estimated to be fewer than 200. By mid-1994, Commodore was out of business.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/Commodore-Final-Years-Brian-Bagnall/dp/0994031033&#34;&gt;Commodore: The Final Years&lt;/a&gt; by Brian Bagnall.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.zimmers.net/cbmpics/cbm/c65/c65faq20.txt&#34;&gt;Commodore C65/C64DX information file #2&lt;/a&gt;, including Fred Bowen&amp;rsquo;s post to comp.sys.cbm dated September 17, 1993, &amp;ldquo;What&amp;rsquo;s a C-65???&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=foMwhcJjmcQ&#34;&gt;Commodore 128 TV commercial&lt;/a&gt; (1985)&lt;/li&gt;
&lt;li&gt;Consumer Electronics Show 1985 video compilation: &lt;a href=&#34;https://www.youtube.com/watch?v=LTeo8i6mQbk&#34;&gt;part 1&lt;/a&gt;, Sony; &lt;a href=&#34;https://www.youtube.com/watch?v=3a16acoLGhA&#34;&gt;part 2&lt;/a&gt; featuring the Atari 130XE (6502 CPU, 128 KB)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://obligement.free.fr/articles_traduction/winter_ces_1985_en.php&#34;&gt;Text of CES 1985 report from Compute!&amp;rsquo;s Gazette, April 1985&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://cbmsteve.ca/c65cc/index.html&#34;&gt;Prototype of a C65 &amp;ldquo;classroom computer,&amp;rdquo;&lt;/a&gt; a version of the C65 without the built-in floppy drive, owned by Fred Bowen&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;pauls-commodore-65&#34;&gt;Paul&amp;rsquo;s Commodore 65&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/pauls_c65_2014.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/pauls_c65_2014.png 999w, https://dansanderson.com/mega65/first-ten-years/pauls_c65_2014_hu_65ca802cb34dfa28.png 600w, https://dansanderson.com/mega65/first-ten-years/pauls_c65_2014_hu_db2944dfa91b374a.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/pauls_c65_2014.png&#34;
        alt=&#34;Paul&amp;amp;#39;s Commodore 65, March 2010&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Paul&#39;s Commodore 65, March 2010
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Commodore 65 prototypes drifted among dealers and enthusiasts, mostly as curiosities, considering there was no software written for the unreleased platform. On the outside, the prototypes looked nearly finished, with the familiar wedge-style case, keyboard, and built-in floppy drive. Inside, the prototypes varied, with inconsistent versions of the mainboard and chips. The KERNAL ROM was incomplete, no meaningful software existed other than a few simple in-house demos, and no documentation was publicly available at the time.&lt;/p&gt;
&lt;p&gt;One C65 prototype made it into the hands of engineer Paul Gardner-Stephen. Despite the lack of commercial software, Paul made regular use of the machine, learning what he could through experimentation and writing his own programs. Over the next sixteen years, the historical value of the prototype machine eventually exceeded Paul&amp;rsquo;s ability to care for it, and he sold it to a collector in the year 2010.&lt;/p&gt;
&lt;p&gt;For the lucky few that owned them, the C65 was a glimpse into an alternate history with one more generation of 8-bit home computers. Paul conceived of a new 8-bit based on his experience with the C65. By 2010, FPGA technology had become fast enough and inexpensive enough for a single person to develop such a computer, without the large scale chip fabrication facilities used by Commodore developers to iterate on the original designs.&lt;/p&gt;
&lt;p&gt;His C65 now in other hands, Paul started work on the &amp;ldquo;C65GS,&amp;rdquo; a new computer with the same spirit as the C65 and some degree of backwards compatibility. Paul originally expected the project to take the form of an &amp;ldquo;accelerator&amp;rdquo; board that would connect to vintage Commodore 64 hardware. The C65GS would be built using an off-the-shelf FPGA development kit, so early stages of the project could proceed without fabricating any parts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;March 12, 2010: &lt;a href=&#34;https://www.youtube.com/watch?v=RgmC8XqJLho&#34;&gt;Paul tours his Commodore 65&lt;/a&gt;. Paul had to sell his C65 shortly after this video was made.&lt;/li&gt;
&lt;li&gt;January 24, 2014: &lt;a href=&#34;https://c65gs.blogspot.com/2014/01/some-screen-shots.html&#34;&gt;Paul starts a developer blog&lt;/a&gt; for the &amp;ldquo;C65GS&amp;rdquo; project, an 8-bit computer inspired by the C65.&lt;/li&gt;
&lt;li&gt;January 31, 2014: Paul explains &lt;a href=&#34;https://c65gs.blogspot.com/2014/01/motivations-and-goals-for-project.html&#34;&gt;motivations and goals for the project&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;March 25, 2015: &lt;a href=&#34;https://www.youtube.com/watch?v=9HHFi8cagyg&#34;&gt;Paul types &amp;ldquo;Hello World&amp;rdquo;&lt;/a&gt; on the C65GS core running the C65 ROM, on the Nexys 4 development board for the Artix 7 FPGA.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;paul-joins-mega&#34;&gt;Paul joins MEGA&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/mega65_2015.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/mega65_2015.jpg 1920w, https://dansanderson.com/mega65/first-ten-years/mega65_2015_hu_178814a6efcede79.jpg 600w, https://dansanderson.com/mega65/first-ten-years/mega65_2015_hu_ada80ab5f94430d5.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/mega65_2015.jpg&#34;
        alt=&#34;MEGA demo, April 2015&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGA demo, April 2015
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://www.m-e-g-a.org/&#34;&gt;The Museum of Electronic Games &amp;amp; Art&lt;/a&gt; (MEGA), a German non-profit organization dedicated to computer engineering education, creativity, and preservation, already had some experience recreating vintage computer history by the time they heard of Paul&amp;rsquo;s project. In 2011, MEGA members recreated &lt;a href=&#34;https://www.m-e-g-a.org/research-education/research/t42-tennis-for-two/&#34;&gt;Tennis for Two&lt;/a&gt; (1958), the early video game milestone played on an oscilloscope. In 2013, MEGA debuted their recreation of the &lt;a href=&#34;https://www.m-e-g-a.org/research-education/research/adventure-vision/&#34;&gt;ENTEX Adventure Vision&lt;/a&gt; (1982) with its unique spinning mirror display. These projects produced research documentation, emulators, tools, and prototypes that would join MEGA&amp;rsquo;s traveling exhibits that also included preserved hardware and modern demo software.&lt;/p&gt;
&lt;p&gt;MEGA was exploring a potential project based on the Commodore 65 when they discovered Paul&amp;rsquo;s C65GS developer blog. MEGA and Paul joined forces in 2014, and &lt;a href=&#34;https://c65gs.blogspot.com/2015/04/introducing-mega65-retro-computer.html&#34;&gt;relaunched the project in April 2015 as the MEGA65&lt;/a&gt;. The new computer would put Paul&amp;rsquo;s FPGA-based design into historically accurate reproductions of the Commodore 65 case with keyboard and built-in 3-1/2&amp;quot; floppy drive, as well as modern conveniences such as digital video output and Ethernet connectivity.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;April 22, 2015: Paul partners with the Museum of Electronic Games &amp;amp; Art (MEGA). &lt;a href=&#34;https://www.m-e-g-a.org/mega65-introduction/&#34;&gt;MEGA announces the MEGA65 project&lt;/a&gt;, and &lt;a href=&#34;https://c65gs.blogspot.com/2015/04/introducing-mega65-retro-computer.html&#34;&gt;Paul discusses it on the dev blog&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;September 13, 2015: &lt;a href=&#34;https://www.youtube.com/watch?v=B1I5908ZH8M&#34;&gt;MEGA65 playing some demos and games&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;October 13, 2015: AMIGA 30 in Neuss, Germany: &lt;a href=&#34;https://www.youtube.com/watch?v=nCyBoulxdj8&#34;&gt;Interview with Detlef Hastik&lt;/a&gt; [German language], with the MEGA65 FPGA board mounted in a C64C case.&lt;/li&gt;
&lt;li&gt;October 15, 2015: AMIGA 30: &lt;a href=&#34;https://www.youtube.com/watch?v=MKNrWI-DPQ8&#34;&gt;deft presents the MEGA65&lt;/a&gt; [German language].&lt;/li&gt;
&lt;li&gt;November 27, 2015: Paul &lt;a href=&#34;https://www.youtube.com/watch?v=2H2mh8wLXco&#34;&gt;presents an early MEGA65 in a C64C case&lt;/a&gt;: &amp;ldquo;Using Understandable Computers to Make Computers Understandable,&amp;rdquo; at Flinders University.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;keyboard-cases-and-community&#34;&gt;Keyboard cases and community&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/mega65_prototype_2016.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/mega65_prototype_2016.jpg 1920w, https://dansanderson.com/mega65/first-ten-years/mega65_prototype_2016_hu_d0328acfbd27746d.jpg 600w, https://dansanderson.com/mega65/first-ten-years/mega65_prototype_2016_hu_93eba322a0373c58.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/mega65_prototype_2016.jpg&#34;
        alt=&#34;The second MEGA65 prototype, January 2016&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The second MEGA65 prototype, January 2016
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;MEGA made steady progress on the keyboard case, exhibiting generations of prototypes in 2015 and 2016. The earliest prototypes were already measurement-exact reproductions of the C65 case and keyboard. Meanwhile, FPGA development was well under way. Paul and Detlef established the project with open source and open hardware licenses, and began the process of building a community of volunteer developers and testers. Paul published regular updates to his developer blog. As part of his work as a researcher and lecturer at &lt;a href=&#34;https://www.flinders.edu.au/people/paul.gardner-stephen&#34;&gt;Flinders University&lt;/a&gt; in Australia, Paul used the MEGA65 as a learning platform for his students. MEGA began promoting the project to solicit developer interest, and to stoke the imagination of the vintage computing community.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;January 22, 2016: MEGA shares photos of &lt;a href=&#34;https://www.m-e-g-a.org/mega-65-second-prototype/&#34;&gt;the second prototype&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;February 17, 2016: The podcast &lt;a href=&#34;https://sceneworld.org/blog/2016/02/17/podcast-episode-20-the-mega65-project/&#34;&gt;Scene World&lt;/a&gt; interviews Paul Gardner-Stephen, Andre Kudra, and Detlef Hastik.&lt;/li&gt;
&lt;li&gt;April 2016: &lt;a href=&#34;https://www.youtube.com/watch?v=9gJb7eG3wG8&#34;&gt;Retrobörse interview with deft&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;August 2016: LGB begins work on a MEGA65 target for his &lt;a href=&#34;https://github.com/lgblgblgb/xemu&#34;&gt;Xemu emulator suite&lt;/a&gt;, based on previous work on a C65 emulator. Xemu would track MEGA65 development to the present day.&lt;/li&gt;
&lt;li&gt;August 14, 2016: &lt;a href=&#34;https://www.youtube.com/watch?v=2VT8yB3odhg&#34;&gt;Gurce presents an early version of the m65dbg debugging tool&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;January 26, 2018: &lt;a href=&#34;https://www.youtube.com/watch?v=o3G7pLJM128&#34;&gt;VIC-IV multi-color multiplexed hardware sprite demo&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;megaphone-the-big-picture&#34;&gt;MEGAPhone: the big picture&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/megaphone_2019.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/megaphone_2019.jpg 1600w, https://dansanderson.com/mega65/first-ten-years/megaphone_2019_hu_8ac39f87ebf2d60.jpg 600w, https://dansanderson.com/mega65/first-ten-years/megaphone_2019_hu_56b47b0565723846.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/megaphone_2019.jpg&#34;
        alt=&#34;MEGAPhone prototype, June 2019&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGAPhone prototype, June 2019
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s easy to assume that the warm feelings we have for personal computers from our childhoods are purely nostalgia. Perhaps we only feel this way about these piles of junk because we grew up with them. But most people I know in this hobby cite another reason for the attraction: simplicity. Modern computing is built upon huge stacks of software. The lowest layers wrangle the unfathomable complexity of electrons coursing through switching circuits, and upper layers make the computer easier to program and easier to use. Over time, the depth and complexity of these layers have grown to alienate a computer&amp;rsquo;s owner from its power, ceding control of our data-driven personhood to software and service companies. Even when this exchange has obvious benefits—you didn&amp;rsquo;t have to code that web browsing program to use it—we get the creeping sense that our modern computers aren&amp;rsquo;t entirely &lt;em&gt;ours.&lt;/em&gt; The technological centerpieces of our lives are merely rented, not owned, and don&amp;rsquo;t always act in our best interests.&lt;/p&gt;
&lt;p&gt;In contrast, vintage computers are knowable, stable, comfortable. They do what you tell them to, and don&amp;rsquo;t do anything else. There are no background processes, there&amp;rsquo;s no unsolicited network activity, there are no operating system updates being installed remotely by the manufacturer, and there&amp;rsquo;s no user telemetry data being sent out to who knows where by something you didn&amp;rsquo;t know you installed years ago. It doesn&amp;rsquo;t take rose-tinted glasses to see this has some benefit over modern commercially-available computing products, something valuable that we may have lost.&lt;/p&gt;
&lt;p&gt;Could modern-day personal computing learn from its ancestry? Could we restore the powers and freedoms we once had without sacrificing utility, or are the tradeoffs we&amp;rsquo;ve made for modern conveniences inevitable? Could the implicit principles of early personal computing be applied intentionally to the design of a modern computer? To a smartphone?&lt;/p&gt;
&lt;p&gt;The MEGAPhone attempts to answer to that question. Funded by &lt;a href=&#34;https://nlnet.nl/project/Mega65/&#34;&gt;grants from the NLnet Foundation&lt;/a&gt;, MEGAPhone is the modern smartphone reimagined through the lens of the MEGA65 and Commodore 8-bit computers. It&amp;rsquo;s literally the same platform, running the MEGA65 FPGA core and ROM on portable hardware, extended with discrete mobile communication components. The &amp;ldquo;apps&amp;rdquo; are just programs, and you can write your own phone apps in BASIC 65 or machine code. The MEGAPhone architecture takes personal security and privacy to its strongest useful conclusion, mobile computing not beholden to a single manufacturer or provider, accessible and extensible by its user.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;October 26, 2018: &lt;a href=&#34;https://c65gs.blogspot.com/2018/10/taking-big-picture-view.html&#34;&gt;Paul gives a status update&lt;/a&gt;, &amp;ldquo;Taking the big picture view.&amp;rdquo; Paul introduces the MEGAPhone, a secondary project to create a portable MEGA65 with a cellular modem and voice capabilities, as a research platform for students.&lt;/li&gt;
&lt;li&gt;November 13, 2018: &lt;a href=&#34;https://www.youtube.com/watch?v=wwAfD9FrmZo&#34;&gt;Paul demos variable-width fonts&lt;/a&gt; in homemade presentation software.&lt;/li&gt;
&lt;li&gt;January 23, 2019: &lt;a href=&#34;https://www.youtube.com/watch?v=KuNB4ocZDXA&#34;&gt;Paul presents the MEGAPhone&lt;/a&gt; at Linux Conf AU 2019.&lt;/li&gt;
&lt;li&gt;March 2, 2019: Paul gives &lt;a href=&#34;https://www.youtube.com/watch?v=2fi1fsKtfxc&#34;&gt;a status update from Australia&lt;/a&gt; [German and English].&lt;/li&gt;
&lt;li&gt;June 5, 2019: Paul shares photos of &lt;a href=&#34;https://c65gs.blogspot.com/2019/06/megaphone-prototype-is-taking-shape.html&#34;&gt;an early MEGAphone prototype&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;pre-series-case-molds-and-devkits&#34;&gt;Pre-series, case molds, and DevKits&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/preseries_2019.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/preseries_2019.png 1009w, https://dansanderson.com/mega65/first-ten-years/preseries_2019_hu_f29a658151d92e5b.png 600w, https://dansanderson.com/mega65/first-ten-years/preseries_2019_hu_28d9e575afff4647.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/preseries_2019.png&#34;
        alt=&#34;Pre-series MEGA65 units, September 2019&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pre-series MEGA65 units, September 2019
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 hit another milestone towards wide distribution with the &amp;ldquo;pre-series&amp;rdquo; prototypes in 2019, a short run of complete units with early revision (R2) mainboards. These were sold privately to team members to raise money for the next phase of the project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;July 1, 2019: &lt;a href=&#34;https://www.youtube.com/watch?v=aEhZfkQ3bAk&#34;&gt;MEGA65 introduction of pre-series hardware&lt;/a&gt;. A total of 20 were made.&lt;/li&gt;
&lt;li&gt;September 18, 2019: &lt;a href=&#34;https://www.youtube.com/watch?v=OtMVfjACTJY&#34;&gt;Twelve pre-series MEGA65s&lt;/a&gt; with bonus random animal noises.&lt;/li&gt;
&lt;li&gt;November 1, 2019: &lt;a href=&#34;https://www.youtube.com/watch?v=bK04hl8OKto&#34;&gt;GeoWrite 128 and GeoPaint 128 running on the MEGA65&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;November 3, 2019: &lt;a href=&#34;https://www.youtube.com/watch?v=WUpx47h0pzI&#34;&gt;Brotkastenfreunde podcast interviews Paul&lt;/a&gt; [German language].&lt;/li&gt;
&lt;li&gt;December 28, 2019: &lt;a href=&#34;https://media.ccc.de/v/36c3-10800-creating_resilient_and_sustainable_mobile_phones&#34;&gt;Paul presents the MEGAPhone&lt;/a&gt; at 36C3, the Chaos Communication Congress for 2019: &amp;ldquo;Creating Resilient and Sustainable Mobile Phones.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/devkit_2020.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/devkit_2020.jpg 1920w, https://dansanderson.com/mega65/first-ten-years/devkit_2020_hu_6c450a329cdd9374.jpg 600w, https://dansanderson.com/mega65/first-ten-years/devkit_2020_hu_7115a25699be6456.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/devkit_2020.jpg&#34;
        alt=&#34;The MEGA65 DevKit, June 2020&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 DevKit, June 2020
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The final version of the MEGA65 would use an injection molding process to produce the replica plastic case and keycaps. Unlike short-run processes like the &lt;a href=&#34;https://www.schuerman.nl/en/plastic-processes/plastic-deep-drawing&#34;&gt;vacuum shaping&lt;/a&gt; used for the pre-series cases, injection molding requires a significant up-front tooling cost, carving the shape of the plastic into reusable metal molds capable of surviving the injection process. MEGA turned to the growing community of enthusiasts for support, raising over 69,000 EUR in donations.&lt;/p&gt;
&lt;p&gt;While the final cases were being developed, MEGA wanted to get the nearly-completed mainboards into the hands of eager developers. They produced a limited run of feature-complete MEGA65 DevKit models, with cases made from clear laser-cut acrylic panels. These would be the first MEGA65s sold to the public. The 100 units sold out quickly.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;January 2020: MEGA opens a fundraising campaign for the case molds, &lt;a href=&#34;https://c65gs.blogspot.com/2020/01/almost-65k-in-65-days.html&#34;&gt;raising over 69,000 EUR&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;June 5, 2020: &lt;a href=&#34;https://www.youtube.com/watch?v=63dUWeNvpCc&#34;&gt;Injection molding tooling testing&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;June 17, 2020: &lt;a href=&#34;https://www.m-e-g-a.org/mega65_devkit/&#34;&gt;MEGA reveals the MEGA65 limited edition Dev Kit&lt;/a&gt;, 100 units.&lt;/li&gt;
&lt;li&gt;June 20, 2020: &lt;a href=&#34;https://www.vintageisthenewold.com/learn-all-about-the-mega65-exclusive-interview-with-the-head-of-the-project-paul-gardner-stephen&#34;&gt;Vintage is the New Old interviews Paul&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;September 10, 2020: &lt;a href=&#34;https://www.youtube.com/watch?v=NJbSPwVOPhE&#34;&gt;Detlef (deft) and Anton (adtbm) give a progress update&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;November 2020: MEGA65 DevKit assembly videos by &lt;a href=&#34;https://www.youtube.com/watch?v=BJqSz99_7og&#34;&gt;retroCombs&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/watch?v=9teojaHfQYQ&#34;&gt;Shallan&lt;/a&gt;, and &lt;a href=&#34;https://www.youtube.com/watch?v=2-voZvEtz48&#34;&gt;Nostalgia Nerd&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;November/December 2020: Shallan&amp;rsquo;s MEGA65 development videos: &lt;a href=&#34;https://www.youtube.com/watch?v=UdvegfoFJV8&#34;&gt;First Steps&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/watch?v=00bm5uBeBos&#34;&gt;The Raster Rewrite Buffer&lt;/a&gt;. See also Shallan&amp;rsquo;s &lt;a href=&#34;https://www.youtube.com/playlist?list=PLq4NVS62WsPDHfWUaJ2L_Az_mlSrJ9mjg&#34;&gt;developer streams&lt;/a&gt; from January 2021 to June 2022.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;picking-up-steam&#34;&gt;Picking up steam&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/hibernated-1-directors-cut-2022.jpg&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/hibernated-1-directors-cut-2022.jpg 1120w, https://dansanderson.com/mega65/first-ten-years/hibernated-1-directors-cut-2022_hu_71f7aeff189039f4.jpg 600w, https://dansanderson.com/mega65/first-ten-years/hibernated-1-directors-cut-2022_hu_5bbebabf6682e88b.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/hibernated-1-directors-cut-2022.jpg&#34;
        alt=&#34;Hibernated 1: Director&amp;amp;#39;s Cut, by Stefan Vogt, published by poly.play&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Hibernated 1: Director&#39;s Cut, by Stefan Vogt, published by poly.play
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 project had permission from Commodore intellectual property licensor Cloanto to distribute the original Commodore 65 prototype KERNAL ROM with the computer. The code dumped from the C65 prototype ROM chips was incomplete, and it seemed clear that it wouldn&amp;rsquo;t provide the best experience for MEGA65 owners in its original form.&lt;/p&gt;
&lt;p&gt;The team formed two projects to address this. One group dug out the original Commodore 65 KERNAL source code from archives, wrote a custom assembler compatible with its vintage syntax, and began fixing bugs, completing features, and adding useful extensions. Another group began work on &lt;a href=&#34;https://github.com/MEGA65/open-roms&#34;&gt;an all-new ROM&lt;/a&gt;, a clean-room implementation of the KERNAL intended to be API compatible with software written in BASIC 10 or using C65 KERNAL APIs, using no original Commodore IP so that it could be fully open-source licensed. The &amp;ldquo;closed ROM,&amp;rdquo; &amp;ldquo;open ROM,&amp;rdquo; and the original C65 prototype ROM would be included with the MEGA65, with an easy way for users to switch between them. The closed ROM was the most complete option by the time of launch, and it was chosen as the default experience.&lt;/p&gt;
&lt;p&gt;Meanwhile, the community began writing and polishing a professional-quality &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;user&amp;rsquo;s guide&lt;/a&gt;, to be printed and included in the box. The guide included a complete reference for the closed ROM&amp;rsquo;s built-in BASIC with the latest extensions, now called &amp;ldquo;BASIC 65&amp;rdquo; to differentiate it from the original C65&amp;rsquo;s BASIC 10. The typesetting was designed to resemble an idealized form of the original Commodore 64 manuals, and contributors spent many months editing and testing the material.&lt;/p&gt;
&lt;p&gt;By September 2021, the MEGA65 was finally ready for its first production run. Manufacturing and distribution partner &lt;a href=&#34;https://shop.trenz-electronic.de/en/Products/MEGA65/&#34;&gt;Trenz Electronic&lt;/a&gt; opened for pre-orders, and sold out the first batch within a few days.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;January 23, 2021: &lt;a href=&#34;https://www.youtube.com/watch?v=_vorCvITSmA&amp;amp;list=PLD8dAKx4J2I56FBEMIxJEHXkSleWbay3h&amp;amp;index=71&#34;&gt;Paul and Martin present the MEGA65&lt;/a&gt; at LinuxConf AU 2021 (&lt;a href=&#34;https://lca2021.linux.org.au/schedule/presentation/111/&#34;&gt;abstract&lt;/a&gt;). See also Paul&amp;rsquo;s other talk at the same conference, &lt;a href=&#34;https://www.youtube.com/watch?v=sfpfxnwJ4eI&amp;amp;list=PLD8dAKx4J2I56FBEMIxJEHXkSleWbay3h&amp;amp;index=48&#34;&gt;Digital Sovereignty&lt;/a&gt;, a concept at the heart of the MEGA65 project.&lt;/li&gt;
&lt;li&gt;January 28, 2021: &lt;a href=&#34;https://www.youtube.com/watch?v=Ohf0sWlrs-s&#34;&gt;Detlef and Anton update, January 2021&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;February 3, 2021: MEGA65 team member Bit Shifter &lt;a href=&#34;https://c65gs.blogspot.com/2021/02/guest-post-from-bit-shifter-improving.html&#34;&gt;picks up development of the MEGA65 ROM&lt;/a&gt; based on the original C65 ROM source code.&lt;/li&gt;
&lt;li&gt;March 18, 2021: &lt;a href=&#34;https://www.youtube.com/watch?v=AsWDnoU2T_Q&#34;&gt;Detlef and Anton update, March 2021&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;April 30, 2021: &lt;a href=&#34;https://theretrohour.com/commodore-65-mega-65-ep273/&#34;&gt;The Retro Hour podcast interviews Paul&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;May 16, 2021: &lt;a href=&#34;https://www.youtube.com/watch?v=KDwIMwlIcb0&#34;&gt;Detlef and Anton update, May 2021&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;September 30, 2021: Pre-orders open for MEGA65 production units. &lt;a href=&#34;https://www.vintageisthenewold.com/mega65-available-for-pre-order-next-week&#34;&gt;Reporting of pre-announcement&lt;/a&gt;, &lt;a href=&#34;https://www.m-e-g-a.org/mega65-pre-orders/&#34;&gt;belated official blog announcement&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;October 10, 2021: &lt;a href=&#34;https://www.youtube.com/watch?v=smvwnWHJJlE&#34;&gt;Retro Computer News on the MEGA65&lt;/a&gt; and MEGAPhone.&lt;/li&gt;
&lt;li&gt;December 26, 2021: &lt;a href=&#34;https://www.youtube.com/watch?v=lFM3mJO1M30&#34;&gt;retroCombs demonstrates the MEGA65 Intro Disk&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;January 7, 2022: poly.play publishes the first boxed commercial title for the MEGA65: &lt;a href=&#34;https://www.m-e-g-a.org/first-physical-mega65-release/&#34;&gt;Hibernated 1: Director&amp;rsquo;s Cut&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;March 21, 2022: &lt;a href=&#34;https://youtu.be/9Ib7z64z9N4?si=EbOkn3q-fmiT4BoP&#34;&gt;lydon explains the MiSTer2MEGA65 framework&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;production-models&#34;&gt;Production models&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/intro_disk_1_2022.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/intro_disk_1_2022.png 720w, https://dansanderson.com/mega65/first-ten-years/intro_disk_1_2022_hu_a519616a77c15703.png 600w, https://dansanderson.com/mega65/first-ten-years/intro_disk_1_2022_hu_96f862a75ae0d76b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/intro_disk_1_2022.png&#34;
        alt=&#34;Intro Disk #1&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Intro Disk #1
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Thousands of people joined the queue for the new computer, excited that the project was close to achieving its lofty goals—and perhaps eager for something to do at home during the continuing global health crisis. Unfortunately, that same crisis disrupted supply chains for electronic components and other materials, and Trenz had to delay delivery of the first batch by several months. Subsequent delivery dates would be difficult to predict, dependent entirely on availability of components.&lt;/p&gt;
&lt;p&gt;Work continued on the FPGA core and KERNAL ROM projects. The MEGA65 was designed to be upgradeable, such that everyone who would receive hardware would continue to benefit from improvements. The first batch of computers shipped with what would be known as v0.9 of the platform.&lt;/p&gt;
&lt;p&gt;Also included with every computer: an SD card populated with dozens of programs written by early developers, DevKit owners, and team members. When a new owner first turns on the MEGA65, they are greeted by the Intro Disk menu, a colorful animated display with jaunty music. The SD card also bundled many Commodore 64 games and demos, which the user could run from the Commodore 65&amp;rsquo;s C64 compatibility mode.&lt;/p&gt;
&lt;p&gt;I received my MEGA65 in May of 2022. To help new owners get over some of the rough patches in the early experience while the team worked to fix them, I wrote a &lt;a href=&#34;https://dansanderson.com/mega65/welcome/&#34;&gt;Welcome Guide&lt;/a&gt; with advice and explanations. The project needed help staying in contact with people waiting on pre-orders and others who had expressed interest, so I started &lt;em&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/em&gt;, a monthly email newsletter and read-aloud podcast. My hope was to get more information about the MEGA65 into various forms of online media, improve the ability to find the project through search engines, and keep people informed of project activity as we bootstrapped the community.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;May 2022: The first batch of 400 units is delivered.&lt;/li&gt;
&lt;li&gt;May 27, 2022: &lt;a href=&#34;https://www.epsilonsworld.com/2022/05/my-mega-65-has-arrived.html&#34;&gt;Epsilon&amp;rsquo;s World review&lt;/a&gt; with many photos.&lt;/li&gt;
&lt;li&gt;May 28, 2022: &lt;a href=&#34;https://www.youtube.com/watch?v=djT7PKPlojE&#34;&gt;Detlef (deft) and Oliver (lydon) update&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;April 28, 2022: &lt;a href=&#34;https://www.youtube.com/watch?v=WDGXpqycPWU&#34;&gt;Gurce introduces the BASIC PLAY command&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;May 11, 2022: &lt;a href=&#34;https://www.youtube.com/watch?v=Qbrn7s458iY&#34;&gt;Thomas Gruber receives his MEGA65&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;May 27, 2022: &lt;a href=&#34;https://www.youtube.com/watch?v=q00WjXhYyhQ&#34;&gt;drwuro describes his first experiences with BASIC 65&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;June 4, 2022: &lt;a href=&#34;https://www.youtube.com/watch?v=5LoKucNzs6U&#34;&gt;AmigaLove: The Miraculous MEGA65 Computer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;June 2022: I publish the &lt;a href=&#34;https://dansanderson.com/mega65/welcome/&#34;&gt;MEGA65 Welcome Guide&lt;/a&gt; for new owners of the 1st batch of retail MEGA65s.&lt;/li&gt;
&lt;li&gt;August 31, 2022: I start &lt;a href=&#34;https://dansanderson.com/mega65/keeping-up-with-the-mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt;, a monthly newsletter and read-aloud podcast.&lt;/li&gt;
&lt;li&gt;September 17, 2022: &lt;a href=&#34;https://www.youtube.com/watch?v=ftyQ5-kHrdQ&#34;&gt;Gurce presents Battle Sparrow&lt;/a&gt; to Commodore Users Europe, and explains how he got involved with the MEGA65 project as early as 2016.&lt;/li&gt;
&lt;li&gt;September 24, 2022: &lt;a href=&#34;https://www.youtube.com/watch?v=BJgEeA8pNbs&#34;&gt;RetroRecipes unboxes the MEGA65&lt;/a&gt;. See also his &lt;a href=&#34;https://youtu.be/iWsKpG3fuGg?si=0FQbxgZnUgRRm5wk&#34;&gt;follow-up playtest&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;October 15, 2022: &lt;a href=&#34;https://youtu.be/Vr9rLUQZgJI?si=w60oDXUUOLhMpBZe&#34;&gt;retroCombs introduces the MEGA65&lt;/a&gt;, the official intro video on the MEGA65 home page. See also the &lt;a href=&#34;https://www.youtube.com/watch?v=UUVOtkLP-eY&amp;amp;list=PLRVBh2hjFTomDGwIT7uPMJv4zH9JAUSVG&#34;&gt;MEGA65 User&amp;rsquo;s Guide video series&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;November 18, 2022: &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt; launches.&lt;/li&gt;
&lt;li&gt;November 20, 2022: &lt;a href=&#34;https://www.youtube.com/watch?v=sgnLsakVZaY&#34;&gt;Xanadu, by deathy/BAS and Gurce&lt;/a&gt;, a two-part demo released at Syntax Party 2022.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-second-batch&#34;&gt;The second batch&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/mousepad_2023.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/mousepad_2023.png 625w, https://dansanderson.com/mega65/first-ten-years/mousepad_2023_hu_8c8388e5e7265ba4.png 600w, https://dansanderson.com/mega65/first-ten-years/mousepad_2023_hu_f20d5994d2f056d5.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/mousepad_2023.png&#34;
        alt=&#34;45GS02 Quick Reference mousepad&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
45GS02 Quick Reference mousepad
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The first delivery batch in May 2022 consisted of 400 units. Another 400 units shipped eight months later, in 2023. The supply chain crisis was ongoing, with limited FPGA supply going to the world&amp;rsquo;s biggest customers and leaving smaller projects on hold. As word spread about the project, more people got in line, but many who pre-ordered in late 2021 were still waiting.&lt;/p&gt;
&lt;p&gt;With more computers in the hands of developers, the MEGA65 was coming into its own, both as a capable 8-bit home computer with attractive features for games and demos, and as an FPGA platform for alternate computer chipsets. One of the most influential FPGA projects was the &lt;a href=&#34;https://github.com/MJoergen/C64MEGA65&#34;&gt;C64 core&lt;/a&gt;, a highly accurate recreation of the Commodore 64 based on a similar project for the &lt;a href=&#34;https://github.com/MiSTer-devel/Wiki_MiSTer/wiki&#34;&gt;MiSTer FPGA platform&lt;/a&gt;. The C64 core was especially welcomed by MEGA65 owners who were hoping to use it as a C64 while waiting for the community to produce more MEGA65 software. The original Commodore 65 team never fully overcame design choices that limited compatibility with existing C64 software, and some speculate that this was a contributing factor that led to the C65 getting cancelled. With the C64 core, the MEGA65 could reconfigure itself with a C64 chipset and run nearly all C64 software with high fidelity.&lt;/p&gt;
&lt;p&gt;Then came the first MEGA65 accessories. Publisher &lt;a href=&#34;https://www.polyplay.xyz/Home&#34;&gt;poly.play&lt;/a&gt; released several MEGA65 games as deluxe boxed editions. Paul designed a four-player joystick adapter for the cartridge port, and &lt;a href=&#34;https://www.bit-zeal.com/product/4PlayerMEGA65/6&#34;&gt;Jim Happel assembled some&lt;/a&gt; to distribute along with &lt;a href=&#34;https://files.mega65.org?id=4b46aca8-ec3b-4483-ae64-df1dfec3ee66&#34;&gt;a disk of four-player games&lt;/a&gt;. Boutique vintage computer clothier Sew Ready produced &lt;a href=&#34;https://www.ebay.com/itm/185798516548&#34;&gt;a dust cover for the C65/MEGA65&lt;/a&gt;. I designed a machine code quick reference for the CPU that you can &lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;purchase as a mousepad or a poster&lt;/a&gt;. Paul also started work on &lt;a href=&#34;https://c65gs.blogspot.com/2024/02/expansion-board-revd-and-new-connector.html&#34;&gt;an expansion board&lt;/a&gt;, a DIY kit that would sit inside the MEGA65 case and provide additional hardware features. (The expansion board is still a work in progress.)&lt;/p&gt;
&lt;p&gt;We declared a new release of the MEGA65 platform—specifically the MEGA65 core, ROM, and system software—as version 0.95 in late 2022, in time to be installed at the factory on second-batch machines. Of course, owners of first-batch machines could upgrade to v0.95 for free. To accompany the release, we finished a 2nd edition of the User Guide that was used for the next printing of bundled manuals, and also made it &lt;a href=&#34;https://www.lulu.com/shop/dan-sanderson-and-edilbert-kirk-and-paul-gardner-stephen/mega65-users-guide/paperback/product-dyrzzzy.html?page=1&amp;amp;pageSize=4&#34;&gt;available via print-on-demand&lt;/a&gt; so owners of the 1st edition could upgrade this as well.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;November 2022: MEGA65 platform v0.95 is released.&lt;/li&gt;
&lt;li&gt;January 2023: The second batch of 400 units is delivered.&lt;/li&gt;
&lt;li&gt;January 20, 2023: &lt;a href=&#34;https://www.youtube.com/watch?v=G355OZSqD5A&#34;&gt;XMAS65, by Mirage&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;January 27, 2023: &lt;a href=&#34;https://www.youtube.com/watch?v=EFV0NnYjH0s&#34;&gt;8-Bit Resurgence discovers the MEGA65&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;June 23, 2023: &lt;a href=&#34;https://www.youtube.com/watch?v=n3ke0alwjds&#34;&gt;C64 for MEGA65 Version 5 Release Trailer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;July 24, 2023: &lt;a href=&#34;https://www.youtube.com/watch?v=vYTTn3fLNxc&#34;&gt;I present the MEGA65 at Pacific Commodore Expo NW 2023&lt;/a&gt;: &amp;ldquo;What&amp;rsquo;s up, MEGA65?&amp;rdquo;&lt;/li&gt;
&lt;li&gt;September 30, 2023: &lt;a href=&#34;https://www.youtube.com/watch?v=G2DUurCSXWQ&#34;&gt;lydon presents at Classic Computing 2023&lt;/a&gt; [German language].&lt;/li&gt;
&lt;li&gt;October 9, 2023: &lt;a href=&#34;https://www.youtube.com/watch?v=Voyiaw4UJto&#34;&gt;Bad Apple, by Mirage&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;October 14, 2023: &lt;a href=&#34;https://media.ccc.de/v/vcfb2023_-_185_-_de_-_202310141545_-_mega65_-_oliver_graf&#34;&gt;lydon presents the MEGA65&lt;/a&gt; at Vintage Computing Festival Berlin: &amp;ldquo;Peek the Past, Poke the Future.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;November 29, 2023: &lt;a href=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/&#34;&gt;45GS02 Quick Reference mousepads&lt;/a&gt; available for purchase.&lt;/li&gt;
&lt;li&gt;January 8, 2024: &lt;a href=&#34;https://www.youtube.com/watch?v=8qHdTKjPXww&#34;&gt;The 8-Bit Guy takes a look at the MEGA65&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;January 31, 2024: &lt;a href=&#34;https://www.youtube.com/watch?v=Ho_4_Ar4meA&#34;&gt;Paul assembles a prototype expansion board&lt;/a&gt; [live stream].&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;general-availability&#34;&gt;General availability&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/mega65-box.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/first-ten-years/mega65-box.jpeg 2048w, https://dansanderson.com/mega65/first-ten-years/mega65-box_hu_27d8efb8f403f939.jpeg 600w, https://dansanderson.com/mega65/first-ten-years/mega65-box_hu_e0d75c1d7d8d7b75.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/first-ten-years/mega65-box.jpeg&#34;
        alt=&#34;The MEGA65 retail box&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 retail box
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Keeping a hardware project perpetually available at low volumes requires some flexibility when it comes to components. The MEGA65 is not a mass-produced appliance, and neither MEGA nor Trenz can purchase and store thousands of identical parts just to keep using the same mainboard design. In 2023, Trenz notified the team that components of the R3A revision of the mainboard used in the first 800 MEGA65s shipped would soon become unavailable. Paul updated the board design with newer replacement parts. He also took the opportunity to fix a few issues we encountered with R3A boards, such as unreliable Real-Time Clock chips. The R6 mainboard revision would be used for MEGA65s going forward, at least until the next component end-of-life notice.&lt;/p&gt;
&lt;p&gt;Some members of the community expressed concern that the hardware revision meant that some MEGA65s were different than others, and certain products might only work with one revision or another. This was mostly noticed with the FPGA core projects, which needed to be updated by their authors for the newer board. Eventually, nearly all alternate cores were updated for both mainboard revisions. (As of this writing, only a few arcade cores remain to be updated.) More controversially, the R6 mainboard included &lt;a href=&#34;https://shop.trenz-electronic.de/media/pdf/ca/ca/31/Mega65-Pressemitteilung.pdf&#34;&gt;a few extra features&lt;/a&gt; in addition to repairs. At the request of the community, Trenz Electronic began &lt;a href=&#34;https://shop.trenz-electronic.de/en/TE0765-06-T002CK-MEGA65-Mainboard-without-housing?c=564&#34;&gt;selling bare mainboards&lt;/a&gt; for anyone wishing to upgrade.&lt;/p&gt;
&lt;p&gt;By 2024, the supply chain crisis abated. All remaining pre-orders for MEGA65s were fulfilled, and Trenz Electronic upgraded the MEGA65 to &lt;a href=&#34;https://shop.trenz-electronic.de/en/TE0765-06-T001CK-MEGA65-highly-advanced-C64-and-C65-compatible-8-bit-computer?c=564&#34;&gt;in-stock status in their store&lt;/a&gt;. Today, Trenz assembles computers in small batches to keep new orders for the MEGA65 on a short delivery timeline.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;February 2024: MEGA65 platform v0.96 is released.&lt;/li&gt;
&lt;li&gt;June 2024: The third batch of 800 units is delivered.&lt;/li&gt;
&lt;li&gt;June 21, 2024: &lt;a href=&#34;https://lyonsden.net/my-mega65-is-finally-here/&#34;&gt;Lyonsden Blog review&lt;/a&gt; with photos.&lt;/li&gt;
&lt;li&gt;June 22, 2024: &lt;a href=&#34;https://www.youtube.com/watch?v=QY1Zj5tIhL4&#34;&gt;I present the MEGA65 at Pacific Commodore Expo NW 2024&lt;/a&gt;: &amp;ldquo;Lessons from My First Two Years with the MEGA65.&amp;rdquo; See also &lt;a href=&#34;https://youtu.be/HYT8zUi7axQ?si=Tt83EZceiizKj0ek&#34;&gt;Katie S. unboxing the MEGA65&lt;/a&gt; at the same event.&lt;/li&gt;
&lt;li&gt;October 2024: All pending pre-orders are fulfilled, and the MEGA65 becomes generally available for sale.&lt;/li&gt;
&lt;li&gt;October 7, 2024: &lt;a href=&#34;https://youtu.be/GUz5R3fmKuI?si=wdZPp51p_F698qoL&#34;&gt;John Aljets interviews me briefly at Portland Retro Gaming Expo&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;November 16, 2024: &lt;a href=&#34;https://www.youtube.com/live/Jt8cdmAikzs?si=zNrTzX3pHAW8vJj_&amp;amp;t=15761&#34;&gt;Joeri van Haren interviews me at CRX 2024&lt;/a&gt; [at 4:22:41 of the Day 2 stream].&lt;/li&gt;
&lt;li&gt;January 20, 2025: &lt;a href=&#34;https://www.youtube.com/watch?v=1xj2Fj3SjUk&amp;amp;t=1s&#34;&gt;The 8 Bit Theory: What C128 and C64 developers should know about the MEGA65&amp;rsquo;s personalities&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-next-10-years&#34;&gt;The Next 10 Years&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/first-ten-years/bannersml.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/first-ten-years/bannersml.png&#34;
            width=&#34;1500&#34;
            height=&#34;500&#34;
            alt=&#34;&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The thing that excites me most about the MEGA65 is that I keep meeting new people who are also excited about it. Trenz Electronic continues to receive new orders, and sometimes people tell me when they place their orders after seeing the MEGA65 at a conference or in a YouTube video. I&amp;rsquo;ve met people who had never heard of it before, people who heard rumors about it in the early days, and people who were on the verge of buying one and decided to take the plunge. Kids love it, at least the ones attending vintage computing conventions. They play the games, but they have just as much fun flipping through the User Guide and trying out the BASIC commands.&lt;/p&gt;
&lt;p&gt;A healthy recreational computing community has multiple layers, each one grown from and supported by the one below it. Initially, these layers form around the platform itself: hardware hackers, FPGA core developers, KERNAL coders, technical writers. Then new people try it out, and find purchase to explore their interests and share their results: programming learners, game makers, demosceners, tool builders, media creators. As people are inspired by the passions of others, they contribute their own passions back, giving everyone more ways to enjoy and engage. People come and go, but the surface area continues to expand. This, more than anything, is what prevents technological abstractions from alienating users: there are people at every layer willing to help other people learn and explore.&lt;/p&gt;
&lt;p&gt;What I most like about the MEGA65 specifically is how its layered design welcomes a community with diverse backgrounds and interests. The authentic Commodore-style BASIC is more accessible than ever, for running programs and for learning how to write new ones. Programmers both novice and expert can explore the undiscovered country of the architecture, pushing this alternate 8-bit timeline forward. And Commodore enthusiasts can access a previously inaccessible piece of history, use it with vintage peripherals and software, and summon more platforms with FPGA cores.&lt;/p&gt;
&lt;p&gt;The community at the FPGA layer has been surprisingly active in the last couple of years. The &lt;a href=&#34;https://github.com/sy2002/MiSTer2MEGA65&#34;&gt;MiSTer2MEGA65 framework&lt;/a&gt; and the excellent work of the MiSTer community draw a clear path toward someday having a complete Commodore computer museum that fits on your desk, in an authentic Commodore keyboard-wedge form factor. C65/MEGA65 and C64 cores exist today, PET and VIC-20 cores have public test releases, and there&amp;rsquo;s a great deal of interest in a potential Amiga core as well. There are cores for the ZX Spectrum, Game Boy, and TI-99/4A, with an Apple IIe core also in development, not to mention a dozen arcade cabinet cores. The MEGA65 has huge potential as an FPGA learning tool, as well.&lt;/p&gt;
&lt;p&gt;Specific to the MEGA65 platform (that&amp;rsquo;s the core, ROM, system software), the MEGA65 Steering Committee is marshaling the project on a steady path to a v1.0 release, with an emphasis on feature quality and API stability. Development will continue beyond v1.0, using a high bar for backwards compatibility of changes, while continuing to track the interests of the community as it evolves and grows. As the current ROM lead, I&amp;rsquo;m especially interested in formalizing more of the KERNAL API surface and building hooks for third-party extensions. (Inner layers beget outer layers.) And we have tons of ideas for improving the non-platform parts of the user experience: on-screen interfaces, documentation, PC tools, networking.&lt;/p&gt;
&lt;p&gt;MEGAPhone research will contribute features back into the MEGA65 platform. It may even be hardware you can purchase someday. The MEGA65 hardware will continue to adapt to shifts in global conditions, as resources allow, so the community can continue to grow.&lt;/p&gt;
&lt;p&gt;And what was that &amp;ldquo;new clothes&amp;rdquo; thing deft was on about? 🤔&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;To ensure the growth and longevity of the platform and the community, we must continue to pump energy through the layers, inviting more people with diverse interests and enthusiasm. It&amp;rsquo;s why I write this Digest.&lt;/p&gt;
&lt;p&gt;If you find this Digest useful, please consider becoming a supporter. Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn/&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Congratulations to the MEGA65 team on an incredible ten years!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/first-ten-years/M65Digest_2025Apr.mp3" length="" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>4140</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/first-ten-years/mega65_globe.jpg"/>
      
    </item>
    
    <item>
      <title>What&#39;s New in v0.97</title>
      <link>https://dansanderson.com/mega65/whats-new-v0-97/</link>
      <pubDate>Tue, 25 Mar 2025 16:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/whats-new-v0-97/</guid>
      <description>&lt;p&gt;What&amp;rsquo;s New in v0.97. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for March 2025.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;What&amp;rsquo;s New in v0.97. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for March 2025.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/whats-new-v0-97/M65Digest_2025Mar.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/whats-new-v0-97/M65Digest_2025Mar.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
What&#39;s New in v0.97.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/whats-new-v0-97/mega65_okiprint.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/whats-new-v0-97/mega65_okiprint.jpeg 640w, https://dansanderson.com/mega65/whats-new-v0-97/mega65_okiprint_hu_5b1fb13a94563c62.jpeg 600w, https://dansanderson.com/mega65/whats-new-v0-97/mega65_okiprint_hu_8130899fad026fb0.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/whats-new-v0-97/mega65_okiprint.jpeg&#34;
        alt=&#34;Messages printed by the MEGA65 on an Okimate 10 printer&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Messages printed by the MEGA65 on an Okimate 10 printer.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We&amp;rsquo;re getting ready to release the next major update to the MEGA65 firmware and system software, and you can help! We&amp;rsquo;re still finishing up the last few fixes before declaring a release candidate, but you can grab the latest development versions of the core and ROM and try them out. The more information we have about what works and what doesn&amp;rsquo;t, the stronger this release will be.&lt;/p&gt;
&lt;p&gt;In this Digest, we&amp;rsquo;ll review installation and testing instructions, and look through the changelogs for things that could use some exercise. Soon, we will declare a release candidate, get all hands on deck to test for a bit, then announce the new version. The result will become release package version 0.97, the new recommended stable platform for all MEGA65 users.&lt;/p&gt;
&lt;p&gt;But first, even more new stuff!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;screenful-of-basic-2025-compo-reminder&#34;&gt;Screenful of BASIC 2025 compo reminder!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/whats-new-v0-97/bwv926.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/whats-new-v0-97/bwv926.png 1337w, https://dansanderson.com/mega65/whats-new-v0-97/bwv926_hu_34c563ad0ee3f011.png 600w, https://dansanderson.com/mega65/whats-new-v0-97/bwv926_hu_46cf12d6d33a0ed8.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/whats-new-v0-97/bwv926.png&#34;
        alt=&#34;A kaleidoscopic design from one of my Screenful 2025 entries&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;A kaleidoscopic design from one of my Screenful 2025 entries.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/&#34;&gt;The Screenful of BASIC 2025 compo&lt;/a&gt; is open and accepting submissions. Thanks to everyone who has entered so far! Remember that the deadline is &lt;strong&gt;April 22, 2025, 11:59 pm GMT&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I managed to get a couple of entries in. They only took me about an afternoon each. I tried to pack a lot of code into the small amount of space, but that&amp;rsquo;s hardly necessary. Poems don&amp;rsquo;t have to be dense to be effective.&lt;/p&gt;
&lt;p&gt;Give it a try, and when you&amp;rsquo;re ready, &lt;a href=&#34;https://itch.io/jam/screenful-of-basic-2025&#34;&gt;upload your entry to itch.io and submit it to the Screenful game jam&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;megasputum-v12-for-maniac-mansion&#34;&gt;MEGASPUTUM v1.2 for Maniac Mansion&lt;/h2&gt;
&lt;p&gt;kibo and M3wP continue to evolve &lt;a href=&#34;https://files.mega65.org?id=744279a9-7ee4-40c7-b34d-26d4c06d4685&#34;&gt;MEGASPUTM&lt;/a&gt;, their LucasArts adventure game player, currently capable of running the Amiga version of &lt;em&gt;Maniac Mansion&lt;/em&gt;. The newly released v1.2 of MEGASPUTM adds a really cool feature: the ability to switch between the Amiga version&amp;rsquo;s sound and music, and the Commodore 64&amp;rsquo;s SID-based sound and music.&lt;/p&gt;
&lt;p&gt;Installing the data files from the Amiga and C64 versions of &lt;em&gt;Maniac Mansion&lt;/em&gt; can be a challenge, so M3wP has made it easier with a new utility included with the player. Provide the original Amiga ADF and Commodore 64 D64 disk image files for the game, and the utility will install the appropriate files onto the D81 disk images, directly on your MEGA65.&lt;/p&gt;
&lt;p&gt;Huge thanks to kibo and M3wP for this fun update, and for continuing to work on the project!&lt;/p&gt;
&lt;h2 id=&#34;mister2mega-framework-update&#34;&gt;MiSTer2MEGA framework update&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/whats-new-v0-97/MiSTer2MEGA65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/whats-new-v0-97/MiSTer2MEGA65.png 2048w, https://dansanderson.com/mega65/whats-new-v0-97/MiSTer2MEGA65_hu_576247f9164cbcb9.png 600w, https://dansanderson.com/mega65/whats-new-v0-97/MiSTer2MEGA65_hu_dab0c4f809d72e1c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/whats-new-v0-97/MiSTer2MEGA65.png&#34;
        alt=&#34;The MiSTer2MEGA FPGA framework&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The MiSTer2MEGA FPGA framework&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;sy2002 and MJoergen have updated the &lt;a href=&#34;https://github.com/sy2002/MiSTer2MEGA65&#34;&gt;MiSTer2MEGA&lt;/a&gt; framework, upon which multiple alternate cores are based, to repair issues with R6 boards, HDMI output, and the joystick swapping feature. Authors of alternate cores will need to re-build and re-release the cores to pick up the fixes.&lt;/p&gt;
&lt;p&gt;muse has already started the process of updating the arcade cores, starting with &lt;a href=&#34;https://files.mega65.org?id=36b41376-b2c6-45e6-a441-cd126357fdd4&#34;&gt;Bank Panic&lt;/a&gt; and &lt;a href=&#34;https://files.mega65.org?id=6a96f6de-2673-40c0-9304-5720fe8ce144&#34;&gt;Burnin&amp;rsquo; Rubber&lt;/a&gt;. There is also now an R6 version of the Burnin&amp;rsquo; Rubber core.&lt;/p&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/whats-new-v0-97/megachase.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/whats-new-v0-97/megachase.png 1024w, https://dansanderson.com/mega65/whats-new-v0-97/megachase_hu_6ba4fde676e6faa3.png 600w, https://dansanderson.com/mega65/whats-new-v0-97/megachase_hu_84e3a924cb3a998.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/whats-new-v0-97/megachase.png&#34;
        alt=&#34;Mega Chase, by shad0wfax&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Mega Chase, by shad0wfax.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=2ea6b891-c07f-4ee2-9253-6ddf706d165e&#34;&gt;Mega Chase&lt;/a&gt; by shad0wfax is an asymmetric 1-player or 2-player space battle game. Player One controls a powerful laser cannon capable of destroying ships in a single blast. Player Two (or the computer) pilots their ship, trying to dodge the laser. If the ship is hit before time runs out, Player One is victorious, otherwise Player Two escapes to fight another day. The game features original quad-SID music, multicolor sprites, custom text fonts, and sampled sound effects, and is written in BASIC.&lt;/p&gt;
&lt;p&gt;muse&amp;rsquo;s arcade core of the month! &lt;a href=&#34;https://files.mega65.org?id=b5fb8733-4850-403c-a7dc-3e9a84a44b0c&#34;&gt;Dig Dug&lt;/a&gt; (Namco, 1982) is now available for both R3 and R6 mainboards. Dig Dug was voted &lt;a href=&#34;https://www.arcade-museum.com/top100&#34;&gt;the 6th most popular arcade game of all time&lt;/a&gt; by the Killer List of Videogames, and was the &lt;a href=&#34;https://en.wikipedia.org/wiki/Arcade_video_game#Highest-grossing&#34;&gt;36th highest grossing&lt;/a&gt; according to sources gathered by Wikipedia. See &lt;a href=&#34;https://github.com/sho3string/DigDugMEGA65_R3_R6&#34;&gt;the Github repo of the core&lt;/a&gt; for installation instructions, as usual.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=d9c77007-b5c3-4d4e-a41c-745d81cad528&#34;&gt;Meteor Defense&lt;/a&gt; by Nuwanda puts you in charge of defending your city against a barrage of meteors. 80-column character based graphics give this challenging shooter extra charm.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=a42f3921-dded-420b-a8d9-144f8d5c8dee&#34;&gt;Mars, 2049 AD&lt;/a&gt; by fredrikr is a short dialog-based text adventure game, written for &lt;a href=&#34;https://itch.io/jam/punycomp-2024&#34;&gt;PunyComp 2024&lt;/a&gt; using the Inform 6 programming language and the &lt;a href=&#34;https://github.com/johanberntsson/PunyInform&#34;&gt;PunyInform&lt;/a&gt; library. This MEGA65 version uses the Ozmoo interactive fiction player. You can &lt;a href=&#34;https://fredrikr.itch.io/mars2049ad&#34;&gt;visit the game&amp;rsquo;s itch.io page&lt;/a&gt;, or &lt;a href=&#34;https://ifdb.org/viewgame?id=n4mp7nk7zzt8onz6&#34;&gt;rate it at IFDB.org&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;how-to-get-the-latest-development-core-and-rom&#34;&gt;How to get the latest development core and ROM&lt;/h2&gt;
&lt;p&gt;You can download the latest development core and ROM at the following links. The core builds include the system files to copy to the SD card, as well as the core file to install from the core menu.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://builder.mega65.org/job/mega65-core/job/development/&#34;&gt;Download the latest development core&lt;/a&gt; for your mainboard revision.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=mega65-rom-beta&#34;&gt;Download the latest beta ROM&lt;/a&gt;. (Registered owner account required.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/new-hotness/&#34;&gt;We covered installation steps and tips last year&lt;/a&gt; when we were testing v0.96, so I won&amp;rsquo;t repeat those. The &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt; also has improved instructions for installing cores and system files.&lt;/p&gt;
&lt;p&gt;The ROM changes in this release are expected to all be functional with the v0.96 core. If you can, please test the development core and ROM together, but if it&amp;rsquo;s more convenient for you, you can test the ROM separately. (This is not always the case for release testing, it just happens to be the case this time.)&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t yet own a MEGA65 and want to help test the ROM in the Xemu emulator, &lt;a href=&#34;https://files.mega65.org?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;the ROM FAQ&lt;/a&gt; explains how to use &lt;a href=&#34;https://files.mega65.org?id=mega65-rom-beta-diff&#34;&gt;the latest ROM patch file&lt;/a&gt;. Please use &lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;the latest &amp;ldquo;future next stable&amp;rdquo; release&lt;/a&gt; of Xemu.&lt;/p&gt;
&lt;p&gt;Remember that you can have multiple ROMs installed on your SD card. The ROM whose file is named &lt;code&gt;MEGA65.ROM&lt;/code&gt; is used by default. To install a secondary ROM, give its file the name &lt;code&gt;MEGA652.ROM&lt;/code&gt;, then hold the &lt;kbd&gt;2&lt;/kbd&gt; key during boot. You can install up to eight ROMs this way with the v0.96 core; the latest development core expands this to ten ROMs, one for each digit key.&lt;/p&gt;
&lt;p&gt;The development core includes changes to the Configuration interface. If you don&amp;rsquo;t want to make the development core your default core, you can access a non-default core&amp;rsquo;s interface by booting to the core selection menu (hold the &lt;kbd&gt;No Scroll&lt;/kbd&gt; key while switching on the computer), selecting the core, then immediately pressing and holding the &lt;kbd&gt;Alt&lt;/kbd&gt; key to open its version of the Configuration menu.&lt;/p&gt;
&lt;p&gt;Pay attention to &lt;a href=&#34;https://discord.gg/5DNvESf&#34;&gt;the Discord&lt;/a&gt; for updates and other testing instructions. Please file bugs in Github:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/MEGA65/mega65-core/issues&#34;&gt;Report a core issue&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues&#34;&gt;Report a ROM issue&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re not sure which type of issue it is, &lt;a href=&#34;https://github.com/MEGA65/mega65-core/issues&#34;&gt;assume it&amp;rsquo;s a core issue&lt;/a&gt;, and we&amp;rsquo;ll figure it out.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;core-changes-in-v097-rc&#34;&gt;Core changes in v0.97 RC&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/whats-new-v0-97/v097rc_config.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/whats-new-v0-97/v097rc_config.png 1429w, https://dansanderson.com/mega65/whats-new-v0-97/v097rc_config_hu_f935b0f200a046d.png 600w, https://dansanderson.com/mega65/whats-new-v0-97/v097rc_config_hu_77e86f8b920a858.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/whats-new-v0-97/v097rc_config.png&#34;
        alt=&#34;The new Configuration option to disable disk noise, in the v0.97 release candidate&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The new Configuration option to disable disk noise, in the v0.97 release candidate.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;New features for everyday use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can now mount D64 disk images from the Freezer.&lt;/li&gt;
&lt;li&gt;By default, accessing a D81 disk image in unit 8 manipulates the floppy drive to make nostalgic sounds. You can now disable this in Configuration: Chipset, Disk Image Drive Noise.&lt;/li&gt;
&lt;li&gt;You can now have up to 10 alternate ROMs on the SD card, numbered 0 to 9.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New features for programmers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DMA start and end addresses can now span megabyte boundaries, e.g. $00FFFFCC - $01000033.&lt;/li&gt;
&lt;li&gt;Audio DMA can now trigger an IRQ when the playhead for a channel hits a given address high byte. Set D713.0-3 to enable IRQs for each audio DMA channel, and set D714-D717 to the address high byte trigger. In the IRQ handler, test D713.4-7 to determine which channel triggered. This makes sound sample buffering much easier to implement, for streaming long samples from Attic memory or other sources.&lt;/li&gt;
&lt;li&gt;If the HWERRATA register is set above its maximum value for the given core, it will return the maximum value. Programs that need later HWERRATA levels can use this to detect if they&amp;rsquo;re running on an earlier core (and not getting the requested level).&lt;/li&gt;
&lt;li&gt;Core selection menu support for the &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/36962324/MEGA65+Style+Cartridge+Work+in+Progress&#34;&gt;MEGA65 cartridge protocol&lt;/a&gt;. The v0.97 RC ROM also has corresponding changes.&lt;/li&gt;
&lt;li&gt;Serial debugger disables interrupts in trace mode, so you can step through code without accidentally branching into the IRQ handler. (To step through the IRQ handler itself, set the breakpoint in the handler routine.) Note that this does not set the CPU &lt;code&gt;I&lt;/code&gt; flag: it uses a separate mechanism so that the program&amp;rsquo;s use of the &lt;code&gt;I&lt;/code&gt; flag is represented accurately.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hardware support:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;R4-R6 boards support the &lt;a href=&#34;https://github.com/MEGA65/mega65-kbd-pcb&#34;&gt;DIY keyboard&lt;/a&gt; project.&lt;/li&gt;
&lt;li&gt;Core builds support the Wukong A100T V2 platform.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The v0.97 RC core also has improvements in these areas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SID 8580 accuracy&lt;/li&gt;
&lt;li&gt;Audio mixer&lt;/li&gt;
&lt;li&gt;Raster Rewrite Buffer&lt;/li&gt;
&lt;li&gt;Paddle/mouse line jitter&lt;/li&gt;
&lt;li&gt;CIA one-shot timers&lt;/li&gt;
&lt;li&gt;Sprites and the border&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;rts #...&lt;/code&gt; instruction&lt;/li&gt;
&lt;li&gt;C64 cartridge detection&lt;/li&gt;
&lt;li&gt;Configuration utility&lt;/li&gt;
&lt;li&gt;Keyboard debounce&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are currently known issues with mounting disks from the Freezer in the latest build. Also, formatting a new SD card doesn&amp;rsquo;t correctly offer to populate the SD card with the system software. We&amp;rsquo;re working on fixing these, and will hold this release until they are fixed.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/MEGA65/mega65-core/blob/development/release-build/Changelog.md&#34;&gt;the mega65-core changelog&lt;/a&gt; for more details and links to resolved issues.&lt;/p&gt;
&lt;h2 id=&#34;rom-changes-in-v097-rc&#34;&gt;ROM changes in v0.97 RC&lt;/h2&gt;
&lt;p&gt;These ROM changes include corresponding changes in &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;the latest User&amp;rsquo;s Guide PDF&lt;/a&gt;, as appropriate. Feel free to &lt;a href=&#34;https://github.com/MEGA65/mega65-user-guide/issues&#34;&gt;report documentation issues&lt;/a&gt;, if you find any.&lt;/p&gt;
&lt;p&gt;New features for everyday use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can now mount D64 disk images using the &lt;code&gt;MOUNT&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;The command &lt;code&gt;DIR U12&lt;/code&gt;, to list the contents of the SD card, now accepts a pattern matching string, similar to using &lt;code&gt;DIR&lt;/code&gt; with DOS devices. All wildcard characters are supported. For example: &lt;code&gt;DIR &amp;quot;M*&amp;quot;,U12&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;DIR&lt;/code&gt; command has a new &lt;code&gt;P&lt;/code&gt; flag that pauses long directory listings at each screenful: &lt;code&gt;DIR P&lt;/code&gt;,  &lt;code&gt;DIR P,U12&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Similarly, the &lt;code&gt;TYPE&lt;/code&gt; command has a new &lt;code&gt;P&lt;/code&gt; flag that pauses long &lt;code&gt;TYPE&lt;/code&gt; output at each screenful, for displaying text files: &lt;code&gt;TYPE &amp;quot;FILENAME&amp;quot;,P&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New features for BASIC programmers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BASIC now supports binary literals! Use a percent sigil to start a binary number literal: &lt;code&gt;%1010&lt;/code&gt; The new &lt;code&gt;DECBIN(&amp;quot;...&amp;quot;)&lt;/code&gt; function converts a string of &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; to a number. &lt;code&gt;STRBIN$(n)&lt;/code&gt; converts a number to a string of &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; characters.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PRINT USING %&lt;/code&gt;-style patterns now support left zero padding for positive values in float and integer patterns: &lt;code&gt;%07.2F&lt;/code&gt; &lt;code&gt;%05D&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RWINDOW(3)&lt;/code&gt; returns the screen height in rows, regardless of window size, similar to how &lt;code&gt;RWINDOW(2)&lt;/code&gt; returns the screen width in columns.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JOY()&lt;/code&gt; now reports up to five game controller buttons, as defined by the 5-button protocol and as implemented by several modern game controllers and adapters. The C64GS controller reports two buttons; Commotron and several others report three buttons; mouSTer and Unijoysticle report five buttons. This protocol works with both R3 and R6 mainboards.
&lt;ul&gt;
&lt;li&gt;Note that the Xemu emulator pretends that a mouse is connected by default, which causes &lt;code&gt;JOY()&lt;/code&gt; to believe buttons 4 and 5 are pressed. &lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;The &amp;ldquo;next&amp;rdquo; version of Xemu&lt;/a&gt; adds the ability to disable mouse emulation: open the context menu, Input Devices, Disable mouse emulation. Xemu does not yet have a way to emulate joystick buttons 2-5.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JOY(3)&lt;/code&gt; reports the combined status of joysticks in either port, allowing for a program to easily support a single joystick in either port without calling &lt;code&gt;JOY()&lt;/code&gt; twice.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CHAR&lt;/code&gt; now accepts a 28-bit charset address argument. This was previously limited to 20-bit addresses.
This is mostly useful for &lt;code&gt;CHAR ...,$FF7E000&lt;/code&gt;, which tells &lt;code&gt;CHAR&lt;/code&gt; to use the custom charset defined by &lt;code&gt;FONT&lt;/code&gt; and &lt;code&gt;CHARDEF&lt;/code&gt; statements when drawing text to the graphics screen. Use &lt;code&gt;$FF7E800&lt;/code&gt; for lowercase.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RPALETTE()&lt;/code&gt; now accepts a screen number of -1 to refer to the primary system palette (palette 0). It also accepts -2, -3, and -4 for the other three system palettes (palettes 1-3). Support for using the other system palettes from BASIC is planned for a future release.&lt;/li&gt;
&lt;li&gt;It is now possible to disable &amp;ldquo;line pushing&amp;rdquo; in the screen editor, using the escape sequence &lt;kbd&gt;ESC&lt;/kbd&gt; &lt;kbd&gt;R&lt;/kbd&gt; (&lt;code&gt;PRINT CHR$(27)+&amp;quot;R&amp;quot;&lt;/code&gt;). Use &lt;kbd&gt;ESC&lt;/kbd&gt; &lt;kbd&gt;N&lt;/kbd&gt; to re-enable. This allows the &lt;code&gt;PRINT&lt;/code&gt; command to write a character to the right-most column without pushing other lines downward. Note that you must still use &lt;kbd&gt;ESC&lt;/kbd&gt; &lt;kbd&gt;M&lt;/kbd&gt; (&lt;code&gt;PRINT CHR$(27)+&amp;quot;M&amp;quot;&lt;/code&gt;) to disable screen scrolling to PRINT a character in the bottom-right corner without scrolling the screen. (Use &lt;kbd&gt;ESC&lt;/kbd&gt; &lt;kbd&gt;L&lt;/kbd&gt; to re-enable scrolling.)&lt;/li&gt;
&lt;li&gt;The BASIC sprite subsystem now recognizes and honors the VIC-IV high resolution sprite registers &lt;code&gt;sprenv400&lt;/code&gt; (high-res vertical, per sprite) and &lt;code&gt;sprh640&lt;/code&gt; (high-res horizontal, system-wide). &lt;code&gt;MOVSPR&lt;/code&gt; accepts 10-bit X and Y coordinates, and will correctly truncate coordinates in low-res modes. We will be adding a mode for matching the sprite resolution to the screen resolution in a future release. It will always be supported for a BASIC program to set these registers directly. We will also add support for a hires mouse pointer in a future release.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BSAVE&lt;/code&gt; now has a &amp;ldquo;raw&amp;rdquo; mode, symmetric with the &lt;code&gt;BLOAD&lt;/code&gt; &amp;ldquo;raw&amp;rdquo; mode, that omits the two-byte start address header normally used for PRGs. This is essential for saving SEQ files, which typically don&amp;rsquo;t have such a header.&lt;/li&gt;
&lt;li&gt;The bitwise operations &lt;code&gt;AND&lt;/code&gt;, &lt;code&gt;OR&lt;/code&gt;, &lt;code&gt;XOR&lt;/code&gt;, and &lt;code&gt;NOT&lt;/code&gt; operate on 16-bit integer values, and were previously restricted to the range of possible signed 16-bit integers [-32,768, 32,767]. It is often convenient to operate on the range of unsigned 16-bit integers [0, 65,535], but these operators were rejecting operands above 32,767. With this update, these operators now accept operands in the range [-32768, 65535]. They are still treated like 16-bit integers and produce a result in the signed 16-bit integer range.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New and improved KERNAL routines; see the &amp;ldquo;KERNAL Jump Table&amp;rdquo; appendix of &lt;a href=&#34;https://files.mega65.org?id=d668168c-1fef-4560-a530-77e9e237536d&#34;&gt;the Compendium&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SAVEFL&lt;/code&gt;: a &lt;code&gt;SAVE&lt;/code&gt; variant that can do a &amp;ldquo;raw&amp;rdquo; save, similar to the BSAVE BASIC command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GETIO&lt;/code&gt;: Read the current input and output devices&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GETLFS&lt;/code&gt; : Read file, device, secondary address&lt;/li&gt;
&lt;li&gt;&lt;code&gt;KEYLOCKS&lt;/code&gt;: Read/set keyboard locks&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ADDKEY&lt;/code&gt;: Add a character to the soft keyboard input buffer&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SETBNK&lt;/code&gt;: Reimplemented with 28-bit address support, using a backwards compatible API.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VECTOR&lt;/code&gt;: &lt;code&gt;KEYSCAN&lt;/code&gt; vector allows programs to intercept keyboard input.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Important changes to existing features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The BASIC &lt;code&gt;INT()&lt;/code&gt; function now always rounds toward negative infinity, also known as &lt;a href=&#34;https://en.wikipedia.org/wiki/Floor_and_ceiling_functions&#34;&gt;the floor function&lt;/a&gt;. This is a change to the behavior when the argument is negative and has a fractional part: &lt;code&gt;INT(-1.5) = -2&lt;/code&gt;, &lt;code&gt;INT(-1) = -1&lt;/code&gt;. All versions of Commodore BASIC, and many other BASICs derived from Microsoft BASIC, define &lt;code&gt;INT()&lt;/code&gt; as &amp;ldquo;floor,&amp;rdquo; and other parts of BASIC depend on this definition internally. This was inadvertently changed starting at ROM 920177 to mean &amp;ldquo;round toward zero,&amp;rdquo; breaking dependent behaviors. Restoring this also fixes issues with trigonometric functions and other features.&lt;/li&gt;
&lt;li&gt;Previously, if the &lt;code&gt;RENUMBER&lt;/code&gt; command was executed without a space between the command name and the first argument (e.g. &lt;code&gt;RENUMBER100&lt;/code&gt;), the command would omit the space between keywords and line numbers in the resulting program (&amp;ldquo;crunch&amp;rdquo; mode). This feature remains, but now requires a &lt;code&gt;C&lt;/code&gt; flag to prevent accidental activation: &lt;code&gt;RENUMBER C 100&lt;/code&gt; Note that &amp;ldquo;crunch&amp;rdquo; mode does not change any other whitespace in the program.&lt;/li&gt;
&lt;li&gt;The KERNAL &lt;code&gt;VECTOR&lt;/code&gt; routine now copies 56 bytes of vector table data, not 32. Future changes to the vector table will use a different routine, to keep this API compatible with existing programs.&lt;/li&gt;
&lt;li&gt;The boot state of register $0001 has changed to start with the datasette lines turned off. The datasette port will be supported in the upcoming expansion board.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stuff that already existed but has now been documented in &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;the latest User&amp;rsquo;s Guide PDF&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;VOL&lt;/code&gt; command accepts two parameters, a volume for the right stereo channel SIDs, and a volume for the left stereo channel SIDs: &lt;code&gt;VOL 9,9&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;MOUSE&lt;/code&gt; command was intended by Fred Bowen to accept arguments to adjust the location of the &amp;ldquo;hot spot&amp;rdquo; on the mouse pointer sprite, as well as set the pointer&amp;rsquo;s initial screen position. These arguments were incorrectly documented and also were not functioning correctly. The features have been fixed, using the original intended argument order: &lt;code&gt;MOUSE ON,port,sprite,hotspot-x,hotspot-y,location-x,location-y&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The trigonometric functions &lt;code&gt;SIN()&lt;/code&gt;, &lt;code&gt;COS()&lt;/code&gt;, and &lt;code&gt;TAN()&lt;/code&gt; accept an argument in units of radians. The previously undocumented variants &lt;code&gt;SIND()&lt;/code&gt;, &lt;code&gt;COSD()&lt;/code&gt;, and &lt;code&gt;TAND()&lt;/code&gt;, respectively, accept an argument in units of degrees.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FONT&lt;/code&gt; accepts a built-in font ID as a parameter: &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, or &lt;code&gt;C&lt;/code&gt;. It also supports &lt;code&gt;D&lt;/code&gt;, &lt;code&gt;E&lt;/code&gt;, and &lt;code&gt;F&lt;/code&gt;, which are the same as &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, and &lt;code&gt;C&lt;/code&gt;, respectively, set to lowercase mode. (&lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;Shift&lt;/kbd&gt; toggles between uppercase and lowercase, as usual, unless disabled by the appropriate escape code.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The v0.97 RC ROM also has improvements in these areas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BASIC 65 bitplane graphics&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;MONITOR&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run/Stop + Restore&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CHAR&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VSYNC&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Number printing&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MOUNT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POT()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CURSOR ON&lt;/code&gt; mode was leaving behind stray blinked-on cursors when the position changed.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PRINT USING&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JOY(1)&lt;/code&gt; no longer reports a spurious signal when top row keys are pressed.&lt;/li&gt;
&lt;li&gt;Text highlighting of error messages&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RMOUSE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DEC()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FOR X&amp;amp; = ...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MOVSPR&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DS&lt;/code&gt; / &lt;code&gt;DS$&lt;/code&gt; disk error codes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BLOAD&lt;/code&gt; and &lt;code&gt;BVERIFY&lt;/code&gt; and Attic RAM&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VAL()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MOUSE ON&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/blob/main/CHANGELOG.md&#34;&gt;the ROM changelog&lt;/a&gt; for more details.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Thanks to everyone who is available to help test this release. Even if you only have a moment to install it and run through a few games and demos, it&amp;rsquo;d be really appreciated.&lt;/p&gt;
&lt;p&gt;Also, huge thanks to everyone who has contributed to the platform in the last year and a half! Every bug fixed makes the MEGA65 better for everyone, now and into the future.&lt;/p&gt;
&lt;p&gt;Remember, you can support this Digest and my other work. Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/whats-new-v0-97/M65Digest_2025Mar.mp3" length="" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1460</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/whats-new-v0-97/mega65_okiprint.jpeg"/>
      
    </item>
    
    <item>
      <title>Screenful of BASIC 2025 compo</title>
      <link>https://dansanderson.com/mega65/screenful-compo-2025/</link>
      <pubDate>Wed, 19 Feb 2025 12:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/screenful-compo-2025/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for February 2025. A new BASIC code competition for the MEGA65 10th anniversary!&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for February 2025. A new BASIC code competition for the MEGA65 10th anniversary!&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/screenful-compo-2025/M65Digest_2025Feb.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/M65Digest_2025Feb.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Screenful of BASIC 2025 compo.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/screenful_example.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/screenful-compo-2025/screenful_example.png 689w, https://dansanderson.com/mega65/screenful-compo-2025/screenful_example_hu_19b790531cc626bb.png 600w, https://dansanderson.com/mega65/screenful-compo-2025/screenful_example_hu_608262bf4f435599.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/screenful-compo-2025/screenful_example.png&#34;
        alt=&#34;An example entry for the Screenful of BASIC 2025 compo.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An example entry for the Screenful of BASIC 2025 compo.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;On April 22, 2015, the Museum of Electronic Games &amp;amp; Art and Paul Gardner-Stephen &lt;a href=&#34;https://www.m-e-g-a.org/mega65-introduction/&#34;&gt;announced the MEGA65 project to the world&lt;/a&gt;. Paul also &lt;a href=&#34;https://c65gs.blogspot.com/2015/04/introducing-mega65-retro-computer.html&#34;&gt;announced the project&lt;/a&gt; on his development blog, where he had been documenting his work on a &amp;ldquo;C65GS&amp;rdquo; FPGA bitstream, on which the MEGA65 would be based. The MEGA65 has been a thing for &lt;em&gt;ten years!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To help celebrate the ten-year anniversary of the MEGA65, ZeHa of Dr. Wuro Industries is throwing a short-form BASIC competition—and you&amp;rsquo;re invited! We want as many entries as possible, so power up your MEGA65 and crack open your &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;User&amp;rsquo;s Guide&lt;/a&gt;. No experience necessary!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll keep this Digest brief so you have extra time to start playing with code. We&amp;rsquo;ll go over how to enter the compo, check out some recent Featured Files, and take a brief look at a fun and obscure feature of the VIC-IV video chip: high resolution text fonts.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;the-screenful-of-basic-2025-compo&#34;&gt;The Screenful of BASIC 2025 compo&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s time for a good ol&amp;rsquo; fashioned short-form BASIC competition!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The twist:&lt;/strong&gt; Your program must be written in BASIC 65, and the program listing must fit entirely in one screen of 80 x 25 text, including space for the &lt;code&gt;READY.&lt;/code&gt; prompt at the bottom of the screen. Someone should be able to type your program in from a single screenshot, and type &lt;code&gt;LIST&lt;/code&gt; to see the entire program on screen. No data files allowed, one screen of code is all you get!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The deadline:&lt;/strong&gt; Entries must be submitted by &lt;strong&gt;11:59 pm GMT, April 22, 2025.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How to submit:&lt;/strong&gt; Go to &lt;a href=&#34;https://itch.io/jam/screenful-of-basic-2025&#34;&gt;the itch.io page for the compo&lt;/a&gt;, create an itch.io account, and follow the instructions. Upload a D81 disk image containing a single PRG file of your program.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pick your favorites:&lt;/strong&gt; Public voting will open from April 23 to April 30. All entries will be available for download from itch.io. Results will be announced on May 1st.&lt;/p&gt;
&lt;p&gt;Your program can do anything you&amp;rsquo;d like, and use any feature of the MEGA65. Just don&amp;rsquo;t destroy someone&amp;rsquo;s files or commit any crimes. Submissions should be family friendly in content. Multiple submissions are allowed, if you&amp;rsquo;re feeling productive.&lt;/p&gt;
&lt;p&gt;Most MEGA65 users are running the latest stable release package v0.96, including ROM 920395. If your program requires a more recent &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/blob/main/CHANGELOG.md&#34;&gt;ROM beta version&lt;/a&gt;, be sure to say so in the description of your entry. (We&amp;rsquo;re close to releasing v0.97 with all of the changes, but it won&amp;rsquo;t go out before the compo deadline.)&lt;/p&gt;
&lt;p&gt;By submitting an entry to the competition, you assert that you have copyrights to the code, and you are assigning the &lt;a href=&#34;https://www.m-e-g-a.org/&#34;&gt;Museum of Electronic Games &amp;amp; Art&lt;/a&gt; (MEGA) a non-exclusive right to distribute your program globally. Your entry will be hosted on &lt;a href=&#34;https://itch.io/&#34;&gt;itch.io&lt;/a&gt;, and may also be included in a compilation disk distributed on &lt;a href=&#34;https://files.mega65.org/html/main.php&#34;&gt;Filehost&lt;/a&gt; or bundled with the MEAG65 on the SD card as part of the &amp;ldquo;Intro Disk&amp;rdquo; anthology.&lt;/p&gt;
&lt;p&gt;For complete rules and submission instructions, visit &lt;a href=&#34;https://itch.io/jam/screenful-of-basic-2025&#34;&gt;the Screenful of BASIC 2025 compo home page&lt;/a&gt; on itch.io. Many thanks to ZeHa for hosting this event!&lt;/p&gt;
&lt;h2 id=&#34;basic-compo-tips&#34;&gt;BASIC compo tips&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/ForBasicToOneLinersCover.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/screenful-compo-2025/ForBasicToOneLinersCover.png 500w, https://dansanderson.com/mega65/screenful-compo-2025/ForBasicToOneLinersCover_hu_36e332f0e21dadf6.png 600w, https://dansanderson.com/mega65/screenful-compo-2025/ForBasicToOneLinersCover_hu_c2a410c4b8cc59ff.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/screenful-compo-2025/ForBasicToOneLinersCover.png&#34;
        alt=&#34;Cover of the book For BASIC To One-Liners, by Holger Weßling&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;For BASIC To One-Liners, by Holger Weßling.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Clever coders have devised many ways to cram a lot of BASIC into a little space, just as a personal challenge or for a short-form coding competition like Screenful. Figuring out what works and what doesn&amp;rsquo;t is part of the fun. If you&amp;rsquo;d like a bit of inspiration, there&amp;rsquo;s a book I can recommend. &lt;a href=&#34;https://lookbehindyou.de/produkt/for-basic-to-one-liners/&#34;&gt;For Basic to One-Liners&lt;/a&gt; by Holger Weßling is packed with time-tested tips and tricks that apply to many dialects of microcomputer BASIC, with a focus on the Commodore 64 and short-form BASIC competitions. ZeHa himself is mentioned in the book!&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve covered BASIC programming topics in past issues of this Digest. In particular, check out &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/&#34;&gt;October 2023: Robot Finds Kitten, part 1&lt;/a&gt; and &lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/&#34;&gt;July 2024: Let&amp;rsquo;s Paint&lt;/a&gt; for some ideas.&lt;/p&gt;
&lt;p&gt;For the purposes of short-form compos, the biggest difference between BASIC 65 and other Commodore BASICs is the breadth of graphics, sound, and music commands available. The language is mostly the same. I&amp;rsquo;d watch out for &lt;a href=&#34;https://www.forum64.de/index.php?thread/111002-mega65-rom-benchmark-results/&amp;amp;postID=1622976#post1622976&#34;&gt;an unusual fact about &lt;code&gt;BEGIN&lt;/code&gt;-&lt;code&gt;BEND&lt;/code&gt; blocks from BASIC 7&lt;/a&gt;, where everything after the &lt;code&gt;BEND&lt;/code&gt; on the same line is considered part of the block. If you discover any more language oddities, please mention them in &lt;a href=&#34;https://discord.gg/5DNvESf&#34;&gt;the Discord&lt;/a&gt; or &lt;a href=&#34;http://mega65.net/&#34;&gt;on Forum64.de&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/wumpus_video.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/screenful-compo-2025/wumpus_video.png 1225w, https://dansanderson.com/mega65/screenful-compo-2025/wumpus_video_hu_ab621be03f5817dd.png 600w, https://dansanderson.com/mega65/screenful-compo-2025/wumpus_video_hu_b2135383fd028846.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/screenful-compo-2025/wumpus_video.png&#34;
        alt=&#34;Still image from &amp;amp;#39;Hunt the Wumpus on the Mega65!&amp;amp;#39; from the YouTube channel Coding with Culp&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;&amp;ldquo;Hunt the Wumpus on the Mega65!&amp;rdquo; from the YouTube channel Coding with Culp.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=163f7eb1-fcdf-48a5-9f05-b03c5bb984b0&#34;&gt;Hunt the Wumpus&lt;/a&gt; by Dave Culp revives the classic computer game in BASIC 65. Traverse the dungeon, watch for clues, and take the Wumpus by surprise—before it surprises you. Don&amp;rsquo;t miss &lt;a href=&#34;https://www.youtube.com/watch?v=Pip6d3JzjLk&#34;&gt;Dave&amp;rsquo;s video about his game&lt;/a&gt; on his YouTube channel, Coding with Culp.&lt;/p&gt;
&lt;p&gt;It seems like muse has a new arcade core for us every month! I won&amp;rsquo;t hold him to that schedule, but I will very much enjoy &lt;a href=&#34;https://files.mega65.org?id=3b7c7970-bed2-4080-bb69-8fe197016901&#34;&gt;Bank Panic&lt;/a&gt; (1984) from Sega. This western-themed reflex action game features colorful cartoon graphics and a unique user interface. This bank has so many doors! R6 owners will prefer the VGA video output. We&amp;rsquo;re waiting on a video fix for R6 boards in the &lt;a href=&#34;https://github.com/sy2002/MiSTer2MEGA65&#34;&gt;MiSTer2MEGA&lt;/a&gt; framework that affects HDMI output of some arcade cores. I needed to use the horizontal position adjustment feature in the menu system, but then it looked great over VGA on my screen. As usual, see &lt;a href=&#34;https://github.com/sho3string/BankPanicMEGA65_R3_R6&#34;&gt;the Github repo&lt;/a&gt; for installation instructions.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=4baa92ff-94d2-4751-8f5d-1f1932b161bc&#34;&gt;WarGames simulator&lt;/a&gt;, originally by Andy Glenn, ported to BASIC 65 by Mr. Jones. Recreate scenes from the classic movie &lt;a href=&#34;https://en.wikipedia.org/wiki/WarGames&#34;&gt;WarGames&lt;/a&gt; (1983) and avert Global Thermonuclear War. The game features a narrative hint mode if you don&amp;rsquo;t remember the movie.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=37e99233-a45d-4350-bbf3-be25d93f1983&#34;&gt;BasicTracker&lt;/a&gt; by ZeHa is a simple, intuitive music composition program with a &lt;a href=&#34;https://en.wikipedia.org/wiki/Music_tracker&#34;&gt;tracker&lt;/a&gt;-like interface. Compose for six simultaneous voices, each with six possible instruments. Enter two octaves worth of notes using letters and numbers, move the cursor with the cursor keys, and follow on-screen instructions for the rest. There&amp;rsquo;s no way to save or export song data, this is just for fun.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;tall-character-mode&#34;&gt;Tall Character Mode&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/hackfont.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/screenful-compo-2025/hackfont.png 1092w, https://dansanderson.com/mega65/screenful-compo-2025/hackfont_hu_a0474defd1bc9627.png 600w, https://dansanderson.com/mega65/screenful-compo-2025/hackfont_hu_3ff8c9a6292a33e5.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/screenful-compo-2025/hackfont.png&#34;
        alt=&#34;The font Hack converted to a MEGA65 high resolution font, by M3wP&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The font Hack converted to a MEGA65 high resolution font, by M3wP.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When you first turn on the computer, it starts up with a text screen 80 character wide and 25 characters tall, where each character is 8 pixels wide and 8 pixels tall, for a resolution of 640 x 200. There are two other text mode resolutions you can access directly from this screen: press &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;4&lt;/kbd&gt; to enter 40 x 25 text mode, &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;5&lt;/kbd&gt; to enter 80 x 50 text mode, and &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;8&lt;/kbd&gt; to return to 80 x 25 text mode. All of these modes use 8 x 8 characters.&lt;/p&gt;
&lt;p&gt;The MEGA65 has another way to draw text—and it&amp;rsquo;s practically a secret. Tall Character mode (TCR mode) doubles the vertical pixel resolution without changing the dimensions of the screen. Each character becomes 8 pixels wide and 16 pixels tall, making the text sharper and easier to read. TCR mode needs a 8x16 font to do this, and the MEGA65 does not have any TCR fonts built in. But there&amp;rsquo;s an easy way to load such fonts yourself.&lt;/p&gt;
&lt;p&gt;Xemu users, note that TCR support was very recently added to the &lt;code&gt;next&lt;/code&gt; branch (as of version 20250216001821), so download the latest if you want to try this in the emulator.&lt;/p&gt;
&lt;h2 id=&#34;loading-tcr-font-files-with-the-freezer&#34;&gt;Loading TCR font files with the Freezer&lt;/h2&gt;
&lt;p&gt;M3wP has been experimenting with this feature recently, and produced TCR conversions of several modern fixed width fonts. Download M3wP&amp;rsquo;s conversions of the fonts &lt;a href=&#34;https://files.mega65.org?id=f2c7b8a3-fa62-4e70-add7-4ccaff40bd9d&#34;&gt;Courier&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=8dc113c6-1d06-4670-9c7c-479aa5fafce4&#34;&gt;Xirod&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=8dc8b5dd-5513-4f62-abe7-09c4c71b6868&#34;&gt;Hack&lt;/a&gt;, and &lt;a href=&#34;https://files.mega65.org?id=572254ae-9857-4806-b62f-2457401ddcae&#34;&gt;Noto&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;These fonts are distributed in the &lt;code&gt;.TCR&lt;/code&gt; file format, a binary format that matches how this data appears in the MEGA65&amp;rsquo;s memory. To load a &lt;code&gt;.TCR&lt;/code&gt; file into the MEGA65:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Copy the &lt;code&gt;.TCR&lt;/code&gt; file to your SD card.&lt;/li&gt;
&lt;li&gt;Open the Freezer.&lt;/li&gt;
&lt;li&gt;Press the &lt;kbd&gt;L&lt;/kbd&gt; key. Select the &lt;code&gt;.TCR&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Press &lt;kbd&gt;F3&lt;/kbd&gt; to resume, and enjoy!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are lowercase ASCII character sets only, and naturally are missing PETSCII graphics symbols. They contain ASCII symbols such as underscore (&lt;code&gt;_&lt;/code&gt;) and tilde (&lt;code&gt;~&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id=&#34;the-oldschool-pc-font-resource&#34;&gt;The Oldschool PC Font Resource&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/pcfonts_all.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/screenful-compo-2025/pcfonts_all.png 1232w, https://dansanderson.com/mega65/screenful-compo-2025/pcfonts_all_hu_cf9570e7531c34da.png 600w, https://dansanderson.com/mega65/screenful-compo-2025/pcfonts_all_hu_6d0a389786933303.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/screenful-compo-2025/pcfonts_all.png&#34;
        alt=&#34;An IBM PC font on the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An IBM PC font on the MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Inspired by M3wP&amp;rsquo;s example, I spent an afternoon playing with &lt;a href=&#34;https://int10h.org/oldschool-pc-fonts/&#34;&gt;The Oldschool PC Font Resource&lt;/a&gt;, a large collection of high fidelity reproductions of system fonts for IBM PCs, PC compatibles, and various BIOSes and devices. I wrote a script to convert the 8x16 bitmap fonts to TCR files, and put together a font browser in BASIC:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=795e98b8-70f6-4343-afff-474fc6704585&#34;&gt;PCFONTS.D81&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mount this disk image, then &lt;code&gt;RUN &amp;quot;*&amp;quot;&lt;/code&gt; to play with the font browser.&lt;/p&gt;
&lt;p&gt;A PC font normally has 256 unique characters in it, with the usual cast of ASCII characters in the first half and some familiar PC graphics characters and symbols in the second half. I attempted to relocate the ASCII-style characters to the corresponding screen codes used for PETSCII, such that ASCII text could be displayed without changes. I put some of the PC symbol characters (like the smiley faces) at useful but arbitrary locations.&lt;/p&gt;
&lt;p&gt;There are two TCR files for each font: a 128-character version and a 256-character (&amp;ldquo;all characters&amp;rdquo;) version. The 128-character version uses the first 128 characters of the PC font, then repeats them in &amp;ldquo;reverse&amp;rdquo; video for the second 128 characters, such that the screen terminal cursor blinks correctly. When the screen terminal&amp;rsquo;s cursor is over a letter, it blinks between the letter and its reverse, so both need to be present in the character set.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/pcfont_128.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/screenful-compo-2025/pcfont_128.png 912w, https://dansanderson.com/mega65/screenful-compo-2025/pcfont_128_hu_909d257b5886ddcd.png 600w, https://dansanderson.com/mega65/screenful-compo-2025/pcfont_128_hu_3753278bad45a312.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/screenful-compo-2025/pcfont_128.png&#34;
        alt=&#34;A PC font organized into a 128-character screen code layout, with reverses&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A PC font organized into a 128-character screen code layout, with reverses.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The 256-character version of the TCR font uses all 256 characters of the PC font, with no reverses. This makes more symbols available, at the expense of not working correctly with the screen terminal. If you&amp;rsquo;re writing your own program, you could implement a new cursor using the reverse character attribute instead of dedicated reverse characters. (We tried upgrading the screen terminal to do this, but ran into issues with how the VIC-III defines character attributes. That&amp;rsquo;s a story for another day.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/pcfont_256.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/screenful-compo-2025/pcfont_256.png 912w, https://dansanderson.com/mega65/screenful-compo-2025/pcfont_256_hu_b5ca3530ac700aee.png 600w, https://dansanderson.com/mega65/screenful-compo-2025/pcfont_256_hu_7b460de057be45be.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/screenful-compo-2025/pcfont_256.png&#34;
        alt=&#34;A PC font organized into a 256-character screen code layout, without reverses&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A PC font organized into a 256-character screen code layout, without reverses.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/dansanderson/mega65-pcfonts&#34;&gt;the mega65-pcfonts Github repo&lt;/a&gt; for documentation, loose TCR files, and the scripts I used to put it all together. Or just enjoy the demo disk.&lt;/p&gt;
&lt;h2 id=&#34;using-a-tcr-font-from-a-program&#34;&gt;Using a TCR font from a program&lt;/h2&gt;
&lt;p&gt;To use a TCR font in your own program (or &lt;code&gt;AUTOBOOT.C65&lt;/code&gt; startup sequence), the TCR file must be on a D81 disk image. You can use the usual PC tools to make such an image, or you can do it on the MEGA65 with the &lt;code&gt;BSAVE&lt;/code&gt; command, like so:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use the Freezer to load the TCR file into the character generator buffer, as above.&lt;/li&gt;
&lt;li&gt;Mount your D81 disk image.&lt;/li&gt;
&lt;li&gt;At the &lt;code&gt;READY&lt;/code&gt; prompt, &lt;code&gt;BSAVE&lt;/code&gt; the character generator buffer: &lt;code&gt;BSAVE &amp;quot;MYFONT.TCR&amp;quot;,P($FF7E000) TO P($FF7EFFF)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;code&gt;PCFONTS.D81&lt;/code&gt; disk has the TCR files on the disk, so you can copy those with the &lt;code&gt;COPY&lt;/code&gt; command. Note that the PC fonts are released under a Creative Commons license with attribution and &amp;ldquo;share-alike&amp;rdquo; provisions. See the licensing terms in &lt;a href=&#34;https://github.com/dansanderson/mega65-pcfonts/blob/main/README.md&#34;&gt;the README.md file&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In your program, load the font file into memory, and activate the TCR mode:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Load the TCR file from disk into the character generator buffer, starting at address $FF7E000.&lt;/li&gt;
&lt;li&gt;Optionally, disable CRT emulation. (TCR mode works with this enabled, but doesn&amp;rsquo;t look as nice.) Clear the PALEMU register, $D054, bit 5.&lt;/li&gt;
&lt;li&gt;Enable TCR mode. Set the CHARY16 register, $D07A, bit 4.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In BASIC:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 BLOAD &amp;#34;MYFONT.TCR&amp;#34;,P($FF7E000)
20 CLRBIT $D054,5
30 SETBIT $D07A,4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To return to 8x8 PETSCII:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Disable TCR mode. Clear the CHARY16 register.&lt;/li&gt;
&lt;li&gt;Restore the PETSCII character set. A BASIC program can use the &lt;code&gt;FONT&lt;/code&gt; command to do this.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;980 CLRBIT $D07A,4
990 FONT C
1000 END&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;how-tcr-fonts-work&#34;&gt;How TCR fonts work&lt;/h2&gt;
&lt;p&gt;In the VIC-IV TCR mode, character set data is read directly from the character generator memory at $FF7E000-$FF7EFFF (4 KB). The screen terminal does not switch between &amp;ldquo;uppercase + graphics&amp;rdquo; and &amp;ldquo;lowercase + uppercase&amp;rdquo; text modes. There is only one text mode. Whereas a PETSCII character set has a set of 256 characters for each text mode, TCR mode uses the same amount of memory for a single mode, with twice as many pixels per character.&lt;/p&gt;
&lt;p&gt;TCR character set data is interpreted as a single set of 256 characters of 8 x 16 resolution, using interleaving lines from charset positions n and n+256. For example, screen code 1 is normally a lowercase &amp;ldquo;a&amp;rdquo; character. Its image is made of alternating lines of the data at positions 1 and 257 in the character set, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Byte      Charset address
---------------------------
........  FF7E008
........            FF7E808
........  FF7E009
........            FF7E809
........  FF7E00A
..xxxx..            FF7E80A
.....xx.  FF7E00B
.....xx.            FF7E80B
..xxxxx.  FF7E00C
.xx..xx.            FF7E80C
.xx..xx.  FF7E00D
..xxxxxx            FF7E80D
........  FF7E00E
........            FF7E80E
........  FF7E00F
........            FF7E80F&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In memory, the lines look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;........  FF7E008
........  FF7E009
........  FF7E00A
.....xx.  FF7E00B
..xxxxx.  FF7E00C
.xx..xx.  FF7E00D
........  FF7E00E
........  FF7E00F

........            FF7E808
........            FF7E809
..xxxx..            FF7E80A
.....xx.            FF7E80B
.xx..xx.            FF7E80C
..xxxxxx            FF7E80D
........            FF7E80E
........            FF7E80F&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s a fun way to get an intuition for how this works. The original 8x8 PETSCII font keeps uppercase letters in the first half and lowercase letters in the second half. Without loading a TCR font, enable TCR mode by setting the CHARY16 register: &lt;code&gt;SETBIT $D07A,4&lt;/code&gt; The VIC-IV interleaves the uppercase and lowercase PETSCII characters at double the vertical resolution.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/screenful-compo-2025/petscii_in_tcr.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/screenful-compo-2025/petscii_in_tcr.png 1351w, https://dansanderson.com/mega65/screenful-compo-2025/petscii_in_tcr_hu_a3c87d9ae3644ba.png 600w, https://dansanderson.com/mega65/screenful-compo-2025/petscii_in_tcr_hu_69d241894f333dca.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/screenful-compo-2025/petscii_in_tcr.png&#34;
        alt=&#34;The 8x8 PETSCII character set with 8x16 TCR mode enabled, illustrating how TCR character data is interleaved&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The 8x8 PETSCII character set with 8x16 TCR mode enabled, illustrating how TCR character data is interleaved.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr&gt;
&lt;p&gt;Character graphics are a &lt;em&gt;big&lt;/em&gt; subject on the MEGA65, and I&amp;rsquo;m planning a series of Digest feature articles for later this year to cover as much of it as I can.&lt;/p&gt;
&lt;p&gt;If you like this kind of thing, please consider supporting the Digest. Your patronage makes this Digest possible—and makes it free for everyone. Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;https://ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now get cracking on that screenful!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/screenful-compo-2025/M65Digest_2025Feb.mp3" length="20645056" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1040</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/screenful-compo-2025/screenful_example.png"/>
      
    </item>
    
    <item>
      <title>Hosting Update 2025</title>
      <link>https://dansanderson.com/mega65/hosting-update-2025/</link>
      <pubDate>Tue, 11 Feb 2025 17:03:52 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/hosting-update-2025/</guid>
      <description>&lt;p&gt;Greetings MEGA65 fans! I am updating the hosting situation of this newsletter. Hopefully this will be automatic for nearly everyone, and you don&amp;rsquo;t need to do anything. Here&amp;rsquo;s what you need to know.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Greetings MEGA65 fans! I am updating the hosting situation of this newsletter. Hopefully this will be automatic for nearly everyone, and you don&amp;rsquo;t need to do anything. Here&amp;rsquo;s what you need to know.&lt;/p&gt;
&lt;p&gt;As I mentioned in &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/&#34;&gt;last month&amp;rsquo;s Digest&lt;/a&gt;, I am updating the hosting situation of this newsletter. Based on many recommendations from friends and my experiences with other newsletters, I have chosen &lt;a href=&#34;https://buttondown.com/&#34;&gt;Buttondown&lt;/a&gt; for email subscriptions. They&amp;rsquo;re featureful, reasonably priced, and best of all, you don&amp;rsquo;t need to create an account to be an email subscriber.&lt;/p&gt;
&lt;p&gt;In most cases, you don&amp;rsquo;t have to do anything in response to this change. Here are the details.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Email:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Email subscriptions should update automatically.&lt;/li&gt;
&lt;li&gt;You may need to confirm that you are receiving emails from Buttondown correctly. (Check your spam folder, etc.) If you received this by email, then it&amp;rsquo;s working.&lt;/li&gt;
&lt;li&gt;To change your email subscription, see the link at the bottom of every email.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Podcast:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Podcast subscriptions &lt;em&gt;should&lt;/em&gt; update automatically. We&amp;rsquo;ll see what happens with the next episode. 😄&lt;/li&gt;
&lt;li&gt;Apple Podcasts has been updated with the new feed URL, and the old feed URL has been set to redirect to the new one.&lt;/li&gt;
&lt;li&gt;To subscribe to the podcast in your podcast player, search for &amp;ldquo;Dan&amp;rsquo;s MEGA65 Digest,&amp;rdquo; or add &lt;a href=&#34;https://dansanderson.com/mega65/index.xml&#34;&gt;the RSS feed&lt;/a&gt; directly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;RSS feed readers and the Substack app:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you read the Digest with an RSS feed reader, make sure you are subscribed to &lt;a href=&#34;https://dansanderson.com/mega65/index.xml&#34;&gt;the RSS feed on my website&lt;/a&gt;, not Substack&amp;rsquo;s feed.&lt;/li&gt;
&lt;li&gt;If you read the Digest through the Substack app, consider subscribing by email, or use an RSS feed reader.&lt;/li&gt;
&lt;li&gt;New issues will not be posted to Substack.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Substack paid subscriptions:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you support the Digest with a paid Substack subscription, &lt;em&gt;thank you for your support!&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Your subscription is still active. You should be able to manage your subscription through &lt;a href=&#34;https://buttondown.com/&#34;&gt;Buttondown&lt;/a&gt;, or directly through &lt;a href=&#34;https://stripe.com/?ad_content=720842111268&#34;&gt;Stripe&lt;/a&gt;. Substack no longer takes a cut.&lt;/li&gt;
&lt;li&gt;Feel free to move your patronage subscription to Ko-fi: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;https://ko-fi.com/dddaaannn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All issues of the Digest are on my website: &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;dansanderson.com/mega65/&lt;/a&gt; For now, I will leave copies of past issues on Substack&amp;rsquo;s website to preserve links. New issues will be posted exclusively to my website, and distributed by email and these feeds.&lt;/p&gt;
&lt;p&gt;Thank you for your patience as I work out the kinks in the new tools! Please let me know if you have any questions, concerns, or feedback.&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>Disassembling Crossroads, part 2</title>
      <link>https://dansanderson.com/mega65/crossroads-part-2/</link>
      <pubDate>Fri, 31 Jan 2025 20:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/crossroads-part-2/</guid>
      <description>&lt;p&gt;Disassembling Crossroads, part 2. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for January 2025.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Disassembling Crossroads, part 2. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for January 2025.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/crossroads-part-2/M65Digest_2025Jan.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/M65Digest_2025Jan.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Disassembling Crossroads, part 2.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/crossroads_creatures.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/crossroads_creatures.png 511w, https://dansanderson.com/mega65/crossroads-part-2/crossroads_creatures_hu_d1f20fa3a2004c03.png 600w, https://dansanderson.com/mega65/crossroads-part-2/crossroads_creatures_hu_1eee5dea757ec30c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/crossroads_creatures.png&#34;
        alt=&#34;The creatures of Crossroads, illustration from Compute!&amp;amp;#39;s Gazette, December 1987.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The creatures of Crossroads, illustration from Compute!&#39;s Gazette, December 1987.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/&#34;&gt;In last November&amp;rsquo;s Digest&lt;/a&gt;, we started a project to dissect the classic C64 title &lt;em&gt;Crossroads&lt;/em&gt;, published by Compute!&amp;rsquo;s Gazette magazine in December 1987. We got a handle on how the game works by playing it, and by inspecting the running game state in &lt;a href=&#34;https://github.com/slajerek/RetroDebugger&#34;&gt;Retro Debugger&lt;/a&gt;, a C64 emulator with memory visualization features. In this issue, we&amp;rsquo;ll get up close and personal with the &lt;em&gt;Crossroads&lt;/em&gt; machine code, using a tool called a &lt;em&gt;disassembler&lt;/em&gt;. Combined with what we&amp;rsquo;ve learned, and some world knowledge of Commodore programs, we can begin to produce human-readable assembly language source code for the game.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Crossroads&lt;/em&gt; was so popular that Compute! commissioned a sequel, &lt;em&gt;Crossroads II: Pandemonium&lt;/em&gt;, which was published in December 1988. I did some searching to see if anyone has disassembled the &lt;em&gt;Crossroads&lt;/em&gt; games already, and discovered &lt;a href=&#34;https://github.com/hyphz/crossroads-2-disassembly/tree/master&#34;&gt;an excellent disassembly of Crossroads II&lt;/a&gt; by Github user hyphz. For the sake of the exercise, I did not look closely at this disassembly at first, but I do expect the original &lt;em&gt;Crossroads&lt;/em&gt; to be similar in many ways.&lt;/p&gt;
&lt;p&gt;We won&amp;rsquo;t do a full disassembly of &lt;em&gt;Crossroads&lt;/em&gt; in a single newsletter, but we&amp;rsquo;ll answer some of the most important questions. Before we do that, let&amp;rsquo;s see what everyone else is up to!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;pet-core-pre-release&#34;&gt;PET core pre-release&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/petcore.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/petcore.png 660w, https://dansanderson.com/mega65/crossroads-part-2/petcore_hu_ad97a5e22d6c4975.png 600w, https://dansanderson.com/mega65/crossroads-part-2/petcore_hu_3c7ebddeb71a1ed5.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/petcore.png&#34;
        alt=&#34;The Commodore PET core, running on the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The Commodore PET core, running on the MEGA65.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Olaf &amp;ldquo;Rhialto&amp;rdquo; Seibert is working on a Commodore PET core for the MEGA65, and has &lt;a href=&#34;https://files.mega65.org?id=468325ae-7e27-475d-80e7-a0f0af409446&#34;&gt;invited everyone to help test a pre-release version&lt;/a&gt;. The Filehost download includes core builds for R3 and R6 boards, and a copy of the necessary ROM files that you install on the SD card in a folder named &lt;code&gt;pet/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Do keep in mind that this is a pre-release and may be missing features. Check out &lt;a href=&#34;https://github.com/Rhialto/PET_MEGA65&#34;&gt;the Commodore PET core on Github&lt;/a&gt; to see source files and file bugs. Many thanks to Rhialto for this exciting project!&lt;/p&gt;
&lt;h2 id=&#34;gaplus-arcade-core&#34;&gt;Gaplus arcade core&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/gaplus.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/gaplus.png 224w, https://dansanderson.com/mega65/crossroads-part-2/gaplus_hu_72266e870013bf0.png 600w, https://dansanderson.com/mega65/crossroads-part-2/gaplus_hu_92eb81d881d8009f.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/gaplus.png&#34;
        alt=&#34;Gaplus arcade game, by Namco&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Gaplus arcade game, by Namco&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;muse continues to deliver arcade core goodness! This month, it&amp;rsquo;s Gaplus, the third game in the Galaga series from Namco. As usual, you will need to &lt;a href=&#34;https://files.mega65.org/?id=a87ab90e-06bc-40bb-8257-6988345d7784&#34;&gt;download the Gaplus core&lt;/a&gt;, locate MAME ROMs on the Internet, then &lt;a href=&#34;https://github.com/sho3string/GaplusMEGA65_R3_R6/blob/master/README.md&#34;&gt;follow the set-up instructions&lt;/a&gt; to produce the files for the SD card. The Gaplus core is available for both R3 and R6 mainboards.&lt;/p&gt;
&lt;p&gt;I encountered an issue with the R6 version when using HDMI video where after a few seconds the game video becomes a static screen of vertical bars. This does not occur over VGA, or with the version for the R3 mainboard. A fix is in progress.&lt;/p&gt;
&lt;h2 id=&#34;goodwells-qr-code-generator&#34;&gt;Goodwell&amp;rsquo;s QR code generator&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/qrcode_vid.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/qrcode_vid.png 1116w, https://dansanderson.com/mega65/crossroads-part-2/qrcode_vid_hu_7ebe9a41f971649.png 600w, https://dansanderson.com/mega65/crossroads-part-2/qrcode_vid_hu_5f914b2884b0116.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/qrcode_vid.png&#34;
        alt=&#34;A still from a video by The 8 Bit Theory on developing QR code generators for Commodore computers&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The 8 Bit Theory on developing QR code generators for Commodore computers.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Goodwell, aka &lt;a href=&#34;https://www.youtube.com/@the8bittheory&#34;&gt;The 8 Bit Theory on YouTube&lt;/a&gt;, recently attempted an experiment to write a &lt;a href=&#34;https://en.wikipedia.org/wiki/QR_code&#34;&gt;QR code&lt;/a&gt; generator for multiple vintage Commodore computers in multiple languages, including BASIC 2, BASIC 7, C, 6502 assembly language—and BASIC 65 for the MEGA65. &lt;a href=&#34;https://www.youtube.com/watch?v=VD_FmrHzkIA&#34;&gt;The video&lt;/a&gt; about the experience discusses implementation techniques and performance characteristics of these implementations. Definitely check it out, it&amp;rsquo;s worth watching the whole thing.&lt;/p&gt;
&lt;p&gt;Goodwell &lt;a href=&#34;https://files.mega65.org?id=1b586270-24e0-4800-b66b-89567c83541f&#34;&gt;uploaded the MEGA65 version to Filehost&lt;/a&gt;, and is continuing to refine it. It might even get added to the MEGA65 Intro Disk menu system, to make it easier to share URLs in the menu text. &lt;a href=&#34;https://github.com/the8bittheory/qr128&#34;&gt;The Github repo&lt;/a&gt; for the QR code generator has all of the versions of the experiment, as source code.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t miss Goodwell&amp;rsquo;s follow-up video about &lt;a href=&#34;https://www.youtube.com/watch?v=1xj2Fj3SjUk&#34;&gt;the MEGA65&amp;rsquo;s technical design&lt;/a&gt;, based on his early experiences developing for the computer.&lt;/p&gt;
&lt;h2 id=&#34;megamage-by-sirgeldi&#34;&gt;MegaMage by SirGeldi&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/megamage.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/megamage.png 628w, https://dansanderson.com/mega65/crossroads-part-2/megamage_hu_15c50b8a9a1cd2e7.png 600w, https://dansanderson.com/mega65/crossroads-part-2/megamage_hu_bf6b0a9caec8f1c8.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/megamage.png&#34;
        alt=&#34;MEGAMage, by SirGeldi&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MEGAMage, by SirGeldi.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Hot off the presses! SirGeldi on Forum64.de has posted &lt;a href=&#34;https://www.forum64.de/index.php?thread/153356-megamage/&#34;&gt;MEGAMage&lt;/a&gt;, a &lt;a href=&#34;https://en.wikipedia.org/wiki/Roguelike&#34;&gt;Roguelike&lt;/a&gt; adventure game written entirely in BASIC. Adorable character graphics and fast map scrolling enhance the gameplay. Even better, SirGeldi built the tools used to develop the graphics, map, and object and monster metadata for the game on the MEGA65 in BASIC, and has included these tools on the disk!&lt;/p&gt;
&lt;p&gt;Download the &lt;code&gt;.zip&lt;/code&gt; file from SirGeldi&amp;rsquo;s message post, unpack it, and transfer the D81 disk image to your MEGA65. To start the game, mount the disk image, then:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RUN &amp;#34;MEGAMAGE&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;even-more-featured-files&#34;&gt;Even more Featured Files!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/soccer_game_2mJSMR.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/soccer_game_2mJSMR.png 705w, https://dansanderson.com/mega65/crossroads-part-2/soccer_game_2mJSMR_hu_c4974bc08574ecef.png 600w, https://dansanderson.com/mega65/crossroads-part-2/soccer_game_2mJSMR_hu_3d6ccf925a88da18.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/soccer_game_2mJSMR.png&#34;
        alt=&#34;Soccer, by SirLazarus&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Soccer, by SirLazarus&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=c7911dff-a85d-4be7-b205-8f4728d7185d&#34;&gt;Soccer&lt;/a&gt;, by SirLazarus, is a new soccer-themed paddle game. It is written in BASIC, and requires the &lt;a href=&#34;https://files.mega65.org?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;latest ROM beta version&lt;/a&gt; 920409 because it uses recently added features. (This ROM update will be included in the next stable release package.) Grab your paddle controllers and check it out!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=ba8f56fb-bace-4428-b828-ce2c9fdce379&#34;&gt;Jotto 2020&lt;/a&gt;, by ToneDeF, is a word puzzle game similar to Mastermind. It plays something like Wordle, though its invention pre-dates Wordle by a year. ToneDeF originally wrote this for other micros, and made this new version for the MEGA65 in BASIC.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=925c3538-99a0-4f8f-9cc4-0f68d4f39549&#34;&gt;Pac-man in BASIC demo&lt;/a&gt;, by xlar54. This playable demo sports many features of the arcade classic, including music, sound, and polished graphics. xlar insists this is just a demo, but only a few features are missing (most notably power pellets). And yes, this too is implemented entirely in BASIC 65.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=59f31c44-8664-4b6a-927b-b4cf6566a156&#34;&gt;Opal Dance&lt;/a&gt;, by lochmana, is a colorful puzzle and maze game. Match colored pieces by walking into them, but think before you move! Each match of two pieces replaces the first piece with a wall, and removes the second piece. Clear as much of the level as you can.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=b1ba53df-1987-4789-9000-57690ef65678&#34;&gt;Mega65 Perpetual Calendar&lt;/a&gt;, by gcastel (MiddleAgedCoder on Discord). Generate calendars for any month of any year. Developed for BASIC 65 with Eleven, you can get &lt;a href=&#34;https://github.com/gcastel/mega65-cal&#34;&gt;the source code from Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=444fb932-a9b9-4a2f-b114-69353e5ffa89&#34;&gt;Xemu keyboard layout reference&lt;/a&gt; for Windows, by Discord user Digger. Windows users, keep this handy app open alongside the Xemu emulator to remember how to replicate MEGA65 keystrokes on the PC keyboard. See also &lt;a href=&#34;https://only8bit.de/xemukeyboard/&#34;&gt;the project homepage&lt;/a&gt; (in German), and the README file (in English) included with the download.&lt;/p&gt;
&lt;h2 id=&#34;mouster-back-in-stock&#34;&gt;mouSTer back in stock&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://retrohax.net/shop/modulesandparts/mouster/&#34;&gt;mouSTer&lt;/a&gt;, the USB-to-Commodore DB9 adapter for modern USB mice and game controllers, is back in stock after a long hiatus. This is one of the best ways to use a modern USB mouse with the MEGA65. It even works with wireless mice that use USB dongles. Get one while you can!&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://retrohax.net/the-mouster-project-20-12-2024-update/&#34;&gt;RetroHax&amp;rsquo;s update from December 30, 2024&lt;/a&gt; for details.&lt;/p&gt;
&lt;h2 id=&#34;digest-administrative-note&#34;&gt;Digest administrative note&lt;/h2&gt;
&lt;p&gt;I am considering migrating the Digest to a new email newsletter service. As Substack evolves their business model and practices, I want to make sure the Digest is hosted on services that remain open and compatible with the values of the MEGA65 project. I&amp;rsquo;ll let everyone know in advance before I make changes.&lt;/p&gt;
&lt;p&gt;The change should be fully automatic, including migrating donations made through the Substack interface as paid subscriptions. Hopefully I can migrate the read-aloud podcast feed URL automatically as well, but this will depend on how your podcast app is subscribed. I&amp;rsquo;ll try to figure it out and let you know. If anyone has any feedback on this change, &lt;a href=&#34;mailto:contact@dansanderson.com&#34;&gt;please let me know&lt;/a&gt;. I know a couple of you are using the Substack app to read it, which should be the only case affected by a migration.&lt;/p&gt;
&lt;p&gt;You can always find all issues of the Digest &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;on my website&lt;/a&gt; and &lt;a href=&#34;https://dansanderson.com/mega65/index.xml&#34;&gt;subscribe to it using an RSS feed reader&lt;/a&gt;. You can also &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;become a patron of the Digest at ko-fi.com/dddaaannn&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;the-art-of-disassembly&#34;&gt;The art of disassembly&lt;/h2&gt;
&lt;p&gt;A quick recap: A computer&amp;rsquo;s CPU performs instructions encoded as bytes in the computer&amp;rsquo;s memory. This machine code is difficult to work with as a list of numbers, so when we humans want to write a program, we use a programming language, and a tool that converts that language to machine code for the computer to execute. Assembly language is a human language that most closely resembles the machine code, with human-readable names for each machine code instruction. The corresponding conversion tool is called an assembler.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a simple assembler built into the MEGA65&amp;rsquo;s machine language monitor. You can start the monitor by entering the &lt;code&gt;MONITOR&lt;/code&gt; command at the READY prompt. Try doing this now, and use the &lt;code&gt;A&lt;/code&gt; command to assemble this short program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MONITOR
A1600 LDA #$01
STA $D020
LDA #$00
STA $D021
RTS&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After the last line, press &lt;kbd&gt;Return&lt;/kbd&gt; on a line by itself to stop the assembler.&lt;/p&gt;
&lt;p&gt;As you type each line, the monitor converts the instruction to the corresponding machine code. It stores the machine code at the requested address in memory, and also prints the address and machine code bytes to the screen, as hexadecimal values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;A 1600  A9 01     LDA  #$01
A 1602  8D 20 D0  STA  $D020
A 1605  A9 00     LDA  #$00
A 1607  8D 21 D0  STA  $D021
A 160A  60        RTS&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The monitor can also reverse this process, to show you which instructions are represented by bytes in memory. This process is known as &lt;em&gt;disassembly.&lt;/em&gt; Use the &lt;code&gt;D&lt;/code&gt; command followed by the address:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;D1600&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sure enough, the program you just entered is right where you put it, at address $1600. There&amp;rsquo;s also a bunch of other stuff after the last instruction you typed starting at address $160B, maybe garbage data or something left behind by another program. These bytes may or may not represent machine code instructions, but the disassembler diligently tries to interpret them as instructions either way. These instructions are what the CPU &lt;em&gt;would&lt;/em&gt; perform if you told it to treat that memory as code.&lt;/p&gt;
&lt;p&gt;The number of bytes used to encode an instruction differs depending on the instruction. Some instructions, like &lt;code&gt;RTS&lt;/code&gt;, are encoded as a single byte. Others, like &lt;code&gt;LDA #$01&lt;/code&gt;, use two bytes. Still others such as &lt;code&gt;STA $D020&lt;/code&gt; require three bytes. Anything trying to interpret bytes as machine code—whether that&amp;rsquo;s a disassembler or the CPU itself—needs to know the address of the first byte of the first instruction, or it could get very confused.&lt;/p&gt;
&lt;p&gt;Try using the disassemble (&lt;code&gt;D&lt;/code&gt;) command again, this time with a starting address of $1601:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;D1601&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The monitor tries to disassemble some of the memory of the program you entered, but the result looks nothing like the program. $1601 is the address of the second byte of the &lt;code&gt;LDA&lt;/code&gt; instruction, $01, which to the disassembler (and the CPU) looks like a version of the &lt;code&gt;ORA&lt;/code&gt; instruction that uses two bytes. At address $1603, the next byte $20 looks like a three-byte &lt;code&gt;JSR&lt;/code&gt; instruction. Coincidentally, the next incorrect instruction gets the disassembler back on track, aligned with the correct first instruction byte at address $1607. But by now, a CPU trying to execute this code will get very lost, and probably crash.&lt;/p&gt;
&lt;p&gt;Disassemblers are not magic, and they need help from the operator—that&amp;rsquo;s you—to convert machine code back into human-readable assembly language. The disassembly process requires research, maybe some guessing and checking, taking notes, and labeling addresses and values once you&amp;rsquo;ve figured out what they mean. A modern disassembly tool can make this process surprisingly easy.&lt;/p&gt;
&lt;h2 id=&#34;introducing-ghidra&#34;&gt;Introducing Ghidra&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/GHIDRA_1.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/GHIDRA_1.png 1497w, https://dansanderson.com/mega65/crossroads-part-2/GHIDRA_1_hu_4c7244334f031e80.png 600w, https://dansanderson.com/mega65/crossroads-part-2/GHIDRA_1_hu_1888c6a4fbb39116.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/GHIDRA_1.png&#34;
        alt=&#34;The logo for the Ghidra reverse engineering tool&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Ghidra logo.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://ghidra-sre.org/&#34;&gt;Ghidra&lt;/a&gt; is a powerful disassembler and reverse engineering multi-tool. It supports many types of CPU machine code, including the 6502, and supports extensions to add more. Ghidra was originally developed by the United States National Security Agency (NSA), and has been released as open source and free of cost.&lt;/p&gt;
&lt;p&gt;I want to credit two YouTube videos on the topic of using Ghidra for reverse engineering Commodore 64 programs: &lt;a href=&#34;https://youtu.be/3wW1una5Pgg?si=48McDKRrIA6kfK1D&#34;&gt;Introduction to Ghidra&lt;/a&gt; by David Youd, and &lt;a href=&#34;https://www.youtube.com/watch?v=xNFswb9CVkg&#34;&gt;How to start a new C64 project in Ghidra&lt;/a&gt; by Jarkko Lehti. These are worth watching when you get a chance, and we&amp;rsquo;ll be using Lehti&amp;rsquo;s configuration files in a moment.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-ghidra&#34;&gt;Setting up Ghidra&lt;/h2&gt;
&lt;p&gt;As of this writing, the latest version of Ghidra is v11.2.1. It&amp;rsquo;s a Java-based application, and it requires a recent version of &lt;a href=&#34;https://www.oracle.com/java/technologies/downloads/&#34;&gt;the Java runtime&lt;/a&gt; (21 or later), which you may need to install or upgrade. Ghidra will tell you if your Java is too old. Properly installed, Windows users can double-click on &lt;code&gt;ghidraRun.bat&lt;/code&gt; to start the program, and macOS and Linux users invoke the &lt;code&gt;ghidraRun&lt;/code&gt; shell script.&lt;/p&gt;
&lt;p&gt;As usual, macOS will refuse to run the scripts and tools until you have blessed them in the Privacy &amp;amp; Security panel. You probably know the drill by now. Attempt to start &lt;code&gt;ghidraRun&lt;/code&gt;, dismiss the complaint, open macOS Settings: Privacy &amp;amp; Security, scroll down, click Open Anyway. If you use Ghidra for other stuff later, you&amp;rsquo;ll need to similarly bless some internal components, which you can do in the Terminal app on the command line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xattr -cr ./Ghidra/Features/FileFormats/os/mac_arm_64/lzfse
xattr -cr ./Ghidra/Features/Decompiler/os/mac_arm_64/decompile
xattr -cr ./Ghidra/Features/Decompiler/os/mac_arm_64/sleigh
xattr -cr ./GPL/DemanglerGnu/os/mac_arm_64/demangler_gnu_v2_*&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you run Ghidra for the first time, it will ask for the path to the Java home directory. This will depend on your operating system. On macOS using Java 23 from Oracle, the path is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/Library/Java/JavaVirtualMachines/jdk-23.jdk/Contents/Home&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ghidra opens its main window, from which you create or select a project, and open tools.&lt;/p&gt;
&lt;h2 id=&#34;creating-the-project&#34;&gt;Creating the project&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_empty_project.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_empty_project.png 912w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_empty_project_hu_68be801713aa1019.png 600w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_empty_project_hu_42a8b3c47c86ff3e.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_empty_project.png&#34;
        alt=&#34;Ghidra&amp;amp;#39;s project window, with no active project&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Ghidra&#39;s project window, with no active project.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Let&amp;rsquo;s start a new project using the &lt;code&gt;crossroads.prg&lt;/code&gt; file that we extracted from the disk image in last month&amp;rsquo;s Digest.&lt;/p&gt;
&lt;p&gt;Create a new project:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the File menu, select New Project.&lt;/li&gt;
&lt;li&gt;Select &amp;ldquo;Non-Shared Project,&amp;rdquo; click Next.&lt;/li&gt;
&lt;li&gt;Create a new folder for the project, and select it. Enter a project name, such as &amp;ldquo;Crossroads.&amp;rdquo; Click Finish. The dialog window closes, and the project is created.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, import the &lt;code&gt;crossroads.prg&lt;/code&gt; file:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the File menu, select Import File.&lt;/li&gt;
&lt;li&gt;Navigate to the file &lt;code&gt;crossroads.prg&lt;/code&gt;, then Select File To Import.&lt;/li&gt;
&lt;li&gt;Leave the Format set to &amp;ldquo;Raw Binary.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Click the &lt;code&gt;...&lt;/code&gt; button next to Language. Select &amp;ldquo;6502,&amp;rdquo; which is at the top of the list for this version of Ghidra. Click OK.&lt;/li&gt;
&lt;li&gt;Leave everything else at default settings, then click OK. Another window opens with some information about the file. Dismiss this with OK.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_import1.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_import1.png 612w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_import1_hu_270b528fabf620ef.png 600w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_import1_hu_153016c01cf6d7af.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_import1.png&#34;
        alt=&#34;The Ghidra file import dialog&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Ghidra file import dialog.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_languageselect.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_languageselect.png 597w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_languageselect_hu_563b57cd1a9deae6.png 600w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_languageselect_hu_d462de3bbf68ac02.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_languageselect.png&#34;
        alt=&#34;The Ghidra language select dialog&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Ghidra language select dialog.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, double-click on the &lt;code&gt;crossroads.prg&lt;/code&gt; file in the project to open it in the CodeBrowser tool. The first time you do this, Ghidra will offer to analyze the file. Say Yes. Leave the default set of analyzers selected, then click Analyze. The analysis doesn&amp;rsquo;t produce spectacular results just yet, but it&amp;rsquo;s usually worth doing.&lt;/p&gt;
&lt;p&gt;Here is &lt;code&gt;crossroads.prg&lt;/code&gt; in all its glory, in the CodeBrowser window. These are the same bytes we saw in the hex dump, but now they&amp;rsquo;re listed one per line. We will use this interface to massage the data as we learn what each part of it means.&lt;/p&gt;
&lt;h2 id=&#34;commenting-the-code&#34;&gt;Commenting the code&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start by telling Ghidra the C64 memory address where this data gets loaded. Because this is a PRG file, it begins with two bytes that are not loaded into memory. We could have gone through an extra step to remove these bytes before importing the data, but for our purposes, it&amp;rsquo;s enough to just take these into account when telling Ghidra where everything lives.&lt;/p&gt;
&lt;p&gt;This data gets loaded into a single block of memory that starts at address $0801. Minus the two PRG header bytes, we can tell Ghidra to start counting addresses at $07FF:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In the Window menu of the CodeBrowser window, select Memory Map. The Memory Map window opens, showing one &amp;ldquo;RAM&amp;rdquo; segment that starts at address &lt;code&gt;0000&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Select the &amp;ldquo;RAM&amp;rdquo; line, then locate the button whose tooltip reads &amp;ldquo;Move a block to another address,&amp;rdquo; a blue arrow-cross icon.&lt;/li&gt;
&lt;li&gt;For the New Start Address, type &lt;code&gt;07ff&lt;/code&gt;. Click OK.&lt;/li&gt;
&lt;li&gt;Close the Memory Map window.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_moveblock.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_moveblock.png&#34;
            width=&#34;250&#34;
            height=&#34;84&#34;
            alt=&#34;The Memory Map toolbar, with the blue cross button: Move a block to another address&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Memory Map toolbar, with the blue cross button: Move a block to another address
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Notice that the data is now lined up with the memory addresses. The first byte of the BASIC bootstrap is at $0801, and the two-byte end-of-BASIC terminator is at $080B. (We peeked at this in &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/&#34;&gt;the previous Digest&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s add a comment describing this data. Right-click on the line for $0801 to open the context menu. Select Comments &amp;gt; Set EOL Comment&amp;hellip; In the window that opens, type a useful description, such as: &amp;ldquo;Start of BASIC bootstrap.&amp;rdquo; You may wish to add a similar comment on $080C, for &amp;ldquo;End of BASIC bootstrap.&amp;rdquo;&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_bytes1.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_bytes1.png 748w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_bytes1_hu_333c5017622a0591.png 600w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_bytes1_hu_a1009203ddff705b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_bytes1.png&#34;
        alt=&#34;The BASIC bootstrap of Crossroads, aligned and commented&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The BASIC bootstrap of Crossroads, aligned and commented.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;initiating-disassembly&#34;&gt;Initiating disassembly&lt;/h2&gt;
&lt;p&gt;The BASIC bootstrap uses the &lt;code&gt;SYS&lt;/code&gt; command to invoke machine code starting at decimal address 2300. Ghidra even shows the &amp;ldquo;2300&amp;rdquo; characters next to the byte listing, guessing that we might be interested in what these look like as ASCII characters. In hexadecimal, this address is $08FC.&lt;/p&gt;
&lt;p&gt;Navigate to this address in the byte listing. Here&amp;rsquo;s a quick way: press &amp;ldquo;G&amp;rdquo; (for &amp;ldquo;go&amp;rdquo;), then enter the address in hexadecimal (&lt;code&gt;08fc&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Start the disassembly at this address: press &amp;ldquo;D&amp;rdquo; (for &amp;ldquo;disassemble&amp;rdquo;).&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_init08fc_1.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_init08fc_1.png 736w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_init08fc_1_hu_2fe15fa105256c33.png 600w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_init08fc_1_hu_a3d063d327bdaa18.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_init08fc_1.png&#34;
        alt=&#34;Our first disassembly, starting at $08fc&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Our first disassembly, starting at $08fc.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Ghidra has just done a bunch of work for us! It took our word for it that the bytes starting at $08fc are machine code: $a9 $ff represent the &lt;code&gt;LDA #$ff&lt;/code&gt; instruction, which Ghidra spells &lt;code&gt;LDA #0xff&lt;/code&gt;, and updated the code listing accordingly. It proceeded to the next instruction, and kept going as long as it was reasonably certain that the CPU would treat those bytes as instructions as it executed.&lt;/p&gt;
&lt;p&gt;Scroll down, and notice that Ghidra stopped disassembly at address $0cab, where it found an &lt;code&gt;RTS&lt;/code&gt; instruction. The bytes starting at $0cac may be more CPU instructions, but Ghidra doesn&amp;rsquo;t know this for sure. In fact, we can see evidence that it may be data and not instructions: the bytes from $0cb1 to $0cba spell out &amp;ldquo;CROSSROADS&amp;rdquo; in ASCII. Ghidra doesn&amp;rsquo;t know this is more likely to be PETSCII and not ASCII, but it displays the ASCII letters for our benefit, just in case.&lt;/p&gt;
&lt;p&gt;Keep scrolling, down to $0dc5. Ghidra found more code! Starting with the first address we gave it, Ghidra decoded each instruction, and when it found a branching instruction or subroutine call, it continued disassembly at that location, filling everything in. It assigned some temporary labels for things that look like functions, such as &lt;code&gt;FUN_0dc5&lt;/code&gt;. As we try to understand what the program does, we can replace these labels with more intuitive names. In the end, we&amp;rsquo;ll have a fully human-readable assembly language program. (Or as human readable as assembly language gets, anyway.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_func0dc5_1.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_func0dc5_1.png 717w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_func0dc5_1_hu_27191bbbf82f90a.png 600w, https://dansanderson.com/mega65/crossroads-part-2/ghidra_func0dc5_1_hu_728eea20e2bfce0e.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_func0dc5_1.png&#34;
        alt=&#34;Ghidra found what might be a function definition at $0dc5&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Ghidra found what might be a function definition at $0dc5.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Ghidra made similar attempts to highlight data locations referenced in the code, assigning labels such as &lt;code&gt;DAT_08b0&lt;/code&gt;. Everything referenced by something else is annotated with the cross references. For example, the byte at address $08b0 is read by an instruction at address $0a7a, so it lists &lt;code&gt;0a7a(R)&lt;/code&gt; (&amp;ldquo;R&amp;rdquo; for &amp;ldquo;read&amp;rdquo;) next to $08b0.&lt;/p&gt;
&lt;p&gt;We can add our own labels. Let&amp;rsquo;s do this for our entry point, $08fc:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Press &amp;ldquo;G&amp;rdquo; for go. Enter &lt;code&gt;08fc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Press &amp;ldquo;L&amp;rdquo; for label. Enter a label name of &lt;code&gt;start&lt;/code&gt;. Because this is the entry point of the program, select the &amp;ldquo;Entry Point&amp;rdquo; property. Click OK.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;importing-c64-symbols&#34;&gt;Importing C64 symbols&lt;/h2&gt;
&lt;p&gt;Ghidra has invented labels for all of the data and code referenced by the disassembled code. The addresses within the imported data range have blue labels and cross references.&lt;/p&gt;
&lt;p&gt;Where the code references an address not in the imported range, Ghidra also generated a label, and colored it red. Consider the first few instructions of the program, starting at $08fc:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LDA #0xff
STA DAT_d40e
STA DAT_d40f&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This loads $ff into the accumulator, and stores that value to addresses $d40e and $d40f. If these were just memory locations, we would assume that these are variables used by the game for storing game state, like the player&amp;rsquo;s position. In this case, we can apply some knowledge of how the Commodore 64 works: addresses in the range $d000-$dfff are input-output registers that control, or are controlled by, the computer&amp;rsquo;s hardware. We can look up what these registers do in &lt;a href=&#34;https://sta.c64.org/cbm64mem.html&#34;&gt;a Commodore 64 technical reference&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this case, these registers belong to the SID sound chip, specifically the frequency of the oscillator on voice #3. We don&amp;rsquo;t yet know why the program does this, but we do know that&amp;rsquo;s what it does. The next two instructions and a bit more knowledge of C64 programming gives us a hint:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LDA #0x80
STA DAT_d412&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The technical reference says $d412 is the SID voice #3 control register. Setting bit 7 like this tells it to use the &amp;ldquo;noise&amp;rdquo; waveform. &lt;em&gt;Crossroads&lt;/em&gt; is certainly a noisy game, but it&amp;rsquo;s probably setting this up to use as a random number generator, or at least a seed for one. We&amp;rsquo;ll have to keep our eye out for something that samples a value from voice #3.&lt;/p&gt;
&lt;p&gt;Now that we&amp;rsquo;ve identified &lt;code&gt;DAT_d40e&lt;/code&gt; et al., we could update the labels to something that describes their functions. To do this, you would right-click on the label and select Edit Label&amp;hellip; (or move the cursor onto the label and press &amp;ldquo;L&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Considering that the C64 I/O registers always do the same thing in every program, it would be nice if Ghidra could automatically recognize all of them and give them useful names. The following is one way to do this, based on &lt;a href=&#34;https://voidhole.com/~grue/ghidra/c64_symbols/&#34;&gt;the files supplied by Jarkko Lehti&lt;/a&gt; to accompany &lt;a href=&#34;https://www.youtube.com/watch?v=xNFswb9CVkg&#34;&gt;his YouTube video&lt;/a&gt; on the subject.&lt;/p&gt;
&lt;p&gt;Download these C64 symbol files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/IO.txt&#34;&gt;IO.txt&lt;/a&gt;: the I/O registers&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/KERNAL.txt&#34;&gt;KERNAL.txt&lt;/a&gt;: the KERNAL jump table subroutines&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/RAM.txt&#34;&gt;RAM.txt&lt;/a&gt;: commonly used C64 internal KERNAL variables&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/IO_d000.bin&#34;&gt;IO_d000.bin&lt;/a&gt;: a binary snapshot of the initial values of C64 I/O registers&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/kernal_e000.bin&#34;&gt;kernal_e000.bin&lt;/a&gt;: a binary snapshot of the C64 KERNAL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;.txt&lt;/code&gt; files tell Ghidra to apply certain labels to certain addresses when they appear in the code. The &lt;code&gt;.bin&lt;/code&gt; files fill in the memory ranges themselves in the Ghidra project, so you can get some idea of what&amp;rsquo;s actually there in the C64&amp;rsquo;s memory.&lt;/p&gt;
&lt;p&gt;In your project, the &lt;code&gt;IO&lt;/code&gt; and &lt;code&gt;KERNAL&lt;/code&gt; data will exist as &lt;em&gt;overlays&lt;/em&gt;. An overlay is a portion of memory that may contain different things at different times, based on system state. With the Commodore 64, I/O registers and KERNAL ROM occupy addresses that can also refer to RAM, based on the memory banking register. Ghidra can only see that an instruction accesses an address, not the memory map of the computer at the time the instruction is called. Telling Ghidra that these memory regions are overlays accounts for the possibility that a given reference to an address may refer either to I/O and ROM, or the underlying RAM.&lt;/p&gt;
&lt;p&gt;To create the &lt;code&gt;IO&lt;/code&gt; overlay:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;From the CodeBrowser window, open the File menu, Add To Program&amp;hellip;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;IO_d000.bin&lt;/code&gt;, click Add To Program.&lt;/li&gt;
&lt;li&gt;In the Add To Program dialog, click Options&amp;hellip; Select Overlay, use a Block Name of &lt;code&gt;IO&lt;/code&gt;, and set the Base Address to &lt;code&gt;d000&lt;/code&gt;. Click OK in the Options dialog, then click OK in the Add To Program dialog. Dismiss the Import Results window.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To create the &lt;code&gt;KERNAL&lt;/code&gt; overlay, repeat these steps with the &lt;code&gt;kernal_e000.bin&lt;/code&gt; file, using a Block Name of &lt;code&gt;KERNAL&lt;/code&gt; and a Base Address of &lt;code&gt;e000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now we can import the symbols that describe addresses in these regions. Ghidra is a highly scriptable application environment, and we can use a script that comes with Ghidra to import the &lt;code&gt;.txt&lt;/code&gt; symbols files.&lt;/p&gt;
&lt;p&gt;To import the symbols:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;From the Window menu, select Script Manager.&lt;/li&gt;
&lt;li&gt;Scroll down to find &lt;code&gt;ImportSymbolsScript.py&lt;/code&gt;. Double-click it to run it.&lt;/li&gt;
&lt;li&gt;When prompted, select the &lt;code&gt;IO.txt&lt;/code&gt; file. Click &amp;ldquo;Go baby go!&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Repeat these steps for the &lt;code&gt;KERNAL.txt&lt;/code&gt; file, and again for the &lt;code&gt;RAM.txt&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ghidra now knows about the I/O registers via an overlay with sensibly named symbols. Ghidra still doesn&amp;rsquo;t know which references refer to RAM and which refer to I/O. We have to tell it.&lt;/p&gt;
&lt;p&gt;Go (&amp;ldquo;G&amp;rdquo;) back to the &lt;code&gt;STA&lt;/code&gt; instruction at $08fe. Its destination is still the red symbol &lt;code&gt;DAT_d40e&lt;/code&gt;. Click on it, then press &amp;ldquo;R&amp;rdquo; to edit the reference. In the pop-up window, double-click the reference, then change the dropdown menu that says &amp;ldquo;RAM:&amp;rdquo; to &amp;ldquo;IO:&amp;rdquo;. Click Update, and close the reference editor. The symbol has changed to &lt;code&gt;D40E_FRQ_3_LO&lt;/code&gt;. That&amp;rsquo;s&amp;hellip; better.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_init08fc_2.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_init08fc_2.png&#34;
            width=&#34;399&#34;
            height=&#34;208&#34;
            alt=&#34;Code near the entry point with I/O registers labeled&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Code near the entry point with I/O registers labeled.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s unusual for a C64 game to un-bank the I/O registers, so it&amp;rsquo;s a little inconvenient that each label needs to be applied like this. I haven&amp;rsquo;t found a good way to automatically declare all references to be for the &lt;code&gt;IO&lt;/code&gt; overlay. One possibility might be to add &lt;code&gt;IO_d000.bin&lt;/code&gt; as a non-overlay region, then edit the &lt;code&gt;IO.txt&lt;/code&gt; symbols file to remove the &lt;code&gt;IO::&lt;/code&gt; part of each address. For now, I like keeping &lt;code&gt;IO&lt;/code&gt; as an overlay, because it accurately describes how the C64 works.&lt;/p&gt;
&lt;p&gt;I did find a reasonably fast way to update all of the labels manually using Ghidra&amp;rsquo;s search feature. In the Search menu, select Program Text&amp;hellip; Prepare a search for &lt;code&gt;DAT_d&lt;/code&gt; in All Fields of the Listing Display, and click Search All. A window opens with the search results, and clicking on a result causes the Listing display to jump to that location. I got 38 results, and it only took me a few minutes to update all of the references to use the &lt;code&gt;IO&lt;/code&gt; labels. It&amp;rsquo;s not the most fun I&amp;rsquo;ve ever had with a computer, but it didn&amp;rsquo;t take so long that I regretted not automating it.&lt;/p&gt;
&lt;h2 id=&#34;getting-some-answers&#34;&gt;Getting some answers&lt;/h2&gt;
&lt;p&gt;Now that we have at least some idea of what we&amp;rsquo;re looking at, let&amp;rsquo;s try to answer a few questions that will help us understand how &lt;em&gt;Crossroads&lt;/em&gt; works. These are just questions that occurred to me, in the order I thought to ask them. They may not be the best questions, or in the best order. But let&amp;rsquo;s see what happens.&lt;/p&gt;
&lt;h3 id=&#34;does-the-program-call-the-kernal-jump-table&#34;&gt;Does the program call the KERNAL jump table?&lt;/h3&gt;
&lt;p&gt;This is an easy one. A call to the KERNAL jump table would look like a &lt;code&gt;JSR&lt;/code&gt; to a hexadecimal address beginning with an &lt;code&gt;f&lt;/code&gt;. Ghidra will have generated a label like &lt;code&gt;FUN_ffd2&lt;/code&gt; prior to me updating it to use the &lt;code&gt;KERNAL&lt;/code&gt; overlay&amp;rsquo;s symbols, so just like we used a search of &lt;code&gt;DAT_d&lt;/code&gt; to find I/O register references, we can search for &lt;code&gt;FUN_f&lt;/code&gt; to find calls to KERNAL routines. I get no results from this search, so I&amp;rsquo;m fairly confident that &lt;em&gt;Crossroads&lt;/em&gt; does not call KERNAL routines. Alas, we don&amp;rsquo;t get to use our &lt;code&gt;KERNAL&lt;/code&gt; overlay. Maybe next time.&lt;/p&gt;
&lt;h3 id=&#34;does-the-program-use-kernal-vectors&#34;&gt;Does the program use KERNAL vectors?&lt;/h3&gt;
&lt;p&gt;As we&amp;rsquo;ve discussed in previous issues of the Digest, most games drive their game loop using &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/&#34;&gt;CPU interrupts&lt;/a&gt;. There are two ways to set up an interrupt handler: replace the KERNAL&amp;rsquo;s interrupt handlers in $fffa-$ffff, or use a &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/&#34;&gt;KERNAL vector&lt;/a&gt; to add a custom subroutine to the KERNAL&amp;rsquo;s interrupt handler. Let&amp;rsquo;s check the latter option first, because it&amp;rsquo;s more common for simple C64 games.&lt;/p&gt;
&lt;p&gt;The designers of the Commodore ROM wanted people to use the VECTOR KERNAL call to read and update the KERNAL vector table, and that&amp;rsquo;s still a best practice for MEGA65 programs. Even early on, C64 programmers skipped over that part of the manual, and just wrote to the C64 vector table at $0314-$0333. We can search for the string &lt;code&gt;0314&lt;/code&gt; to find any direct references to the IRQ vector.&lt;/p&gt;
&lt;p&gt;Yup, there it is. The instructions at $0ba8-$0bb1 are writing address $11c4 to the KERNAL IRQ vector $0314-$0315.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LDA #0xc4
STA 0314_IRQ_VECTOR_LO
LDA #0x11
STA 0315_IRQ_VECTOR_HI&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This appears to be the only vector touched, and it is only set in this one location in the code that Ghidra has disassembled. Let&amp;rsquo;s go to the address being written to the vector and check it out: &amp;ldquo;G&amp;rdquo;, then &lt;code&gt;11c4&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Hoo boy, Ghidra hasn&amp;rsquo;t disassembled this yet! This is because the main routine, which sets up the game and installs the IRQ vector, doesn&amp;rsquo;t actually call the IRQ handler directly. We have a bit more work to do. Press &amp;ldquo;D&amp;rdquo; to start disassembly from this address. Also, press &amp;ldquo;L&amp;rdquo; to add an entry point label, with a name such as &lt;code&gt;irq&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll have to re-do our searches for I/O register labels and KERNAL calls now that we have more disassembled code. That&amp;rsquo;s just how it goes. I found 8 more I/O registers, but still no KERNAL calls.&lt;/p&gt;
&lt;h3 id=&#34;does-the-program-do-any-c64-cpu-bank-switching&#34;&gt;Does the program do any C64 CPU bank switching?&lt;/h3&gt;
&lt;p&gt;I mentioned that most games leave I/O registers banked to $d000-$dfff, the initial state of the C64. We can double-check that by looking for references to &lt;a href=&#34;https://www.c64-wiki.com/wiki/Bank_Switching&#34;&gt;the C64 bank switching register&lt;/a&gt;, address $0001.&lt;/p&gt;
&lt;p&gt;A search for &lt;code&gt;DAT_0001&lt;/code&gt; does produce two results in the start-up routine, so it&amp;rsquo;s worth taking a closer look. Starting at address $09f9, the routine sets this to $73, or binary %01110011. According to C64 technical documentation, this setting makes sure the C64 character ROM—the graphics data for the PETSCII font—is visible at $d000-$dfff instead of the I/O registers. It&amp;rsquo;s not that way for long, though. Just below, at address $0a10, the banking register gets set to $77, or binary %01110111, which switches the I/O registers back in.&lt;/p&gt;
&lt;p&gt;While the character ROM is visible, a short loop copies the first 472 bytes of PETSCII graphics data to address $2000.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;	LDX #0x0
LAB_09ff:
	LDA DAT_d000,X
	STA 0x2000,X
	LDA DAT_d0ec,X
	STA 0x20ec,X
	INX
	CPX #0xec
	BNE LAB_09ff&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we know what this does, we can rename the &lt;code&gt;LAB_09ff&lt;/code&gt; label to something like &lt;code&gt;copy_char_loop&lt;/code&gt;, and add explanatory comments to the bank switching instructions. We can also relabel &lt;code&gt;DAT_0001&lt;/code&gt; while we&amp;rsquo;re at it.&lt;/p&gt;
&lt;h3 id=&#34;does-the-program-use-any-self-modifying-code&#34;&gt;Does the program use any self-modifying code?&lt;/h3&gt;
&lt;p&gt;From our perspective as reverse engineers, one of the scariest things a program can do is modify its own code. The program is entirely within its right to do this—code is just data in memory—but it means that the disassembler may not be seeing the code in the form it is executed.&lt;/p&gt;
&lt;p&gt;To find places where the program might be modifying itself, we have to look for attempts to store values in locations that Ghidra believes are inside subroutine code. I bet there&amp;rsquo;s a way to get Ghidra to make a list of such places, but I haven&amp;rsquo;t found one yet. I did notice, however, that Ghidra refers to such addresses by the name of the function, plus an offset, like this example near the entry point:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LDA #0x0
STA FUN_0b4a+1
LDA #0x28
STA FUN_0b4a+2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These address expressions appear in a grey color. From visual inspection, I found only a few examples of this. Thankfully, they were all short subroutines that were easy to understand, and all of the self-modifications were to addresses for &lt;code&gt;LDA&lt;/code&gt; and &lt;code&gt;STA&lt;/code&gt; instructions.&lt;/p&gt;
&lt;p&gt;Several of these appear to be simple utility functions for using addresses from variables together with indirect addressing. For example, &lt;code&gt;FUN_0b4a&lt;/code&gt; is simply the &lt;code&gt;STA&lt;/code&gt; instruction in absolute Y-indexed addressing mode, followed by an &lt;code&gt;RTS&lt;/code&gt;. To use this routine, the program writes an address into the &lt;code&gt;STA&lt;/code&gt; instruction, sets the A and Y CPU registers, then calls the subroutine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FUN_0b4a
  STA 0x0000,Y
  RTS&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This probably saved the developer some headache, using a single self-modifying mechanism instead of having every subroutine modify its own instructions. The initialization routine near the entry point uses this mechanism as part of a loop to fill some memory with zeroes.&lt;/p&gt;
&lt;h3 id=&#34;is-there-any-more-code&#34;&gt;Is there any more code?&lt;/h3&gt;
&lt;p&gt;We found the entry point and the IRQ vector routine, and we identified self-modifying code and confirmed that it&amp;rsquo;s not doing something crazy like dynamically writing &lt;code&gt;JMP&lt;/code&gt; instructions to memory at run time. It looks like Ghidra has found most of the code in the program. Are we safe to conclude that the remaining unidentified regions are static data, or perhaps initialized variable space?&lt;/p&gt;
&lt;p&gt;This requires a bit of judgement, a bit of guesswork, and a willingness to change our minds later, but we can start to form some conclusions from a visual inspection of Ghidra&amp;rsquo;s analysis. Here&amp;rsquo;s what I see so far:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$080d-$08fb: I see some repeating numeric patterns that are unlikely to be instructions. Ghidra found cross-references into this memory starting at $08b0, and they&amp;rsquo;re all read-only references from the initialization routine. The program must refer to some of this data with dynamically calculated addresses that Ghidra can&amp;rsquo;t see. It&amp;rsquo;s not conclusive, but with no obvious writes to this memory, this is probably static data, such as graphics patterns.&lt;/li&gt;
&lt;li&gt;$0cac-$0dc4: Ghidra is displaying obvious patterns in the ASCII decoding that match text displayed on the game&amp;rsquo;s screen, with strings such as &amp;ldquo;CROSSROADS&amp;rdquo; and &amp;ldquo;1PLAYER,&amp;rdquo; and many space characters ($20). There are only a few explicit read-only references. This is probably character data for the static parts of the display.&lt;/li&gt;
&lt;li&gt;$0f65-$11c3 and $15fe-$1693: These are less obvious to me just from staring at them. Some of it is clearly data, but I don&amp;rsquo;t yet know how to interpret patches of it. Once again, there are no explicit instructions writing to these areas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For now at least, I feel confident that these regions are static data and not code, and that Ghidra has found all of the code in the program.&lt;/p&gt;
&lt;h3 id=&#34;whats-in-the-data&#34;&gt;What&amp;rsquo;s in the data?&lt;/h3&gt;
&lt;p&gt;We can learn more about the suspected data regions by double-clicking on the cross-references and digging around the code that refers to them. We can also make some guesses about how the data is encoded, and try to decode it to see if we recognize any patterns, similar to how we identified text strings with Ghidra&amp;rsquo;s built-in ASCII decoding.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m especially interested to find the character graphics data that gives &lt;em&gt;Crossroads&lt;/em&gt; its special flair. This is likely to take the form of monochrome character pixel data, where each byte represents a row of 8 pixels, and consecutive bytes are stacked, usually in a square of 8 rows. If we visualized the bytes in suspicious data regions this way, would the &lt;em&gt;Crossroads&lt;/em&gt; cast of characters jump out at us?&lt;/p&gt;
&lt;p&gt;Ghidra has extensive features for visualizing data structures. Once we have a guess as to how data should be interpreted, we can paint data types onto the bytes and see if they make sense. For example, to visualize a byte as a binary number:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Locate address $080f. The byte value is $44. Ghidra doesn&amp;rsquo;t know how to interpret this, so it displays a type of &lt;code&gt;??&lt;/code&gt;, its hex value, and its ASCII value.&lt;/li&gt;
&lt;li&gt;Right-click on it to open the context menu, navigate to Data, and select the &lt;code&gt;byte&lt;/code&gt; type. Ghidra updates &lt;code&gt;??&lt;/code&gt; to &lt;code&gt;db&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Right-click again, navigate to Data, and now select the Settings&amp;hellip; option that has appeared now that the value has a type. Change Format to &amp;ldquo;binary&amp;rdquo; and Padding to &amp;ldquo;padded.&amp;rdquo; Click OK. Ghidra updates the visualization to a padded binary value: &lt;code&gt;01000100b&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_datatype.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/crossroads-part-2/ghidra_datatype.png&#34;
            width=&#34;536&#34;
            height=&#34;356&#34;
            alt=&#34;The Data Settings dialog&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Data Settings dialog, as it appears on macOS.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Let&amp;rsquo;s try this for a chunk of the data region $080d-$08f9. (We can always undo it later.) Click-drag with the mouse, or move the cursor to the first line and hold Shift while cursoring down, to select lines. Use the Data context menu to make them all bytes displayed as padded binary.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;083d ff    db    11111111b    ; ########
083e 8f    db    10001111b    ; #   ####
083f ff    db    11111111b    ; ########
0840 3c    db    00111100b    ;   ####
0841 7e    db    01111110b    ;  ######
0842 7e    db    01111110b    ;  ######
0843 ee    db    11101110b    ; ### ###
0844 87    db    10000111b    ; #    ###&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&amp;rsquo;s a little difficult to make out when displayed as 0&amp;rsquo;s and 1&amp;rsquo;s, but I see some familiar faces. Going eight bytes at a time, I see two frames of animation for each of an enemy missile ($080d), a bullet ($081d), the Human/player ($082d), the Purple Rubberhead ($083d), and more. I have to squint to see the rest, but if each of the nine enemies gets 16 bytes starting at $083d, it feels safe to say these are graphics tiles up to at least $08cd.&lt;/p&gt;
&lt;h3 id=&#34;how-does-the-program-set-up-character-graphics-data&#34;&gt;How does the program set up character graphics data?&lt;/h3&gt;
&lt;p&gt;We have a rough idea that the game keeps its graphics assets starting at $080d, and establishes its custom character font at $2000 with some combination of this data and PETSCII characters from character ROM. We&amp;rsquo;ve already found where the set-up routine ($08fc) copies the character ROM to $2000. What else does it do?&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s relatively easy to see that a big chunk of the set-up routine is messing around in the $2000 memory region. Starting from the beginning, it sets a few registers, then immediately dives into the work of rendering the character data, with various loops and &lt;code&gt;STA&lt;/code&gt; instructions indexing into this memory.&lt;/p&gt;
&lt;p&gt;The characters of &lt;em&gt;Crossroads&lt;/em&gt; walk in four directions, with two frames of animation. We only found two frames of animation in the graphics data, with the characters facing to the right. Can you guess where it gets the graphics for the other three directions?&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-2/rubberhead1.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/crossroads-part-2/rubberhead1.png&#34;
            width=&#34;570&#34;
            height=&#34;80&#34;
            alt=&#34;The Purple Rubberhead character set, rendered from two 8x8 frames&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Purple Rubberhead character set, rendered from two 8x8 frames.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To achieve the full effect, the set-up loop takes the 8x8 right-facing creature graphics and writes it into character graphics memory. Then it flips each byte horizontally and writes the left-facing copy. Then it rotates it 90 degrees one way for up-facing, and 90 degrees the other way for down-facing.&lt;/p&gt;
&lt;p&gt;Moreover, the second step of each character&amp;rsquo;s animation is drawn across &lt;em&gt;two&lt;/em&gt; character tiles, for that slick grid-breaking animation. The creature takes up two characters on the 40x25 screen for this half step, and no other creature or item is allowed in either tile at this moment. The set-up routine renders these half-steps dynamically from the 8x8 pixel data, using bit shifting instructions to produce half-tile images. I see groups of four bit shifting instructions at $0a5d and $0a6d that might be involved in this process.&lt;/p&gt;
&lt;p&gt;Just after setting up the character data at $2000, the program sets VIC register $d018 to $18. This establishes how the VIC uses memory, and indeed, it sets the character memory pointer to $2000. It also sets the screen memory location to $0400. The VIC-II can only see 16 KB of the address space at a time, and which 16 KB is selected by a register at $dd00. &lt;em&gt;Crossroads&lt;/em&gt; does not appear to change this register from its default setting.&lt;/p&gt;
&lt;h2 id=&#34;future-possibilities-with-ghidra&#34;&gt;Future possibilities with Ghidra&lt;/h2&gt;
&lt;p&gt;That&amp;rsquo;s a good start, and plenty for a single newsletter. Ghidra is a very powerful tool and I&amp;rsquo;m still learning about all it can do.&lt;/p&gt;
&lt;p&gt;Ghidra is highly extensible, and there is substantial potential for extensions and scripts to support C64 and MEGA65 development and reverse engineering. In &lt;a href=&#34;https://www.youtube.com/watch?v=xNFswb9CVkg&#34;&gt;his video&lt;/a&gt;, Jarkko Lehti is using &lt;a href=&#34;https://github.com/grue74/ghidra-c64helpers&#34;&gt;his own Ghidra fork&lt;/a&gt; with a few nice features such as PETSCII string visualization.&lt;/p&gt;
&lt;p&gt;When I was squinting at the character set data, I was wishing for a bit of tool support for visualizing bitfields as graphics, much like how Retro Debugger lets you view memory contents in different ways. I wonder if Ghidra can do custom inline data visualizers like this, or if a feature like this is already available.&lt;/p&gt;
&lt;p&gt;The annotated disassembly can be exported in multiple formats, but none of them resemble something that could be re-assembled by a tool such as Acme assembler. A custom export tool or post-processing script would be handy for that, and would be easy to write.&lt;/p&gt;
&lt;p&gt;Of course, the thought naturally occurs to someday use Ghidra to disassemble MEGA65 machine code programs. It&amp;rsquo;d take some effort, but it is possible to write an extension to provide 45GS02 CPU support to the disassembler. Ghidra has an entire language for specifying new processors called &lt;a href=&#34;https://spinsel.dev/assets/2020-06-17-ghidra-brainfuck-processor-1/ghidra_docs/language_spec/html/sleigh.html&#34;&gt;SLEIGH&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;d also be good to generate symbols files and overlays for all of the MEGA65&amp;rsquo;s I/O register personalities. &lt;a href=&#34;https://github.com/dansanderson/mega65-symbols&#34;&gt;I already have symbol generator scripts&lt;/a&gt; that could be tweaked to produce something that Ghidra can import.&lt;/p&gt;
&lt;p&gt;In practice, most MEGA65 machine code programs that exist today have friendly authors that have open sourced their code. It&amp;rsquo;s still fun to think about.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I chose &lt;em&gt;Crossroads&lt;/em&gt; for this demonstration for a few reasons. For one, it really was one of my favorite games, so I was excited to play with it. But also, I had a suspicion that its internals were straightforward enough to understand through disassembly. As fast and seamless as &lt;em&gt;Crossroads&lt;/em&gt; is to play, you only need to know a few things about C64 programming to start to make guesses about how it works just from looking at it.&lt;/p&gt;
&lt;p&gt;Many C64 games and demos use data compression techniques to limit disk space and loading times. This can make disassembly more difficult, because you can&amp;rsquo;t just load the PRG into Ghidra directly. One possible technique is to run the program in Retro Debugger, let it decompress everything into memory, then take a snapshot of the memory of the running program. You can then apply disassembly techniques to the snapshot. I suspected that &lt;em&gt;Crossroads&lt;/em&gt; did not use compression for code, and felt comfortable just loading the PRG file directly into Ghidra.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in writing programs for the MEGA65, it&amp;rsquo;s worth studying C64 programs. The Commodore 65 was designed as a true technological successor to the C64, and many C64 programming techniques apply to C65 and MEGA65 programs. The original source code for many C64 programs have been lost to time, but we can use tools like Retro Debugger and Ghidra to pull them apart and reconstruct their secrets.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s one more tool that we can use to reverse engineer C64 programs—and it&amp;rsquo;s sitting right beside you. The MEGA65 can run many C64 programs in its GO64 mode, and you can use the MEGA65 core&amp;rsquo;s serial debugger, along with a powerful frontend like &lt;a href=&#34;https://github.com/MEGA65/m65dbg&#34;&gt;m65dbg&lt;/a&gt;, to analyze a running program. We&amp;rsquo;ll have to revisit this in a future Digest.&lt;/p&gt;
&lt;p&gt;Onward into the new year!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/crossroads-part-2/M65Digest_2025Jan.mp3" length="62005206" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>3100</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/crossroads-part-2/crossroads_creatures.png"/>
      
    </item>
    
    <item>
      <title>Santa&#39;s Souped-Up MEGA65</title>
      <link>https://dansanderson.com/mega65/santas-souped-up-mega65/</link>
      <pubDate>Thu, 12 Dec 2024 16:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/santas-souped-up-mega65/</guid>
      <description>&lt;p&gt;Santa&amp;rsquo;s Souped-Up MEGA65. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for December 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Santa&amp;rsquo;s Souped-Up MEGA65. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for December 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/M65Digest_2024Dec.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/M65Digest_2024Dec.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Santa&#39;s Souped-Up MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/santasxmascaper.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/santasxmascaper.png 296w, https://dansanderson.com/mega65/santas-souped-up-mega65/santasxmascaper_hu_c00740e5c4a85937.png 600w, https://dansanderson.com/mega65/santas-souped-up-mega65/santasxmascaper_hu_7039c392ccff0bff.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/santasxmascaper.png&#34;
        alt=&#34;Santa Claus, sleigh, and reindeer, clipped from Santa&amp;amp;#39;s Xmas Caper (1990) for the Commodore 64 by Zeppelin Games&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Santa&#39;s Xmas Caper (1990) for the Commodore 64, by Zeppelin Games.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Hey everyone! I hope you&amp;rsquo;re all ready for some end-of-the-year relaxation, maybe some time off work, spent with family, in whatever temperature extreme you&amp;rsquo;re experiencing in your hemisphere. I also hope you&amp;rsquo;ll get some time to play with your MEGA65, because you&amp;rsquo;re gonna need it!&lt;/p&gt;
&lt;p&gt;There are so many project announcements this month that I&amp;rsquo;ve decided to dedicate this entire issue to new downloads, to celebrate everyone&amp;rsquo;s talent and enthusiasm, and to give thanks for our wonderful community. We will finish our &lt;em&gt;Crossroads&lt;/em&gt; disassembly project in January.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;sidplay65&#34;&gt;SidPlay65&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/sidplay65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/sidplay65.png 1032w, https://dansanderson.com/mega65/santas-souped-up-mega65/sidplay65_hu_bd5d5bbf91d521d4.png 600w, https://dansanderson.com/mega65/santas-souped-up-mega65/sidplay65_hu_1a190e6a61446e39.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/sidplay65.png&#34;
        alt=&#34;SidPlay65 by LightTangent&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;SidPlay65 by LightTangent.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There&amp;rsquo;s a new way to make music with your MEGA65, thanks to MEGA65 developer LightTangent! &lt;a href=&#34;https://files.mega65.org?id=04708d59-c6d0-4319-9728-b0dba44a878a&#34;&gt;SidPlay65&lt;/a&gt; is a MEGA65 program that re-implements the &lt;a href=&#34;https://sidplayer.org/&#34;&gt;SIDPlayer music system&lt;/a&gt; from Compute! Publishing. It plays single-SID and dual-SID songs, and supports some advanced SIDPlayer format features like colorful PETSCII banner displays and karaoke lyrics.&lt;/p&gt;
&lt;p&gt;SIDPlayer was one of several major tentpole products for the Commodore 64 from Compute!,along with &lt;em&gt;Crossroads&lt;/em&gt; and the hit word processing package &lt;em&gt;SpeedScript&lt;/em&gt;. The initial version of SIDPlayer appeared as a type-in in the book &lt;a href=&#34;https://archive.org/details/All_About_the_Commodore_64_Volume_Two_1985_COMPUTE_Publications&#34;&gt;&lt;em&gt;All About the Commodore 64, Volume Two&lt;/em&gt;&lt;/a&gt; by Craig Chamberlain. It included rudimentary music editing software, and a player routine that could be embedded in your BASIC or machine language programs. Chamberlain revised the system and published the Enhanced SIDPlayer in the book &lt;a href=&#34;https://archive.org/details/Computes_Music_System_for_the_Commodore_128_and_64&#34;&gt;&lt;em&gt;COMPUTE!&amp;rsquo;s Music System for the Commodore 128 &amp;amp; 64&lt;/em&gt;&lt;/a&gt;, this time with a companion floppy disk instead of type-in code.&lt;/p&gt;
&lt;p&gt;The SIDPlayer system was a huge hit in the United States, and C64 owners produced thousands of songs and shared them on online services like &lt;a href=&#34;https://en.wikipedia.org/wiki/Delphi_(online_service)&#34;&gt;Delphi&lt;/a&gt; and &lt;a href=&#34;https://en.wikipedia.org/wiki/Quantum_Link&#34;&gt;Quantum Link&lt;/a&gt;. Some SIDPlayer songs were written to be played on two SID chips simultaneously for a total of six simultaneous voices, made possible by either having two C64s, hacking a C64 to add a second SID chip, or using the &lt;em&gt;SID Symphony Stereo Cartridge&lt;/em&gt; from Dr. Evil Laboratories. Today, this legacy lives on in the &lt;a href=&#34;https://www.c64music.co.uk/&#34;&gt;Compute!&amp;rsquo;s Gazette SID Collection&lt;/a&gt; (CGSC). You can download the whole set, or browse and play the collection in a web browser with the website &lt;a href=&#34;https://deepsid.chordian.net/&#34;&gt;DeepSID&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;LightTangent &lt;a href=&#34;https://gitlab.com/fptech/rev-sidplayer&#34;&gt;disassembled the original SIDPlayer program&lt;/a&gt;, and used the findings to write SidPlay65. Many thanks to LightTangent for this ambitious project!&lt;/p&gt;
&lt;h2 id=&#34;full-color-full-motion-video-demos-by-miragebd&#34;&gt;Full-color full-motion video demos by MirageBD&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/hyperballad1.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/hyperballad1.jpg 320w, https://dansanderson.com/mega65/santas-souped-up-mega65/hyperballad1_hu_8328ba521cfcac76.jpg 600w, https://dansanderson.com/mega65/santas-souped-up-mega65/hyperballad1_hu_41869a2079299445.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/hyperballad1.jpg&#34;
        alt=&#34;A still from HyperBallad by Bjork, as rendered on the MEGA65 by MirageBD&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;HyperBallad by Bjork, as rendered on the MEGA65 by MirageBD.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;MirageBD has been researching methods for streaming full-color full-motion video from the SD card. So far, Mirage has produced two brilliant demos: &lt;a href=&#34;https://files.mega65.org?id=1b20b366-9177-4739-8420-c74f911a7202&#34;&gt;HyperBallad&lt;/a&gt; (1995), the Björk music video masterpiece, and &lt;a href=&#34;https://files.mega65.org?id=44fbe834-7f60-4134-956b-a2feff3eee34&#34;&gt;Duel&lt;/a&gt;, a scene from the movie &lt;a href=&#34;https://www.imdb.com/title/tt0087197/&#34;&gt;&lt;em&gt;Electric Dreams&lt;/em&gt;&lt;/a&gt; (1984). Both demos launch from a D81 disk image, and stream data directly from a large file on the SD card.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important note:&lt;/strong&gt; Running these demos requires a fast SD card, very likely an SD card &lt;em&gt;faster&lt;/em&gt; than the one that was included with your MEGA65. As lydon explained on Discord, the bundled cards are optimized for a longer lifespan, at the expense of some speed. If these demos glitch out after the first couple of seconds, consider getting a SanDisk Ultra brand microSD card.&lt;/p&gt;
&lt;h2 id=&#34;copa65-by-bananzi&#34;&gt;COPA65 by Bananzi&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/copa65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/copa65.png 784w, https://dansanderson.com/mega65/santas-souped-up-mega65/copa65_hu_835f956e0b5a029f.png 600w, https://dansanderson.com/mega65/santas-souped-up-mega65/copa65_hu_6b8ee64e1e5aa370.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/copa65.png&#34;
        alt=&#34;Title image from the manual for COPA65 by Bananzi&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;COPA65 by Bananzi. (Image from the manual.)&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Ever wanted to copy and paste text in the MEGA65 screen editor? Now you can, with this clever extension by Bananzi! &lt;a href=&#34;https://files.mega65.org?id=d9a62fc3-6881-4116-b7f1-66110ded147a&#34;&gt;COPA65&lt;/a&gt; adds a text clipboard to the built-in editor experience, as well as both keyboard and mouse methods for selecting text.&lt;/p&gt;
&lt;p&gt;With COPA65 installed, simply press &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;C&lt;/kbd&gt; to wake it up, then press one of the command keys. For example, use the &lt;code&gt;C&lt;/code&gt; command (press &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;C&lt;/kbd&gt;, then press &lt;kbd&gt;C&lt;/kbd&gt;) to set the start of a selection, move the cursor to the end of the selection, then use the &lt;code&gt;C&lt;/code&gt; command again to copy the text. Finally, move the cursor to where you wish to paste, then use the &lt;code&gt;V&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Other commands can quickly select characters, words, and lines, and can insert pasted text instead of overwriting. See the detailed manual included with the download for instructions on installation and use.&lt;/p&gt;
&lt;p&gt;COPA65 requires ROM beta version 920398 or later, which is when we formalized the extension mechanism being used. This is newer than the ROM included in release package v0.96. You can &lt;a href=&#34;https://files.mega65.org?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;update to the latest ROM beta version&lt;/a&gt;, or wait for the v0.97 release package, which hopefully will be out soon.&lt;/p&gt;
&lt;p&gt;Really amazing work, Bananzi!&lt;/p&gt;
&lt;h2 id=&#34;midnight-mega-by-nobruinfo&#34;&gt;Midnight Mega by nobruinfo&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/midnight.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/midnight.png 720w, https://dansanderson.com/mega65/santas-souped-up-mega65/midnight_hu_48a266691a07311.png 600w, https://dansanderson.com/mega65/santas-souped-up-mega65/midnight_hu_8210f0ebee82c428.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/midnight.png&#34;
        alt=&#34;Midnight Mega by nobruinfo&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Midnight Mega by nobruinfo.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Bruno (nobruinfo on Discord) has been working on a powerful file browser, which he calls &lt;a href=&#34;https://files.mega65.org?id=f3cc7335-48ad-4099-ae99-d870e5dfc156&#34;&gt;Midnight Mega&lt;/a&gt;. You can use Midnight Mega to browse your SD card, mount disk images, and view and copy files.&lt;/p&gt;
&lt;p&gt;Midnight Mega is still in a beta testing release, and it is recommended to back up your data regularly. Please &lt;a href=&#34;https://github.com/nobruinfo/midnightmega/issues&#34;&gt;report any issues you find&lt;/a&gt;, and join the discussion on the &lt;code&gt;#midnight-mega&lt;/code&gt; channel of the MEGA65 Discord. Also note that it only supports disk images and the internal floppy drive; it does not yet support external IEC drives.&lt;/p&gt;
&lt;h2 id=&#34;gurce-disassembles-sea-wolf&#34;&gt;Gurce disassembles Sea Wolf&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/seawolf2.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/seawolf2.png 704w, https://dansanderson.com/mega65/santas-souped-up-mega65/seawolf2_hu_52014cde7b43cf.png 600w, https://dansanderson.com/mega65/santas-souped-up-mega65/seawolf2_hu_a9b69cfa02b68b5b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/seawolf2.png&#34;
        alt=&#34;Screenshot from Gurce&amp;amp;#39;s version of the C64 game Sea Wolf&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Gurce&amp;rsquo;s version of &lt;em&gt;Sea Wolf&lt;/em&gt; for the Commodore 64, modified to support four players.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;My series on disassembling &lt;em&gt;Crossroads&lt;/em&gt; is directly inspired by Gurce, who recently disassembled another classic C64 game, &lt;a href=&#34;https://en.wikipedia.org/wiki/Sea_Wolf_(video_game)&#34;&gt;&lt;em&gt;Sea Wolf&lt;/em&gt;&lt;/a&gt;. In this submarine battle game, you (and an optional second player) use paddle controls to maneuver submarines to fire missiles at battleships. The game&amp;rsquo;s lineage goes all the way back to the electro-mechanical arcade game &lt;a href=&#34;https://en.wikipedia.org/wiki/Periscope_(arcade_game)&#34;&gt;&lt;em&gt;Periscope&lt;/em&gt;&lt;/a&gt; by Sega (1966), followed by a similar electro-mechanical version by Midway called &lt;em&gt;Sea Devil&lt;/em&gt;. Midway launched a video arcade version under the name &lt;em&gt;Sea Wolf&lt;/em&gt; in 1976. Commodore International produced a home version for the VIC-20 and C64 in 1982.&lt;/p&gt;
&lt;p&gt;Gurce made two videos about his disassembly project. &lt;a href=&#34;https://www.youtube.com/watch?v=WwZNy4HIL0k&#34;&gt;Part 1&lt;/a&gt; introduces the game and the project, and presents a few findings. The extended &lt;a href=&#34;https://youtu.be/2CkLBIRiCV0?si=iKYhKNXchjm1WT4E&#34;&gt;part 2&lt;/a&gt; presents the entire project, with live demos and slides. You can read &lt;a href=&#34;https://github.com/gurcei/petwolf/blob/main/SEA%20WOLF%20DISASSEMBLY.txt&#34;&gt;Gurce&amp;rsquo;s complete notes&lt;/a&gt; and &lt;a href=&#34;https://github.com/gurcei/petwolf/blob/main/seawolf.asm&#34;&gt;the final disassembly&lt;/a&gt; on Github. With disassembly in hand, Gurce was able to modify the game to support four players, with two paddles on each of the two joystick ports.&lt;/p&gt;
&lt;p&gt;Disassembling classic games is a great way to learn about programming for the C64 and the MEGA65. What game would you disassemble?&lt;/p&gt;
&lt;h2 id=&#34;featured-files-cornucopia&#34;&gt;Featured Files Cornucopia!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/stargate1.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/stargate1.png 2152w, https://dansanderson.com/mega65/santas-souped-up-mega65/stargate1_hu_63c58336150b087b.png 600w, https://dansanderson.com/mega65/santas-souped-up-mega65/stargate1_hu_65184665631c53bf.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/stargate1.png&#34;
        alt=&#34;A screenshot from the arcade game Stargate&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Stargate (1981).&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;muse has given us another arcade core! &lt;a href=&#34;https://files.mega65.org?id=fb977a9b-3979-4420-99f2-c683f52070b7&#34;&gt;Stargate&lt;/a&gt; is the 1981 sequel to the arcade classic &lt;em&gt;Defender&lt;/em&gt;, a fast-paced horizontal shooter. As with other arcade cores, you will need to search for ROM data files and follow &lt;a href=&#34;https://github.com/sho3string/StargateMEGA65_R3_R6&#34;&gt;the installation instructions&lt;/a&gt;. The core is available for both R3 and R6 mainboards.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=e824b00d-706b-4d1c-a5e9-3ffd94e326cb&#34;&gt;Fireplace&lt;/a&gt; is a short BASIC demo by Urban Lindeskog, featuring PETSCII flames and crackling sound effects. Drag your MEGA65 out to the living room and run this for the holidays to keep your family warm.&lt;/p&gt;
&lt;p&gt;RobH developed an &lt;a href=&#34;https://files.mega65.org?id=1775e66c-d8b5-4af4-9c00-4ca03a6e681e&#34;&gt;example of sprite to character collision detection&lt;/a&gt; in BASIC, then followed up with &lt;a href=&#34;https://files.mega65.org?id=f52f6ecf-3ad3-463b-87c4-77423b26b03b&#34;&gt;a Lode Runner-like ladder climbing demo&lt;/a&gt;. These demos show off how to implement several game mechanics with this technique, including a player sprite, walls, collectibles, ladders, and doors. Both include well-commented BASIC source code.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=99494f19-0605-4e52-96a3-20fad28e221e&#34;&gt;Alpha Burst&lt;/a&gt; is a brief graphics-only demo by Drex, with brilliant colors and a borderless display. Run this on real hardware for full effect.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=81fd9a5d-1ced-4e13-af78-5ba90c81de80&#34;&gt;Disk Doctor Mega&lt;/a&gt; by tundra/C is a low-level disk viewer and editor for both physical floppy disks and virtual D81 disk images. Inspect your disk tracks and sectors, and potentially recover data from damaged disks.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=77e4a95b-cfc1-4170-9b3b-b1f27bcf8d8a&#34;&gt;Unelite Part 1&lt;/a&gt; by mk9 is a text adventure game with PETSCII graphics. Use the joystick to select options in this branching sci-fi narrative.&lt;/p&gt;
&lt;h2 id=&#34;45gs02-quick-reference-and-other-media&#34;&gt;45GS02 Quick Reference, and other media&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/45gs02quickref.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/45gs02quickref.png 666w, https://dansanderson.com/mega65/santas-souped-up-mega65/45gs02quickref_hu_1abf55a0f68de551.png 600w, https://dansanderson.com/mega65/santas-souped-up-mega65/45gs02quickref_hu_8f9242292d31b832.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/santas-souped-up-mega65/45gs02quickref.png&#34;
        alt=&#34;45GS02 quick reference, by dddaaannn (that&amp;amp;#39;s me)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;45GS02 quick reference, by dddaaannn (that&amp;rsquo;s me).&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I brought a few gifts to the party as well. You can still &lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;buy the 45GS02 quick reference&lt;/a&gt; as a mousepad or a poster. If you&amp;rsquo;d prefer a digital copy, you can now &lt;a href=&#34;https://files.mega65.org?id=ac9cf203-5276-430e-a491-dab7787ca79c&#34;&gt;download the 45GS02 Quick Reference PDF&lt;/a&gt; for free. I also uploaded the &lt;a href=&#34;https://files.mega65.org?id=b14f0473-5358-4460-b98f-4536dc732b36&#34;&gt;BASIC65 Quick Reference PDF&lt;/a&gt; from the User&amp;rsquo;s Guide for similar convenience.&lt;/p&gt;
&lt;p&gt;When I took my MEGA65s to computer shows earlier this year, I made some paper items to keep at the table to help show it off. I have uploaded these designs to Filehost, in case anyone else wants to use them. The &lt;a href=&#34;https://files.mega65.org?id=1654a0b1-1117-4a9d-8a63-84830161f630&#34;&gt;MEGA65 Conference Table standee design&lt;/a&gt; is designed to be printed professionally on a 11&amp;quot; x 17&amp;quot; sign, and has facts and figures about the computer. The &lt;a href=&#34;https://files.mega65.org?id=c8143477-dded-470a-b719-a0a64c3e3e75&#34;&gt;MEGA65 Demo Booklet&lt;/a&gt; prints in landscape orientation on 8-1/2&amp;quot; x 11&amp;quot; paper, suitable for spiral binding on the top long edge, and features diagrams, screenshots, and very brief instructions intended for someone unfamiliar with the computer to try it out in just a few minutes. Accompany this with an SD card pre-loaded with the mentioned disk images for full effect.&lt;/p&gt;
&lt;/section&gt;
&lt;blockquote&gt;
&lt;p&gt;Santa called his elves together &lt;br&gt;
To soup up his old sleigh &lt;br&gt;
So Rudolph and the other reindeer &lt;br&gt;
Could rest on Christmas day&lt;/p&gt;
&lt;p&gt;He&amp;rsquo;s got a million miles to travel &lt;br&gt;
And to do it in one day &lt;br&gt;
And that&amp;rsquo;s why Santa Claus &lt;br&gt;
Has a souped-up Santa sleigh&lt;/p&gt;
&lt;p&gt;Got a rocket burnin&amp;rsquo; mighty quick &lt;br&gt;
Turnin&amp;rsquo; Santa&amp;rsquo;s souped-up sleigh &lt;br&gt;
Comes in like a streak of light &lt;br&gt;
And it goes out the same way&lt;/p&gt;
&lt;p&gt;When you hear that rocket roar &lt;br&gt;
You know Santa&amp;rsquo;s on his way &lt;br&gt;
But he&amp;rsquo;ll be back again next year &lt;br&gt;
In his souped-up Santa sleigh&lt;/p&gt;
&lt;p&gt;— &amp;ldquo;Santa&amp;rsquo;s Souped-up Sleigh,&amp;rdquo; &lt;em&gt;from the film&lt;/em&gt; Melvin &amp;amp; Howard, &lt;em&gt;dir. Jonathan Demme&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Have a great holiday! See you next year.&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/santas-souped-up-mega65/M65Digest_2024Dec.mp3" length="13485369" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>674</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/santas-souped-up-mega65/santasxmascaper.png"/>
      
    </item>
    
    <item>
      <title>Disassembling Crossroads, part 1</title>
      <link>https://dansanderson.com/mega65/crossroads-part-1/</link>
      <pubDate>Fri, 15 Nov 2024 00:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/crossroads-part-1/</guid>
      <description>&lt;p&gt;Disassembling Crossroads, part 1. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for November 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Disassembling Crossroads, part 1. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for November 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/crossroads-part-1/M65Digest_2024Nov.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/M65Digest_2024Nov.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Disassembling Crossroads, part 1.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_cartoon.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_cartoon.png 613w, https://dansanderson.com/mega65/crossroads-part-1/crossroads_cartoon_hu_d8009d710939b88b.png 600w, https://dansanderson.com/mega65/crossroads-part-1/crossroads_cartoon_hu_860a90a6a146284f.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_cartoon.png&#34;
        alt=&#34;The title illustration for the game Crossroads, published by Compute!&amp;amp;#39;s Gazette, December 1987.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The title illustration for the game Crossroads, published by Compute!&#39;s Gazette, December 1987.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One of my all-time favorite games for the Commodore 64—and I know I&amp;rsquo;m not alone in this—is &lt;em&gt;Crossroads,&lt;/em&gt; the single-screen maze shoot&amp;rsquo;em&amp;rsquo;up by Steve Harter, published in &lt;a href=&#34;https://en.wikipedia.org/wiki/Compute!%27s_Gazette&#34;&gt;Compute!&amp;rsquo;s Gazette magazine&lt;/a&gt; as a type-in program in December 1987. The game features dozens of enemies of a variety of types and colors, all fighting each other in a cacophony of attacks and explosions. You&amp;rsquo;re dropped into the fray to collect items called &amp;ldquo;spars,&amp;rdquo; which provide you some protection against attacks, and which the enemies also consume. The game supports one or two players on joysticks, and both players battle for survival simultaneously.&lt;/p&gt;
&lt;p&gt;Some people like to say that typing in programs from magazines and books helped them learn how to write programs of their own. I can see how that might be true for BASIC programs, though I can&amp;rsquo;t honestly say I learned anything from type-ins when I was in grade school. For programs written in languages other than BASIC, Compute! offered no way to learn. In &lt;a href=&#34;https://web.archive.org/web/20231231051645/https://kirk.is/2006/04/13&#34;&gt;this interview with Steve Harter&lt;/a&gt; by Kirk Israel, Steve says he wrote &lt;em&gt;Crossroads&lt;/em&gt; in assembly language, but Compute! never published assembly language listings for full programs in magazines. Instead, Compute! published such programs as columns of numbers, along with a helper program that assisted with keying these values directly into memory. The most you could learn from these type-ins was data entry, and perseverance.&lt;/p&gt;
&lt;p&gt;(I&amp;rsquo;m aware of only two cases where Compute! published full assembly language program listings for the C64, both as books: the &lt;a href=&#34;https://archive.org/details/sboml&#34;&gt;LADS assembler&lt;/a&gt; and the &lt;a href=&#34;https://archive.org/details/Computes_Speedscript&#34;&gt;SpeedScript word processor&lt;/a&gt;. Steve wrote &lt;em&gt;Crossroads&lt;/em&gt; using LADS. Also, as I mentioned &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/&#34;&gt;a while back&lt;/a&gt;, Compute!&amp;rsquo;s Gazette did include the assembly language source code for Fast Assembler on the cover disk, just not in the magazine.)&lt;/p&gt;
&lt;p&gt;Over the next two issues of this Digest, we&amp;rsquo;ll crack open the original Crossroads program and see what we can learn, using two modern reverse engineering tools for your PC. This month, we&amp;rsquo;ll take a look at &lt;a href=&#34;https://github.com/slajerek/RetroDebugger&#34;&gt;Retro Debugger&lt;/a&gt;, a C64 emulator with real-time memory visualization features. To keep this newsletter to a reasonable length (😬) we&amp;rsquo;ll discuss just enough to get started, and ask a few specific questions of interest about the game.&lt;/p&gt;
&lt;p&gt;As always, let us begin with some MEGA65 news!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;new-filehost-feature-high-score-tables&#34;&gt;New Filehost feature: high score tables&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/highscore.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-1/highscore.png 689w, https://dansanderson.com/mega65/crossroads-part-1/highscore_hu_9fc467e18217522d.png 600w, https://dansanderson.com/mega65/crossroads-part-1/highscore_hu_123f57dab8c79dce.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-1/highscore.png&#34;
        alt=&#34;An example of a Filehost high score table, for the game Classy&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Filehost high score tables.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Filehost has a fun new feature for competitive MEGA65 gaming: high score tables! When you upload your game to Filehost, you can choose to enable &amp;ldquo;Highscore submission.&amp;rdquo; This allows players to submit their high scores by clicking the plus (&amp;quot;+&amp;quot;) button on your game&amp;rsquo;s Filehost detail page, uploading a screenshot as evidence. All score submissions must be approved by you before appearing on the page. You will receive a message when a player submits a score for your game.&lt;/p&gt;
&lt;p&gt;Check out &lt;a href=&#34;https://files.mega65.org?id=3549b82b-b851-41ec-a8d9-918996a4d2ea&#34;&gt;the high score table on Classy&lt;/a&gt; as an example.&lt;/p&gt;
&lt;p&gt;Thanks as always to Tayger for the Filehost innovations! Everyone go out and rack up those high scores!&lt;/p&gt;
&lt;h2 id=&#34;galaga-ghostsngoblins-and-xevious-now-available-for-r6-boards-ti-994a-now-available-for-r3-boards&#34;&gt;Galaga, Ghosts&amp;rsquo;n&amp;rsquo;Goblins, and Xevious now available for R6 boards; TI-99/4A now available for R3 boards&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/gng_scr_sDWmSg.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-1/gng_scr_sDWmSg.png 512w, https://dansanderson.com/mega65/crossroads-part-1/gng_scr_sDWmSg_hu_bfbdfe622f450e89.png 600w, https://dansanderson.com/mega65/crossroads-part-1/gng_scr_sDWmSg_hu_b6bd1a5b031fa293.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-1/gng_scr_sDWmSg.png&#34;
        alt=&#34;Ghosts&amp;amp;#39;n&amp;amp;#39;Goblins arcade core for the MEGA65, now available for R6 boards&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Ghosts&amp;rsquo;n&amp;rsquo;Goblins arcade core for the MEGA65, now available for R6 boards.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Over the last year or so, muse has given us alternate cores for the arcade games &lt;a href=&#34;https://files.mega65.org?id=8bc248e3-c29c-4ba8-b8c3-6018a995a9ea&#34;&gt;Galaga&lt;/a&gt;, &lt;a href=&#34;(https://files.mega65.org?id=e563df76-e12f-47de-9bb2-cca4ebe1e18d)&#34;&gt;Ghosts&amp;rsquo;n&amp;rsquo;Goblins&lt;/a&gt;, and &lt;a href=&#34;https://files.mega65.org?id=d32474e9-6f30-48f8-bba3-167cad4bbc4f&#34;&gt;Xevious&lt;/a&gt;, originally released for the R3 mainboard. Now, thanks to Robert Jaremczak (rjaremczak), there are R6 versions for these cores: &lt;a href=&#34;https://files.mega65.org?id=1672149c-66d3-4df7-9128-e9c83095c49a&#34;&gt;Galaga R6&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=f66965dc-4006-4ebe-8fde-eed9bc60d3aa&#34;&gt;Ghosts&amp;rsquo;n&amp;rsquo;Goblins R6&lt;/a&gt;, and &lt;a href=&#34;https://files.mega65.org?id=c67076de-8dd5-4877-8c95-7a01d2cae441&#34;&gt;Xevious R6&lt;/a&gt;. See the original installation instructions for the R3 cores, which also apply to the R6 versions.&lt;/p&gt;
&lt;p&gt;zeldin has updated the &lt;a href=&#34;https://kugelblitz360.github.io/m65-altcores/computer-cores.html#ti-994a&#34;&gt;TI-99/4A core&lt;/a&gt; several times since its initial release, and as of version 1.3, the core is available for the R3 mainboard as well as R6. &lt;a href=&#34;https://files.mega65.org/html/main.php?id=a25ce133-ed07-4ef7-8495-179d69c43ed0&#34;&gt;Go grab the latest&lt;/a&gt;, and be sure to &lt;a href=&#34;https://github.com/zeldin/Mega99/issues&#34;&gt;file any bugs you find&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I had a few people respond to &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/&#34;&gt;last&amp;rsquo;s month&amp;rsquo;s Digest&lt;/a&gt; to point out that core availability is currently a sticking point with regards to mainboard revisions, with some cores only available for R3 and others only for R6. Core developers must put in additional effort to support both mainboards, and not everybody owns both boards for testing. If you&amp;rsquo;re working on a core and need assistance building it for a board revision that you do not own, please reach out to the MEGA65 community on Discord or by email. We will eagerly connect you with resources for building and testing your core on both revisions.&lt;/p&gt;
&lt;p&gt;Thank you Robert and zeldin for working on cores!&lt;/p&gt;
&lt;h2 id=&#34;last-call-for-r3-real-time-clock-replacements-grove-rtc&#34;&gt;Last call for R3 Real-Time Clock replacements (Grove RTC)&lt;/h2&gt;
&lt;p&gt;Back in 2022, we noticed that a small but significant percentage of R3 mainboards had faulty Real-Time Clock (RTC) chips. Paul quickly put together a workaround involving a core update and an &lt;a href=&#34;https://www.aliexpress.us/item/2251832636105970.html?algo_pvid=26a281a9-a207-475f-9c56-de8ce11cea57&amp;amp;algo_exp_id=26a281a9-a207-475f-9c56-de8ce11cea57-0&amp;amp;pdp_ext_f=%7B%22sku_id%22:%2210000000337849443%22%7D&amp;amp;pdp_npi=2@dis!USD!2.27!2.0!!!!!@2101e9d116652918520047406e6ac3!10000000337849443!sea&amp;amp;curPageLogUid=S6c2J0uTS2Tp&amp;amp;gatewayAdapt=4itemAdapt&#34;&gt;inexpensive RTC breakout board&lt;/a&gt; and &lt;a href=&#34;https://core-electronics.com.au/grove-4-pin-male-jumper-to-grove-4-pin-conversion-cable-5-pcs-per-pack.html&#34;&gt;Grove connector&lt;/a&gt;. This requires a soldering iron to put together, but no expertise: it&amp;rsquo;s just four wires. Nevertheless, I wanted to make sure that everyone who needed one could get one easily, so I built a bunch of them and &lt;a href=&#34;https://files.mega65.org?ar=ff484da0-d942-4e9b-adf1-3b5a77acaa25&#34;&gt;made them available for the cost of shipping&lt;/a&gt;. The MEGA65 team also supported this effort financially out of their own pockets.&lt;/p&gt;
&lt;p&gt;I will be ending my distribution offer at the end of 2024. I have about a dozen units remaining, and am willing to send them out to anyone who needs them. If you have an R3 mainboard and believe your Real-Time Clock is faulty, please follow &lt;a href=&#34;https://files.mega65.org?ar=ff484da0-d942-4e9b-adf1-3b5a77acaa25&#34;&gt;these instructions for testing your RTC and requesting a unit&lt;/a&gt;. I will email you with instructions to send me the shipping cost by PayPal, then get one out to you, while supplies last.&lt;/p&gt;
&lt;p&gt;Please do not request one if you don&amp;rsquo;t need one. Only a fraction of the MEGA65s delivered in 2022 have this issue. Follow the instructions to test your MEGA65 before requesting a replacement. If you discover you need one later than the end of this year, consider ordering the parts and cooking one up yourself. These are easy to build!&lt;/p&gt;
&lt;h2 id=&#34;the-sega-adapter-is-great-actually&#34;&gt;The sega-adapter is great actually&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/switchpro.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-1/switchpro.jpeg 640w, https://dansanderson.com/mega65/crossroads-part-1/switchpro_hu_ab6ab74bddd6c315.jpeg 600w, https://dansanderson.com/mega65/crossroads-part-1/switchpro_hu_389e6414763e94d3.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-1/switchpro.jpeg&#34;
        alt=&#34;Controlling a MEGA65 with a Switch Pro controller, 8bitDo Retro Receiver, and sega-adapter&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Controlling a MEGA65 with a Switch Pro controller, 8bitDo Retro Receiver, and sega-adapter.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Last month I mentioned &lt;a href=&#34;https://github.com/eyvind/sega-adapter/tree/master&#34;&gt;the sega-adapter project&lt;/a&gt; by Eyvind Bernhardsen as a fun way to connect Sega Genesis-style game controllers to Commodore computers. Since I sent the newsletter, I had some boards printed, got the parts together, and assembled a few. Chat, I recommend it, especially when used with the &lt;a href=&#34;https://www.8bitdo.com/retro-receiver-genesis-mega-drive/&#34;&gt;8bitDo Retro Receiver for Sega Genesis&lt;/a&gt; (&lt;a href=&#34;https://www.amazon.com/8Bitdo-Retro-Bluetooth-Receiver-Original-Genesis/dp/B07MSWGSJY&#34;&gt;$16 on Amazon&lt;/a&gt;). The 8bitDo Retro Receiver pairs with almost any modern Bluetooth game controller, including Nintendo, Playstation, and older Xbox controllers (but not newer Bluetooth LE Xbox controllers). 8bitDo also makes a Bluetooth Sega Genesis gamepad; be sure to get the &lt;a href=&#34;https://www.amazon.com/dp/B07MSN1NPC&#34;&gt;M30 Bluetooth model&lt;/a&gt;, not the &amp;ldquo;M30 2.4G wireless&amp;rdquo; model. I got my Nintendo Switch Pro controller to be a 3-button game controller for my MEGA65!&lt;/p&gt;
&lt;p&gt;I &lt;a href=&#34;https://dansanderson.com/lab-notes/sega-adapter/&#34;&gt;wrote a brief article on my blog&lt;/a&gt; about assembling this project if you want to know more. It was easy, but it was my first encounter with PIC microcontrollers, so I had a few things to learn. It was a fun afternoon project with a satisfying result, and because I made ten, I have my holiday gifts all sorted.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;playing-crossroads&#34;&gt;Playing Crossroads&lt;/h2&gt;
&lt;p&gt;The first step to reverse engineering anything is to understand what the thing does. We can learn a lot about &lt;em&gt;Crossroads&lt;/em&gt; just from playing it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://archive.org/&#34;&gt;Archive.org&lt;/a&gt; has complete scans of Compute!&amp;rsquo;s Gazette magazine, and &lt;em&gt;Crossroads&lt;/em&gt; is in &lt;a href=&#34;https://archive.org/details/1987-12-computegazette&#34;&gt;issue 54, December 1987&lt;/a&gt;. An amusingly nostalgic way to acquire the &lt;em&gt;Crossroads&lt;/em&gt; program would be to enter the &amp;ldquo;MLX&amp;rdquo; data entry program listed in the magazine, then use MLX to enter the 6,676 hexadecimal numbers for the game. (That&amp;rsquo;s 5,935 program bytes, plus error checking digits.) I recommend simply downloading &lt;a href=&#34;https://commodore.software/downloads/download/732-compute-s-gazette-associated-disks/15337-compute-s-gazette-all-disk-images&#34;&gt;the Compute!&amp;rsquo;s Gazette cover disk image archive&lt;/a&gt;. The disk image for the December 1987 issue is named &lt;code&gt;1987-12.d64&lt;/code&gt;. This disk image works great with the C64 core for the MEGA65. (Alas, I could not get it to run in GO64 mode. Maybe later we can figure out why.)&lt;/p&gt;
&lt;p&gt;We can learn some useful things about Crossroads even before we run it. If we browse the disk directory, we can see that there are many files from this issue of the magazine, but the game likely consists of a single PRG file named &lt;code&gt;CROSSROADS&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LOAD &amp;#34;$&amp;#34;,8
LIST&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can load this file from disk into memory, using the &lt;code&gt;,8,1&lt;/code&gt; arguments to &lt;code&gt;LOAD&lt;/code&gt; to tell it to use whatever memory start address that &lt;code&gt;CROSSROADS&lt;/code&gt; prefers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LOAD &amp;#34;CROSSROADS&amp;#34;,8,1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The program loads, and we&amp;rsquo;re back at the &lt;code&gt;READY.&lt;/code&gt; prompt. Because the game didn&amp;rsquo;t do anything fancy to start automatically, we can guess that the program has loaded to the start of BASIC memory, and probably begins with a BASIC bootstrap program that invokes the machine code, like &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/&#34;&gt;we&amp;rsquo;ve done for our own programs&lt;/a&gt;. Let&amp;rsquo;s confirm this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LIST&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sure enough, there is a one-line BASIC program in memory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SYS2300&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Connect a joystick to port 2 (first player), then start the program with the &lt;code&gt;RUN&lt;/code&gt; command. The game starts without any further disk activity, which confirms our hypothesis that this is a single-file game.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve never played &lt;em&gt;Crossroads&lt;/em&gt; before, take some time to enjoy it! Shoot bullets at monsters by pressing the fire button, and collect the white spinning &amp;ldquo;spars&amp;rdquo; to gain shields and progress to the end of the level. Connect a second joystick and invite a friend!&lt;/p&gt;
&lt;h2 id=&#34;observing-the-game&#34;&gt;Observing the game&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_screenshot.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_screenshot.png 384w, https://dansanderson.com/mega65/crossroads-part-1/crossroads_screenshot_hu_aa9feeb98ea8c4a8.png 600w, https://dansanderson.com/mega65/crossroads-part-1/crossroads_screenshot_hu_27a9f7e151be967e.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_screenshot.png&#34;
        alt=&#34;A screenshot of the attract mode of Crossroads.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Crossroads, in &#34;attract mode.&#34;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;As you play, try to make some guesses about how the game works, and come up with some questions you would like answered. Your own questions and hypotheses will guide your reverse engineering process.&lt;/p&gt;
&lt;p&gt;Here are just a few things I noticed that might be worth exploring:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Program states.&lt;/strong&gt; The game starts with an &amp;ldquo;attract mode&amp;rdquo; where a bunch of enemies duke it out on a maze without a player present, and with a scrolling message across the top of the screen. Like many vintage arcade games, attract mode appears very similar to gameplay, and likely reuses the game&amp;rsquo;s logic with minor changes. The game starts the first level when the player presses the fire button. Each level starts with an introductory animation where creatures appear with special graphical and sound effects. The players are the last to arrive. Then play begins. A level ends when a player collects a number of spars, at which point the game pauses until a key is pressed, and the game restarts at the next level. The game ends when both players are out of lives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Creature properties.&lt;/strong&gt; Creatures and players have a number of shields that protect them from attacks. Each attack deducts a shield, and the creature is destroyed when attacked without shields. A creature or a player gains a shield by picking up a spar. The player&amp;rsquo;s shield count appears at the top of the screen, under the &amp;ldquo;S.&amp;rdquo; Other creatures also have shield counts, but these are not visible. Player actions are controlled by joystick inputs; creature actions are controlled by algorithms. Each creature is of one of nine types, and the type describes their action patterns, reactions to collisions with bullets and other creatures, and the initial number of shields.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Character graphics.&lt;/strong&gt; The maze and the creatures appear to occupy a grid in the same shape as the C64&amp;rsquo;s 40 x 25 character mode, and every element appears to be the size of a single character. It&amp;rsquo;s likely that at least some of these graphical elements are using VIC-II character graphics, where the glyphs of some letters, numbers, and symbols in the PETSCII typeface have been replaced with these designs. Each element is of a single color and high resolution, 8 x 8 pixels per character.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Creature half-steps.&lt;/strong&gt; Even though creatures are the size of a single grid tile, they appear to traverse the screen in half-tile steps! If creatures are implemented with character graphics, the game must be doing something interesting to allow a creature to appear this way.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sprites.&lt;/strong&gt; There appear to be too many creatures and bullets on the screen at one time for the game to be using the eight VIC sprites to draw them. While advanced techniques like sprite multiplexing (which we &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/&#34;&gt;discussed previously&lt;/a&gt;) could use sprites to draw more than eight objects at a time, there&amp;rsquo;s nothing in the design of this game that prevents more than eight objects from appearing on the same scan line, so this seems unlikely. However, there is an explosion effect that occurs when a creature takes damage, and this appears to overlay the character graphics. This suggests that this effect might be done with sprites.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sound.&lt;/strong&gt; The soundscape of &lt;em&gt;Crossroads&lt;/em&gt; consists entirely of sound effects that represent activity on the screen: creatures appearing at the start of the level, player bullets firing, enemy bullets firing, shields absorbing damage, creatures and bullets being destroyed, and spars getting collected. There&amp;rsquo;s so much going on early in the level that each sound may be difficult to pick out, and it&amp;rsquo;s a bit easier after the screen is mostly clear. I&amp;rsquo;ll be interested to see how sounds are allocated to the three SID channels, especially when there are more than three events causing sound at a time.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;https://web.archive.org/web/20231231051645/https://kirk.is/2006/04/13&#34;&gt;that interview with the developer&lt;/a&gt; that I mentioned earlier, Steve confirms that the creatures use character graphics, and the explosions use sprites. Steve also mentions that the sprite images for the explosion animations are generated randomly.&lt;/p&gt;
&lt;h2 id=&#34;examining-the-prg&#34;&gt;Examining the PRG&lt;/h2&gt;
&lt;p&gt;We want to use modern PC tools to examine the program, so we need to extract the PRG file from the disk image. Graphical tools like &lt;a href=&#34;https://style64.org/dirmaster&#34;&gt;DirMaster&lt;/a&gt; (Windows only) or &lt;a href=&#34;https://droid64.sourceforge.net/&#34;&gt;DroiD64&lt;/a&gt; (Java, multi-platform) work nicely, or you can use the c1541 command included with the &lt;a href=&#34;https://vice-emu.sourceforge.io/&#34;&gt;VICE emulator&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;c1541 1987-12.d64 -read crossroads crossroads.prg&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use a tool called a &lt;em&gt;hex viewer&lt;/em&gt; to examine the bytes of the PRG file. I like a terminal-based hex viewer called &lt;a href=&#34;https://github.com/sharkdp/hexyl&#34;&gt;hexyl&lt;/a&gt;, and there are many others to choose from. We won&amp;rsquo;t spend more than a minute staring at raw bytes, but we can use this to get our bearings. Here are the first few dozen bytes of the PRG file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;00000000  01 08 0b 08 0a 00 9e 32  33 30 30 00 00 00 00 00  |.......2300.....|
00000010  44 aa aa 11 00 00 00 00  11 aa aa 44 00 00 00 00  |D..........D....|
00000020  00 3c 3c 00 00 00 00 00  00 3c 3c 00 00 00 38 38  |.&amp;lt;&amp;lt;......&amp;lt;&amp;lt;...88|
00000030  30 7f be 68 ce ec 38 38  30 7f 76 30 30 38 ff 8f  |0..h..880.v008..|
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/cross-development/&#34;&gt;As we&amp;rsquo;ve seen before&lt;/a&gt;, a PRG file starts with two bytes that specify the load address for the program. In this case, the first two bytes are $01 and $08, specifying the Commodore 64 BASIC start address of $0801 hexadecimal, or 2049 decimal. The PRG address bytes are not written to memory, they only tell the BASIC command &lt;code&gt;LOAD &amp;quot;CROSSROADS&amp;quot;,8,1&lt;/code&gt; where to put the rest of the data.&lt;/p&gt;
&lt;p&gt;The subsequent bytes describe the one-line BASIC program we saw earlier:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$0b $08: The address of the next line. In this case, it&amp;rsquo;s the end-of-program marker: $080b.&lt;/li&gt;
&lt;li&gt;$0a $00: The line number. $000a = 10 decimal.&lt;/li&gt;
&lt;li&gt;$9e: The C64 BASIC token for &lt;code&gt;SYS&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;$32 $33 $30 $30: PETSCII for &lt;code&gt;2300&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;$00: End of line.&lt;/li&gt;
&lt;li&gt;$00 $00: End of program. If you count from $0801, you&amp;rsquo;ll see this is at address $080b, from the first bytes of the first line.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These 12 bytes start at address 2049, which means the rest of the program data starts at address 2061 ($080d). Interestingly, the &lt;code&gt;SYS&lt;/code&gt; command uses address 2300 ($08fc). The data starting at address 2061 might be code, or it might be something else. We don&amp;rsquo;t know yet. We only know that the byte at address 2300 is the beginning of a machine code instruction, and that it&amp;rsquo;s the first instruction executed by the program.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s amusing to compare this hex dump to the listing in the magazine. (Well I think it&amp;rsquo;s amusing.) Note that Compute!&amp;rsquo;s Gazette program listings have nine bytes on a line, but only the first eight bytes are part of the program. The ninth byte is a &lt;em&gt;checksum&lt;/em&gt;, which the MLX program uses to verify that you entered the line correctly. If it didn&amp;rsquo;t do this, entering these programs would be a nightmare, as opposed to merely a nuisance.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_hexlisting.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_hexlisting.png&#34;
            width=&#34;248&#34;
            height=&#34;480&#34;
            alt=&#34;The beginning of the hexadecimal program listing of Crossroads, as it appears in Compute!&amp;amp;#39;s Gazette magazine, December 1987.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The beginning of the hexadecimal program listing of Crossroads, as it appears in the magazine.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;introducing-retro-debugger&#34;&gt;Introducing Retro Debugger&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger1.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger1.png 1119w, https://dansanderson.com/mega65/crossroads-part-1/retrodebugger1_hu_ff6129dccedfa147.png 600w, https://dansanderson.com/mega65/crossroads-part-1/retrodebugger1_hu_8b6c1e50083f2b05.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger1.png&#34;
        alt=&#34;Retro Debugger, running an emulation of the C64.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Retro Debugger.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If programming is the art of telling a computer what to do, debugging is the art of figuring out why it&amp;rsquo;s not doing what you meant. One of the best ways to do that is to peek inside the computer&amp;rsquo;s memory as it steps through your instructions, and try to line up the evolving state of the computer with your own mental model. This process is often so opaque and frustrating that I sometimes wish I could just rip the top off the chips and look inside as the program is running. Thanks to high fidelity emulators running on modern computers, this fantasy is now a reality.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/slajerek/RetroDebugger&#34;&gt;Retro Debugger&lt;/a&gt; by Marcin Skoczylas is an emulator for the C64, Atari XL/XE, and Nintendo Entertainment System, with some powerful real-time debugging tools. As the emulator runs, you see the C64 screen in one window, and use other windows to render the memory in different useful ways: as hex values, as machine code instructions, as graphics in common VIC-supported formats, and as a color-coded memory map. All of this is updated as the emulation runs at full speed, and you can pause execution and manipulate system state as a program runs.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s use Retro Debugger to inspect &lt;em&gt;Crossroads&lt;/em&gt;, and follow up on a few of our assumptions about how the game does graphics.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-retro-debugger&#34;&gt;Setting up Retro Debugger&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/slajerek/RetroDebugger/releases&#34;&gt;Download the latest Retro Debugger release&lt;/a&gt; for your platform (Windows, macOS, or Linux). You also need the original C64 ROM and 1541 DOS code. Retro Debugger opted not to include these in the distribution, but you can get them directly by installing the &lt;a href=&#34;https://vice-emu.sourceforge.io/&#34;&gt;VICE&lt;/a&gt; emulator. You&amp;rsquo;ll have to dig around the VICE folder for the appropriate &lt;code&gt;.bin&lt;/code&gt; files. On my Mac, I found them here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./VICE.app/Contents/Resources/share/vice/C64/
./VICE.app/Contents/Resources/share/vice/DRIVES/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Retro Debugger needs the ROM files to be in a single folder, with specific filenames. Create a new folder for these (such as inside the Retro Debugger folder), make duplicates of the files from VICE, and rename them as shown:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.../C64/basic-901226-01.bin&lt;/code&gt; -&amp;gt; &lt;code&gt;basic&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.../C64/chargen-901225-01.bin&lt;/code&gt; -&amp;gt; &lt;code&gt;chargen&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.../C64/kernal-901227-03.bin&lt;/code&gt; -&amp;gt; &lt;code&gt;kernal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.../DRIVES/dos1541-325302-01+901229-05.bin&lt;/code&gt; -&amp;gt; &lt;code&gt;dos1541&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.../DRIVES/dos1541ii-251968-03.bin&lt;/code&gt; -&amp;gt; &lt;code&gt;dos1541II&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you start Retro Debugger for the first time, you need to tell it where to find the ROM files. Open the Settings menu, select C64, then Select C64 ROMs folder. Navigate to the folder you created with the ROM files in it. Retro Debugger loads the ROMs and starts the emulation. If it complains, make sure the ROM files are in the right place and have been renamed as expected.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_disasm.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_disasm.png&#34;
            width=&#34;376&#34;
            height=&#34;431&#34;
            alt=&#34;Retro Debugger&amp;amp;#39;s C64 Disassembly window, with larger text size&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Retro Debugger&#39;s C64 Disassembly window, with larger text.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Behold, the insides of the C64! You can see the CPU bouncing around the instructions for blinking the cursor at the READY prompt, and all of the memory and register updates that go with it. With the &amp;ldquo;C64 Screen&amp;rdquo; window active, you can interact with the C64 as you would with VICE, typing BASIC commands and whatnot.&lt;/p&gt;
&lt;p&gt;Retro Debugger starts with some of its tools visible, but there are many more. With the cursor still at the READY prompt, open the VIC Editor menu, and select C64 Charset. The C64 Charset window opens. At this point, you should see what the VIC is currently using for its character set, which at the moment is standard C64 PETSCII. Resize the window to make the characters easier to see.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_charset.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_charset.png&#34;
            width=&#34;528&#34;
            height=&#34;155&#34;
            alt=&#34;Retro Debugger&amp;amp;#39;s C64 Charset window, with the PETSCII character set.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Retro Debugger&#39;s C64 Charset window, with the PETSCII character set.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;On my computer, I need to make the text bigger to be useful. Some windows, like the C64 Screen and Charset windows, have fixed-sized content, and you can drag the window corners to resize. In other windows, to increase the text size, right-click on the window, then adjust the Font Size slider. These windows can also be resized to display more information. The app will remember your window layout between sessions.&lt;/p&gt;
&lt;p&gt;Retro Debugger is based on VICE, and has all of its debugging features. To pause the emulator, press &lt;kbd&gt;F10&lt;/kbd&gt; (or open the Code menu, then select Pause). While paused, press &lt;kbd&gt;F10&lt;/kbd&gt; repeatedly to advance by one instruction at a time. Press &lt;kbd&gt;F11&lt;/kbd&gt; to resume full speed. You can also set &lt;em&gt;breakpoints&lt;/em&gt; on instructions, set &lt;em&gt;watchpoints&lt;/em&gt; on memory locations, and can navigate to instructions that access specific memory addresses. You can even rewind the emulation to the instruction that last accessed a memory address.&lt;/p&gt;
&lt;p&gt;For more information on features and keyboard shortcuts, see &lt;a href=&#34;https://github.com/slajerek/RetroDebugger/blob/master/docs/README-C64-65XE-NES-Debugger.txt&#34;&gt;docs/README-C64-65XE-NES_Debugger.txt&lt;/a&gt;, included with the program.&lt;/p&gt;
&lt;h2 id=&#34;playing-crossroads-in-the-emulator&#34;&gt;Playing Crossroads in the emulator&lt;/h2&gt;
&lt;p&gt;There are two ways to get &lt;em&gt;Crossroads&lt;/em&gt; running in the emulator. One method is to open the D64 disk image, then type the BASIC commands to load and run the game, as you would on a C64. Because &lt;em&gt;Crossroads&lt;/em&gt; is a single PRG file, you can also just open the PRG file that we extracted earlier. Opening the PRG is often faster, especially if you need to reset the program.&lt;/p&gt;
&lt;p&gt;Open the File menu, then select Open. Select the &lt;code&gt;crossroads.prg&lt;/code&gt; file. This will load and run the game immediately, so prepare your speaker or headphones volume for the game&amp;rsquo;s violent introduction.&lt;/p&gt;
&lt;p&gt;Next, open the Settings menu, then Joystick #2, and select a configuration for the joystick. With the joystick set to &amp;ldquo;Keyboard,&amp;rdquo; the cursor keys move the stick, and the right Alt key is the fire button. Or you can connect any PC-compatible game controller. If a controller is connected, its device name will appear in the menu.&lt;/p&gt;
&lt;p&gt;Select the C64 Screen window, then press fire to start a game. Good luck!&lt;/p&gt;
&lt;h2 id=&#34;investigating-character-graphics&#34;&gt;Investigating character graphics&lt;/h2&gt;
&lt;p&gt;We have a hypothesis about how &lt;em&gt;Crossroads&lt;/em&gt; uses character graphics. Let&amp;rsquo;s see if we can confirm this hypothesis in Retro Debugger.&lt;/p&gt;
&lt;p&gt;When you started the game, it installed a new character set and told the VIC to use it. The Charset window now shows new graphics tiles: a limited set of PETSCII letters and numbers, and nearly all of the graphics for the game. You can see four types of maze wall, the &amp;ldquo;spar,&amp;rdquo; and various images for each of the creature types and bullets facing all four directions. Each of these are unique &lt;em&gt;tiles&lt;/em&gt; of 8-by-8 pixels, and the tiles can be placed anywhere on the 40-by-25 tile grid.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_charset_crossroads.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_charset_crossroads.png&#34;
            width=&#34;527&#34;
            height=&#34;155&#34;
            alt=&#34;Retro Debugger&amp;amp;#39;s C64 Charset window, now with the Crossroads character set.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The C64 Charset window, now with the Crossroads character set.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We&amp;rsquo;ve made a discovery! The spar appears to be animating directly inside the Charset window! While &lt;em&gt;Crossroads&lt;/em&gt; animates creatures using multiple static tile definitions, it animates the spar simply by continuously updating its single tile definition. This conserves charset tiles, at the expense of some CPU time.&lt;/p&gt;
&lt;p&gt;If we squint, we can start to see how the game achieves its &amp;ldquo;half step&amp;rdquo; effect for creatures. When a creature is standing fully on a tile position, it is drawn as a single tile based on which direction it is facing. When a creature is walking between two tile grid spaces, it occupies both spaces, with a tile for each half of the image. There is a tile pair for each of the four directions. Each creature has two animation frames, and it appears that &lt;em&gt;Crossroads&lt;/em&gt; stores both frames as single tiles, and uses only the second frame for the half-step tiles, for a total of 16 tile definitions per creature.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/green_tiles.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/crossroads-part-1/green_tiles.png&#34;
            width=&#34;310&#34;
            height=&#34;185&#34;
            alt=&#34;Four right-facing tiles for Green Mashed Potato facing to the right&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Four right-facing tiles for Green Mashed Potato facing to the right.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;how-the-vic-finds-character-sets&#34;&gt;How the VIC finds character sets&lt;/h2&gt;
&lt;p&gt;The Charset window determines the memory location of the character set data that the VIC is using based on hardware registers, then draws the data it finds as characters. We can use some Commodore 64 knowledge to figure out where in memory this character set is stored.&lt;/p&gt;
&lt;p&gt;The way the VIC-II accesses memory is &lt;a href=&#34;https://www.c64-wiki.com/wiki/VIC_bank&#34;&gt;a little bit complicated&lt;/a&gt;. The VIC can only access one of the four 16 KB banks at a time. Additionally, the C64 architecture makes a special accommodation so the VIC can access the PETSCII character set from an upper bank of ROM even when a lower bank is selected. This configuration for how the VIC sees memory is managed by the second of the C64&amp;rsquo;s two CIA chips. This is controlled by the lowest two bits of the CIA data register at $DD00.&lt;/p&gt;
&lt;p&gt;In Retro Debugger, select the C64 Memory window. With this window selected, you can use either the &lt;kbd&gt;Page Up&lt;/kbd&gt;/&lt;kbd&gt;Page Down&lt;/kbd&gt; keys or your mouse&amp;rsquo;s scroll wheel to browse memory. You can also jump directly to an address by pressing &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;G&lt;/kbd&gt; (or on macOS, &lt;kbd&gt;Command&lt;/kbd&gt;+&lt;kbd&gt;G&lt;/kbd&gt;), then typing the address in hexadecimal. Use this to jump to the register address $DD00.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Be careful what you type when the Memory window is active. If the cursor is on a memory value, typing hexadecimal digits will modify memory. When you type &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;G&lt;/kbd&gt; (or &lt;kbd&gt;Command&lt;/kbd&gt;+&lt;kbd&gt;G&lt;/kbd&gt;) to go to an address, double-check that the cursor has moved into the address column before typing the address.&lt;/p&gt;
&lt;p&gt;With &lt;em&gt;Crossroads&lt;/em&gt; running, the register at $DD00 is set to $C7, so the lowest two bits are %11. According to &lt;a href=&#34;https://www.c64-wiki.com/wiki/VIC_bank&#34;&gt;C64 technical documentation&lt;/a&gt;, this points the VIC at bank 0, addresses $0000-$3FFF. It also tells the VIC to see the PETSCII character set at addresses $1000-$1FFF, hiding the RAM at these addresses from the VIC. This only hides the RAM from the VIC, not the CPU.&lt;/p&gt;
&lt;p&gt;Still in the C64 Memory window, jump to register &lt;a href=&#34;https://www.c64-wiki.com/wiki/53272&#34;&gt;$D018 (53272 decimal)&lt;/a&gt;. This register tells the VIC where to find screen memory within the selected bank, and where to find the character set. With the game running, this appears to be set to $19. This value is interpreted as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$19 = %0001 1001&lt;/li&gt;
&lt;li&gt;The upper four bits specify the location of screen memory, as a multiple of 1024 ($0400) bytes. %0001 = 1, so screen memory starts at address $0400. This is an offset from the beginning of the selected bank, and in this case the bank is 0, so the final address is $0400.&lt;/li&gt;
&lt;li&gt;The next three bits specify the location of character memory, as a multiple of 2048 ($0800) bytes. %100 = 4, so character memory starts at address $2000.&lt;/li&gt;
&lt;li&gt;The last (least significant) bit is ignored.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Be aware that the character memory offset gets described in manuals and online resources in different ways. I just described it the way the &lt;a href=&#34;https://www.c64-wiki.com/wiki/53272&#34;&gt;C64 wiki&lt;/a&gt; does: a three-bit number times 2048. Other books, including the MEGA65 manual, describe it as the upper three bits of a four-bit number whose last bit is 0, times 1024. The math works out the same either way.&lt;/p&gt;
&lt;p&gt;With the selected CIA configuration, a program could tell the VIC to use the PETSCII character set from ROM by setting the three bits to %010 = 2 times 2048 = address $1000. &lt;em&gt;Crossroads&lt;/em&gt; tells the VIC to look at $2000 instead, which is RAM where Crossroads can install its custom character set.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s confirm our understanding. In the C64 Memory window, go to address $2000.&lt;/p&gt;
&lt;p&gt;The C64 Memory window doesn&amp;rsquo;t know what the values in memory mean, but it tries to help us out by displaying them in four different ways: as hex bytes, as PETSCII characters, as character graphics data, and as sprite graphics data. In this case, we&amp;rsquo;re looking at character graphics data, so that view makes the most sense, and the other views are mostly nonsense. Scroll down to address $21F8 to see the spar glyph data being animated by the program.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memory_chars.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memory_chars.png 560w, https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memory_chars_hu_1ba492115ccdfe04.png 600w, https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memory_chars_hu_e263c9817d04ec76.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memory_chars.png&#34;
        alt=&#34;The C64 Memory window, positioned to inspect the Crossroads character set, starting at address $21F8.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The C64 Memory window, positioned to inspect the Crossroads character set.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;cheating-at-crossroads&#34;&gt;Cheating at Crossroads&lt;/h2&gt;
&lt;p&gt;The C64 Memory window lets us peek into the computer&amp;rsquo;s memory as it is running, and also lets us change memory as we like. If we knew where to look, we could change properties of the game, such as the number of lives the player has. So how do we know where to look?&lt;/p&gt;
&lt;p&gt;Locating variables is such a common task that the debugger has a tool just for this. Open the C64 menu, then select the C64 Memory Monitor. (This is a new tool, not the C64 Memory window that we&amp;rsquo;ve been using.) Resize this innocuous-looking little window to make it bigger.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor_empty.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor_empty.png 641w, https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor_empty_hu_c2829209105eed4c.png 600w, https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor_empty_hu_14bcf12d2a6c5ef0.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor_empty.png&#34;
        alt=&#34;The C64 Memory Monitor window, before a capture&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The C64 Memory Monitor window, before a capture.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Start a new single-player game by pressing the fire button on the joystick configured for port #2. The level clears, creatures spawn in, and finally the player arrives.&lt;/p&gt;
&lt;p&gt;The player starts with 4 lives. We can know for sure that somewhere in the computer&amp;rsquo;s memory is a representation of this value, and this representation will change when the player loses a life. We don&amp;rsquo;t know where it is, or how the value is represented.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a guess that the number of lives is stored as a byte, encoded as a non-negative integer. In other words, if we search the computer&amp;rsquo;s memory for a value of 4, there&amp;rsquo;s a chance that this might be how it stores the number of lives. This is just a guess! We can start with this, and refine our guess if it doesn&amp;rsquo;t work out.&lt;/p&gt;
&lt;p&gt;With the emulation still running, in the C64 Memory Monitor, click the Capture button. Retro Debugger takes a snapshot of all of memory, and a giant list of memory addresses and values appears. Next, set the filter settings:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check the box next to &amp;ldquo;Changed.&amp;rdquo; The list updates to show only the memory that differs from the captured snapshot in the current state of the emulation.&lt;/li&gt;
&lt;li&gt;Check the box next to &amp;ldquo;Matches prev.&amp;rdquo; Click the value box, type &lt;code&gt;04&lt;/code&gt;, then press &lt;kbd&gt;Enter&lt;/kbd&gt;. (It&amp;rsquo;s important to press &lt;kbd&gt;Enter&lt;/kbd&gt; in this field, or the value won&amp;rsquo;t stick.) The Memory Monitor now lists all of the memory locations that were set to $04 when you clicked the Capture button, but currently contain something else.&lt;/li&gt;
&lt;li&gt;Finally, check &amp;ldquo;Matches current,&amp;rdquo; and set its value to $03.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The list narrows to just the memory addresses that were 4, and are now 3. You may see more than one row, but likely only a few. Of all 65,536 memory addresses in the computer, these are the only ones that meet the criteria. This list updates in real-time as the emulation runs, and some rows will flicker in and out as memory changes.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor.png 639w, https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor_hu_2ef3fbfcf462fa36.png 600w, https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor_hu_e73b6d273409e6ce.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/crossroads-part-1/retrodebugger_memorymonitor.png&#34;
        alt=&#34;Retro Debugger&amp;amp;#39;s C64 Memory Monitor window, with a capture, and filter settings to find the player 1 life counter&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Retro Debugger&#39;s C64 Memory Monitor window, with a capture, and filter settings to find the player 1 life counter.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Select the C64 Screen window again, and use your gamepad or the keyboard to move the player into harm&amp;rsquo;s way until they run out of shields and lose a life. The number of lives shown in the top display reduces to 3. Press &lt;kbd&gt;F10&lt;/kbd&gt; to pause the emulation.&lt;/p&gt;
&lt;p&gt;One of the addresses that meet the filter criteria in the Memory Monitor is $0011. Let&amp;rsquo;s take another guess that this is player 1&amp;rsquo;s life count. This is a good guess for at least two reasons. It&amp;rsquo;s an address in the Zero Page (addresses $0000-$00FF), which is a common place to put variables. It&amp;rsquo;s also the only row that doesn&amp;rsquo;t flicker while the emulation is running.&lt;/p&gt;
&lt;p&gt;On the row showing address $0011, click the &amp;ldquo;Memory&amp;rdquo; button. This updates the C64 Memory window to highlight that location. As expected, its value is currently $03. Now change this value: select the Memory window, then type &lt;code&gt;07&lt;/code&gt;. Press the &lt;kbd&gt;F11&lt;/kbd&gt; key to unpause the emulator.&lt;/p&gt;
&lt;p&gt;Hmmm, the number of player lives on the screen still shows &amp;ldquo;3.&amp;rdquo; Was our guess incorrect? Try killing off the player one more time. Success! The life count now reads &amp;ldquo;6,&amp;rdquo; one less than the value we set. Double-check that the value at address $0011 is now $06.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_l6.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/crossroads-part-1/crossroads_l6.png&#34;
            width=&#34;263&#34;
            height=&#34;81&#34;
            alt=&#34;The Crossroads status bar, showing that player 1 now has 6 lives&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Player 1 now has 6 lives.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When we dig deeper into the machine code next month, we should expect to find instructions that manipulate address $0011, and can probably assume that the code is related to the number of lives of player 1. We can use that information and some inductive reasoning to determine the purpose of the surrounding code, and figure out the rest of the program.&lt;/p&gt;
&lt;p&gt;We got a bit lucky with our guesses in this example, though truthfully many games store the number of player lives this way. What if our guesses were wrong, and the number of lives wasn&amp;rsquo;t stored as a non-negative integer in a byte value? One possible strategy would be to locate the code that updated the &amp;ldquo;4&amp;rdquo; on the screen to a &amp;ldquo;3.&amp;rdquo; We could use the Memory Monitor against the screen codes for those characters, or we could locate the screen memory address and ask Retro Debugger to tell us which instruction last changed it. It might be possible to figure out from nearby code where it reads the value that it displays, and how the value is interpreted.&lt;/p&gt;
&lt;h2 id=&#34;more-things-to-try&#34;&gt;More things to try&lt;/h2&gt;
&lt;p&gt;Retro Debugger comes packed with plenty of toys for messing with the state of the emulator. Browse the menus and experiment! Most menu items open a new window with interesting features. Here are just a few ideas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Locate that first instruction.&lt;/strong&gt; Recall that the BASIC bootstrap invokes the machine code at address 2300, or $08FC in hexadecimal. Pause the emulator by pressing &lt;kbd&gt;F10&lt;/kbd&gt;. Select the C64 Disassembly window, type &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;G&lt;/kbd&gt; (or &lt;kbd&gt;Command&lt;/kbd&gt;+&lt;kbd&gt;G&lt;/kbd&gt; for macOS) to go to address $08FC. We can see that the first few instructions initialize some hardware registers: $D40E, $D40F, $D412. You can look up these addresses in &lt;a href=&#34;https://sta.c64.org/cbm64mem.html&#34;&gt;C64 technical documentation&lt;/a&gt; to see what they do. Researching all of the code this way is a bit tedious, but it&amp;rsquo;s fun to see the code sitting right there in memory. We&amp;rsquo;ll use a more powerful tool for investigating this code in next month&amp;rsquo;s Digest.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Watch the SID chip make sound.&lt;/strong&gt; Open the C64 menu, then the C64 SID sub-menu, then the C64 SID tool. The C64 SID window opens, showing information about the SID chip&amp;rsquo;s three sound voices. (Check out &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/&#34;&gt;one of the earliest Digest issues&lt;/a&gt; for an introduction to the SID chip.) Keep this window open, play the game for a bit, and watch the SID waveforms as the enemies duke it out.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Draw on the screen.&lt;/strong&gt; Open the VIC Editor menu, and select Show VIC Editor. This window resembles the screen, and by default shows the tile grid and the pixel grid. This is a powerful tool for updating the VIC data in real time, and there&amp;rsquo;s quite a bit of documentation of its features in &lt;a href=&#34;https://github.com/slajerek/RetroDebugger/blob/master/docs/README-C64-65XE-NES-Debugger.txt&#34;&gt;the text file&lt;/a&gt;. For now, select the C64 VIC Editor window, then left-click on an empty space on the &lt;em&gt;Crossroads&lt;/em&gt; maze. It fills in with a character. Try making a wall of characters in the maze. Another discovery! The characters block the path of creatures, and the player! It is likely that the game code reads screen memory directly to detect whether a creature is adjacent to a wall.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Watch for sprites.&lt;/strong&gt; The VIC Editor highlights sprites with a red box. If you zoom out in this window with the mouse scroll wheel, you can see that &lt;em&gt;Crossroads&lt;/em&gt; keeps the sprites off screen when not in use. Play the game to cause explosion effects as shields and creatures are destroyed. Notice that the red boxes appear around the explosions in progress, then retreat out of view when no longer needed.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;We&amp;rsquo;ve only scratched the surface of what Retro Debugger can do, and we&amp;rsquo;ve already learned quite a bit about how &lt;em&gt;Crossroads&lt;/em&gt; works. We&amp;rsquo;ll be able to apply this knowledge as we start investigating the code.&lt;/p&gt;
&lt;p&gt;Next month, we&amp;rsquo;ll introduce &lt;a href=&#34;https://ghidra-sre.org/&#34;&gt;Ghidra&lt;/a&gt;, a powerful tool for inspecting machine code. With some effort and ingenuity, we&amp;rsquo;ll be able to produce a complete human-readable assembly language source listing for the game—the listing that Compute!&amp;rsquo;s Gazette refused to print.&lt;/p&gt;
&lt;p&gt;Before you ask: no, there is currently no real-time memory visualization tool like Retro Debugger for the MEGA65 or the &lt;a href=&#34;https://github.com/lgblgblgb/xemu&#34;&gt;Xemu emulator&lt;/a&gt;. Yes, it would be cool. LGB tells me more work is needed on Xemu before it can support real-time memory visualization. In the short term, we&amp;rsquo;re more likely to see investment in the serial debugging protocol and tools like &lt;a href=&#34;https://github.com/MEGA65/m65dbg&#34;&gt;m65dbg&lt;/a&gt;, which can be used with both the Xemu emulator and with real MEGA65 hardware over a &lt;a href=&#34;https://dansanderson.com/mega65/welcome/using-jtag.html&#34;&gt;JTAG connection&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This Digest is made possible by an amazing group of supporters. Only supporters are allowed to complain when the feature article isn&amp;rsquo;t specifically about the MEGA65. To become a supporter, visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;More next month!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/crossroads-part-1/M65Digest_2024Nov.mp3" length="48165532" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>2408</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/crossroads-part-1/crossroads_cartoon.png"/>
      
    </item>
    
    <item>
      <title>Building a Sega game controller adapter</title>
      <link>https://dansanderson.com/lab-notes/sega-adapter/</link>
      <pubDate>Wed, 13 Nov 2024 14:40:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/lab-notes/sega-adapter/</guid>
      <description>&lt;p&gt;Thanks to the sega-adapter project by Eyvind Bernhardsen and the 8bitDo Retro Receiver, I can connect my Nintendo Switch Pro game controller to my MEGA65.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Thanks to the sega-adapter project by Eyvind Bernhardsen and the 8bitDo Retro Receiver, I can connect my Nintendo Switch Pro game controller to my MEGA65.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/sega-adapter/sega-adapter.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/sega-adapter/sega-adapter.jpeg 617w, https://dansanderson.com/lab-notes/sega-adapter/sega-adapter_hu_b237bc9219b99954.jpeg 600w, https://dansanderson.com/lab-notes/sega-adapter/sega-adapter_hu_c4516cb81a7abb30.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/sega-adapter/sega-adapter.jpeg&#34;
        alt=&#34;An assembled sega-adapter.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An assembled sega-adapter.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Last month, I published &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/&#34;&gt;a feature article for my MEGA65 newsletter about Commodore-compatible game controllers&lt;/a&gt;. I mentioned &lt;a href=&#34;https://github.com/eyvind/sega-adapter/tree/master&#34;&gt;the sega-adapter project&lt;/a&gt; by Eyvind Bernhardsen, a fun way to connect Sega Genesis-style game controllers to Commodore computers. These aren&amp;rsquo;t for sale pre-assembled anywhere, but they looked easy to assemble, so I ordered some boards and parts. I&amp;rsquo;m happy to report that it&amp;rsquo;s a fun and easy project!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-connected.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-connected.jpeg 640w, https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-connected_hu_ba4ba265b0d9ff0d.jpeg 600w, https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-connected_hu_50099ea6dba2862c.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-connected.jpeg&#34;
        alt=&#34;The 8bitDo Retro Receiver and sega-adapter, connected to a MEGA65.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The 8bitDo Retro Receiver and sega-adapter, connected to a MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;a href=&#34;https://en.wikipedia.org/wiki/Sega_Genesis&#34;&gt;Sega Genesis&lt;/a&gt; (aka Mega Drive) game console had a controller that was well liked at the time. It used the same 9-pin connector as Commodore and Atari computers, but did not use the same wiring protocol. Don&amp;rsquo;t try connecting one directly to a a Commodore! This will likely damage the Commodore&amp;rsquo;s sensitive CIA chip. Some people like the Genesis controller so much that there&amp;rsquo;s demand for an adapter that allows it. &lt;a href=&#34;https://retrorewind.ca/64-amiga-genesis-adapter&#34;&gt;Here&amp;rsquo;s a simple adapter available from Retro Rewind&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The sega-adapter project uses an inexpensive PIC microcontroller that translates the signals and adds useful features, such as the ability to switch button configurations simply by holding certain buttons. I was especially interested in this design because it supports the 3-button protocol that I describe in the newsletter, an extension of the Commodore 64GS controller protocol for multi-button gaming beyond the original one-button Atari joystick. Because the PIC is re-programmable, I imagine it might be possible to support the &lt;a href=&#34;https://github.com/crystalct/5plusbuttonsJoystick&#34;&gt;5plusbuttonsJoystick&lt;/a&gt; protocol as well, though I haven&amp;rsquo;t tried this yet.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/sega-adapter/switchpro.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/sega-adapter/switchpro.jpeg 640w, https://dansanderson.com/lab-notes/sega-adapter/switchpro_hu_ab6ab74bddd6c315.jpeg 600w, https://dansanderson.com/lab-notes/sega-adapter/switchpro_hu_389e6414763e94d3.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/sega-adapter/switchpro.jpeg&#34;
        alt=&#34;Controlling a MEGA65 with a Switch Pro controller, 8bitDo Retro Receiver, and sega-adapter&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Controlling a MEGA65 with a Switch Pro controller, 8bitDo Retro Receiver, and sega-adapter.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;As recommended in the sega-adapter documentation, this project works especially well with the &lt;a href=&#34;https://www.8bitdo.com/retro-receiver-genesis-mega-drive/&#34;&gt;8bitDo Retro Receiver for Sega Genesis&lt;/a&gt; (&lt;a href=&#34;https://www.amazon.com/8Bitdo-Retro-Bluetooth-Receiver-Original-Genesis/dp/B07MSWGSJY&#34;&gt;$16 on Amazon&lt;/a&gt;). The 8bitDo Retro Receiver pairs with almost any modern Bluetooth game controller, including Nintendo, Playstation, and older Xbox controllers (but not newer Bluetooth LE Xbox controllers). 8bitDo also makes a Bluetooth Sega Genesis gamepad; be sure to get the &lt;a href=&#34;https://www.amazon.com/dp/B07MSN1NPC&#34;&gt;M30 Bluetooth model&lt;/a&gt;, not the &amp;ldquo;M30 2.4G wireless&amp;rdquo; model. Within minutes of assembling my first sega-adapter, I got my Nintendo Switch Pro controller to be a 3-button game controller for my MEGA65!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/sega-adapter/m30-rr.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/lab-notes/sega-adapter/m30-rr.png 1200w, https://dansanderson.com/lab-notes/sega-adapter/m30-rr_hu_f412b64d551643c6.png 600w, https://dansanderson.com/lab-notes/sega-adapter/m30-rr_hu_ba3586ea05f649b6.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/sega-adapter/m30-rr.png&#34;
        alt=&#34;The 8bitDo Retro Receiver for Sega Genesis (and adapters)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The 8bitDo Retro Receiver for Sega Genesis (and adapters).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The sega-adapter is uses the following parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A small custom circuit board&lt;/li&gt;
&lt;li&gt;A 9-pin male connector, for the incoming Sega Genesis controller signal (such as the 8bitDo Retro Receiver)&lt;/li&gt;
&lt;li&gt;A PIC microcontroller&lt;/li&gt;
&lt;li&gt;A capacitor&lt;/li&gt;
&lt;li&gt;Header pins, and a &amp;ldquo;pigtail&amp;rdquo; cable for the 9-pin female connector that goes to the MEGA65 (or what have you)&lt;/li&gt;
&lt;li&gt;Optional header pins and jumper to switch between C64 and Amiga modes—or you can just use solder to set it to C64 mode permanently&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s it. If you buy &lt;a href=&#34;https://github.com/eyvind/sega-adapter/tree/master/kicad#bom&#34;&gt;the exact parts recommended by the project&lt;/a&gt;, everything goes together using a soldering iron and something to apply crimping force to the pigtail&amp;rsquo;s ribbon cable. I got the boards from &lt;a href=&#34;https://oshpark.com/&#34;&gt;OSHPark&lt;/a&gt; and parts from &lt;a href=&#34;https://www.digikey.com/&#34;&gt;Digikey&lt;/a&gt;, for a total unit cost of about $16 each for a batch of ten adapters. The recommended 9-pin connectors were the most expensive parts, and you might be able to find cheaper ones in different form factors, if you&amp;rsquo;re willing to get crafty. I appreciated how the project&amp;rsquo;s design and parts list were chosen to be easy to assemble.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-assembly.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-assembly.jpeg 640w, https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-assembly_hu_b29646c964d8c587.jpeg 600w, https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-assembly_hu_20b4d5beae40b6d4.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/sega-adapter/sega-adapter-assembly.jpeg&#34;
        alt=&#34;A closer look at the assembled sega-adapter board.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A closer look at the assembled sega-adapter board. The pigtail connects via IDC connector pins.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You also need an inexpensive PIC microcontroller programmer such as a generic &amp;ldquo;PICKit3&amp;rdquo; device. I bought one for &lt;a href=&#34;https://www.amazon.com/dp/B07PHPBP3Y&#34;&gt;$33 on Amazon&lt;/a&gt;. I&amp;rsquo;d never worked with PIC microcontrollers before! You can spend $200+ on an official dev kit, but from what I can tell this isn&amp;rsquo;t necessary for hobbyist applications. For software, you just need the free version of &lt;a href=&#34;https://www.microchip.com/en-us/tools-resources/develop/mplab-x-ide&#34;&gt;Microchip MPLAB X IDE&lt;/a&gt; and the &lt;a href=&#34;https://github.com/eyvind/sega-adapter/releases&#34;&gt;pre-built release of the sega-adapter .hex file&lt;/a&gt;. Of course, the source is also available, and MPLAB X can compile it if you want to customize.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/sega-adapter/segaadapter-programming.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/sega-adapter/segaadapter-programming.jpeg 445w, https://dansanderson.com/lab-notes/sega-adapter/segaadapter-programming_hu_ed3bb15c013e56a8.jpeg 600w, https://dansanderson.com/lab-notes/sega-adapter/segaadapter-programming_hu_a7731daa19e86b31.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/sega-adapter/segaadapter-programming.jpeg&#34;
        alt=&#34;The PIC microcontroller connected to the PICKit3 and 5V DC power for programming.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The PIC microcontroller connected to the PICKit3 and 5V DC power for programming.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To program the PIC, put it on a breadboard, then connect five of the wires of the PICKit3 to pins of the PIC, as described in the pinout diagrams (which I&amp;rsquo;m including below). Leave the sixth wire disconnected. You also need to apply about 5 volts of DC power across the PIC power pins. The PICKit3 does &lt;em&gt;not&lt;/em&gt; supply power the microcontroller, and it needs to be powered to accept programming. You can use a little battery box, a wall wart of appropriate voltage, or a bench power supply.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/sega-adapter/pic_pinout.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/lab-notes/sega-adapter/pic_pinout.png&#34;
            width=&#34;367&#34;
            height=&#34;252&#34;
            alt=&#34;Pinout of the PIC 16F1847 microcontroller used by the sega-adapter&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pinout of the PIC 16F1847 microcontroller used by the sega-adapter.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/sega-adapter/pickit3_pinout.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/lab-notes/sega-adapter/pickit3_pinout.png&#34;
            width=&#34;565&#34;
            height=&#34;279&#34;
            alt=&#34;Pinout of the PICKit3 connector, and how it connects to the PIC&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pinout of the PICKit3 connector, and how it connects to the PIC
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It was a fun afternoon project, with a satisfying result. I&amp;rsquo;ve always had a nominal interest in microcontroller-based projects but never really ventured far from Arduino boards in my own projects. I feel like I finally see the light on PICs and am inspired to try using them for other things.&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>Up Up Down Down Left Right Left Right B A Start</title>
      <link>https://dansanderson.com/mega65/up-up-down-down/</link>
      <pubDate>Mon, 21 Oct 2024 19:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/up-up-down-down/</guid>
      <description>&lt;p&gt;Up Up Down Down Left Right Left Right B A Start. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for October 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Up Up Down Down Left Right Left Right B A Start. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for October 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/up-up-down-down/M65Digest_2024Oct.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/M65Digest_2024Oct.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Up Up Down Down Left Right Left Right B A Start.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_cx40.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_cx40.jpeg 539w, https://dansanderson.com/mega65/up-up-down-down/9pin_cx40_hu_d698bc6604a7a0e.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/9pin_cx40_hu_c3505b10465eed4b.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_cx40.jpeg&#34;
        alt=&#34;The Atari CX40 joystick&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Atari CX40 joystick.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Everyone who owned a Commodore 64 had at least one joystick, a game controller consisting of a lever that could be pushed in eight directions and a single action button. Games based on this controller typically involved the player using the stick to move an avatar—a spaceship, a person, a creature—as well as pushing the action button to activate a weapon against some enemies. The button on this kind of joystick was almost universally referred to as the &amp;ldquo;fire&amp;rdquo; button for how often it was used to launch missiles or shoot bullets.&lt;/p&gt;
&lt;p&gt;Then came the Nintendo Entertainment System with its gamepad controller, a plastic rectangle with a directional thumb pad, two action buttons, and two more business-like buttons intended for pausing the game and accessing menus. NES games, especially &lt;a href=&#34;https://en.wikipedia.org/wiki/Super_Mario_Bros.&#34;&gt;Super Mario Bros.&lt;/a&gt; and &lt;a href=&#34;https://en.wikipedia.org/wiki/The_Legend_of_Zelda&#34;&gt;The Legend of Zelda&lt;/a&gt;, popularized a new game design language based on the two action buttons. While Mario-like platform games were made for the C64 and its one-button joystick, expecting the player to shove the joystick forward (&amp;ldquo;up&amp;rdquo;) to jump, every generation of gamers that followed the NES expected to be able to jump in a platform game by pressing one of the two action buttons.&lt;/p&gt;
&lt;p&gt;The vast majority of C64 games used the one-button joystick protocol. But there have been several attempts, both vintage and modern, to bring multi-button gaming to the C64, and to other computers with 9-pin joystick ports. This is of particular interest to modern retro game developers who want to use multi-button game design conventions while coding for the C64 and MEGA65.&lt;/p&gt;
&lt;p&gt;In this Digest, we&amp;rsquo;ll explore a bit of the history of 9-pin game controllers, and investigate several methods used to implement multi-button schemes. We&amp;rsquo;ll look at the fundamentals of game controller electronics, and game controller programming. We&amp;rsquo;ll also take a closer look at several modern game controllers and controller adapters you can buy today for your MEGA65.&lt;/p&gt;
&lt;p&gt;But first news!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;more-mega65-parts-available-separately&#34;&gt;More MEGA65 parts available separately&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/mega65_keyboard.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/mega65_keyboard.jpeg 1737w, https://dansanderson.com/mega65/up-up-down-down/mega65_keyboard_hu_e5a8457c0abb24bd.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/mega65_keyboard_hu_98348ae45aef2d17.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/mega65_keyboard.jpeg&#34;
        alt=&#34;MEGA65 replacement keyboard&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MEGA65 replacement keyboard, one of several MEGA65 parts now available separately.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/&#34;&gt;Last month&lt;/a&gt;, we noticed that Trenz Electronic is now &lt;a href=&#34;https://shop.trenz-electronic.de/en/TE0765-06-T002CK-MEGA65-Mainboard-without-housing?c=564&#34;&gt;making the MEGA65 mainboard available for preorder&lt;/a&gt; as a standalone part. Trenz has since added more MEGA65 parts to &lt;a href=&#34;https://shop.trenz-electronic.de/en/Products/MEGA65/&#34;&gt;their store&lt;/a&gt;: the MEGA65 keyboard, the plastic case, the floppy drive, and the power supply. The keyboard is a sophisticated part, including the mechanical key switches, keycaps, cable, metal frame, and LEDs. The case includes other plastic bits such as the ALPS floppy drive eject button and reset button cap. You could, in theory, assemble a full MEGA65 from the spare parts available.&lt;/p&gt;
&lt;p&gt;Math wizards may notice that the cost of the parts all together add up to more than the cost of a complete MEGA65. I can&amp;rsquo;t speak for Trenz, but this jibes with my limited understanding of the microeconomics of short-run niche electronics. Without economies of scale, Trenz has to account for labor, logistics, and potential lossage to support the individual items, even when pulling from the same stock they use to assemble full units. As deft puts it, &amp;ldquo;Imagine buying a car one piece at a time.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m grateful that they&amp;rsquo;re making these available, so we have potential replacement parts, as well as options for other projects.&lt;/p&gt;
&lt;h2 id=&#34;should-i-upgrade-my-mainboard&#34;&gt;&amp;ldquo;Should I upgrade my mainboard?&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;Did you receive your MEGA65 in 2022, or buy it second-hand from someone who did? Then your computer has the revision 3 (R3) mainboard. Starting in 2024, Trenz Electronic began shipping MEGA65s with the revision 6 (R6) mainboard, which has &lt;a href=&#34;https://shop.trenz-electronic.de/media/pdf/ca/ca/31/Mega65-Pressemitteilung.pdf&#34;&gt;several changes from R3&lt;/a&gt;. If you&amp;rsquo;re unsure which MEGA65 mainboard you have, you can double-check which one you have in the MegaInfo panel: open the Freezer (hold Restore for one second, then release), then press &lt;kbd&gt;Help&lt;/kbd&gt;. It&amp;rsquo;ll say which one you have next to &amp;ldquo;MEGA65 Model.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Should owners of the R3 board upgrade to the R6? Probably not. It is unlikely that a difference between the R3 and R6 mainboards would be worth the cost of a new mainboard to most R3 owners. The differences may not even be noticeable.&lt;/p&gt;
&lt;p&gt;There are a few notable categories of changes between the R3 and R6 boards: bidirectional cartridge and joystick I/O lines, an added SDRAM chip, and electrical fixes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bidirectional cartridge lines.&lt;/strong&gt; The original R3 mainboard supports the vast majority of cartridges made for the Commodore 64, which provide program data as input to the computer. It will also support cartridges made for the MEGA65 in the future. The cartridge port changes in the R6 board apply to a few electronically fancy cartridges that communicate with the computer using both input and output. For example, the &lt;a href=&#34;https://www.mssiah.com/&#34;&gt;MSSIAH MIDI interface cartridge&lt;/a&gt; works with the C64 core, and requires the R6 mainboard. EasyFlash 3 is also known to require the R6. Notably, an EasyFlash 1 cartridge can be both read from and written to by an R3 MEGA65. That&amp;rsquo;s how we&amp;rsquo;ve been testing &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/36962324/MEGA65+Style+Cartridge+Work+in+Progress&#34;&gt;the MEGA65 cartridge protocol&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bidirectional joystick port lines.&lt;/strong&gt; The original R3 mainboard also supports the vast majority of game controller peripherals for the C64, which provide input to the computer about how the user is manipulating the controller. A few unusual peripheral designs use the data lines for both input and output, to implement more buttons or other features with proprietary protocols. The R6 mainboard adds support for such protocols. See this month&amp;rsquo;s feature article for more on game controller protocols.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SDRAM chip.&lt;/strong&gt; The R6 adds an SDRAM chip that is intended to broaden the possibilities for alternate FPGA cores. It is possible that someday there could exist an alternate core that requires the R6 and doesn&amp;rsquo;t run on the R3. Personally, I think it&amp;rsquo;s worth tempering these expectations. I&amp;rsquo;ve discussed this with a bunch of people familiar with MiSTer-style core development, and they have all estimated that the most compelling alternate cores for the MEGA65—including an Amiga core—should fit the original R3 board. There may never be an alternate core that requires the SDRAM, even though it was added for this purpose. No core exists today that requires an R6, and I&amp;rsquo;m not aware of anyone working on one.&lt;/p&gt;
&lt;p&gt;Most importantly, the MEGA65 core does &lt;em&gt;not&lt;/em&gt; use the new SDRAM component. All software written for the MEGA65 will run on both R3 and R6 mainboards, now and in the foreseeable future. There are no plans to treat the SDRAM chip as a memory expansion for the MEGA65.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Minor fixes.&lt;/strong&gt; Lastly, the R6 board implements some minor fixes for known issues. If you are noticing these issues on an R3 board, you may be able to use inexpensive workarounds, such as &lt;a href=&#34;https://www.amazon.com/gp/product/B0B28GR7XY&#34;&gt;an HDMI repeater&lt;/a&gt; or a &lt;a href=&#34;https://files.mega65.org?ar=ff484da0-d942-4e9b-adf1-3b5a77acaa25&#34;&gt;replacement Real-Time Clock&lt;/a&gt;. If you&amp;rsquo;re not noticing these issues, you won&amp;rsquo;t notice the fixes with an upgrade. This category also includes a few changes to accommodate the availability of components; these changes don&amp;rsquo;t affect the functionality of the computer.&lt;/p&gt;
&lt;p&gt;I know I&amp;rsquo;ve spent a lot of money over the years indulging my &lt;a href=&#34;https://en.wikipedia.org/wiki/Fear_of_missing_out&#34;&gt;FOMO&lt;/a&gt; by buying hobby computers &amp;ldquo;just in case&amp;rdquo; I want them later, and it&amp;rsquo;d be hypocritical of me to say an R6 is not a worthy upgrade to an R3 when I own one of each. But given that a new mainboard is more than half the cost of a new MEGA65, it&amp;rsquo;s worth resisting the temptation to think other people have all of those things and you have none of them. Really, R3 and R6 are mostly identical.&lt;/p&gt;
&lt;h2 id=&#34;portland-retro-gaming-expo-2024&#34;&gt;Portland Retro Gaming Expo 2024&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/prge.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/prge.jpeg 1280w, https://dansanderson.com/mega65/up-up-down-down/prge_hu_858528a2ce607a56.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/prge_hu_5c84f405526dbb68.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/prge.jpeg&#34;
        alt=&#34;The MEGA65 at the Portland Retro Gaming Expo 2024&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The MEGA65 at the Portland Retro Gaming Expo 2024, prior to opening.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I took the MEGA65 to the &lt;a href=&#34;https://www.retrogamingexpo.com/&#34;&gt;Portland Retro Gaming Expo&lt;/a&gt; in Portland, Oregon, mere weeks after getting back from Chicago. PRGE is another massive show, but with a different vibe from VCF Midwest. As the name implies, the show is dominated by vintage gaming, with free-to-play arcade and gaming console exhibits, gaming tournaments, several concurrent tracks of talks and panels, meet-and-greet booths with voice acting and YouTube celebrities, and a massive vendor floor with multiple eras of console games and related merchandise.&lt;/p&gt;
&lt;p&gt;PRGE has always featured vintage home computing in its line-up, but representation of the home 8-bits on the vendor floor has waned as our vintage hardware has become more collectible. This year, PRGE established a &amp;ldquo;home computing&amp;rdquo; exhibit to keep some of our favorite computers in the show. My MEGA65 booth joined several large displays of Texas Instruments, Commodore, Atari, and Apple vintage equipment, as well as more obscure Z80-based computers. I sat closest to the tournament area, where competitors tore through &lt;a href=&#34;https://en.wikipedia.org/wiki/Street_Fighter&#34;&gt;Street Fighter&lt;/a&gt; and &lt;a href=&#34;https://rivalsofaether.com/&#34;&gt;Rivals of Aether&lt;/a&gt; as commentators hyped up the crowd. I was also across from the big surprise of the show, a large display by &lt;a href=&#34;https://en.wikipedia.org/wiki/Blockbuster_(Bend,_Oregon)&#34;&gt;The Last Blockbuster&lt;/a&gt;, with Blockbuster video iconography, merch, and racks of VHS tapes.&lt;/p&gt;
&lt;p&gt;My MEGA65 table was much larger and more welcoming to visitors than it was at VCF Midwest. I&amp;rsquo;m grateful to Hans, the show runner, for gifting me two tables, and for lending me a big screen TV. And I got to hang up the banner! Even in this back corner of the show floor, the MEGA65 drew a lot of attention, and I spent nearly all of the first day on my feet, answering questions, shaking hands, and handing out cards and mousepads. Several people from press outlets wanted interviews. If the fire alarm hadn&amp;rsquo;t gone off in the middle of the day, I may never have had a break for lunch. The second day was quieter, but I still had quite a few kids stop by for a round of &lt;a href=&#34;https://files.mega65.org?id=0f619bcf-63f0-43d5-b938-0ae6b87f4917&#34;&gt;Unicone&lt;/a&gt; or &lt;em&gt;First Shot&lt;/em&gt;.&lt;/p&gt;
&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/GUz5R3fmKuI?si=LdQr72BwuzIDLvGn&#34; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;It was especially gratifying to see young people take an interest in the MEGA65. Some of them already knew what it was and were excited to see it in person, some dragged their parents over to the table for a look, and several sat down at the computer for long stretches of time to peruse the demo disks and write short programs. I talked to MEGA65 owners and wannabe owners, and plenty of people simply intrigued by an 8-bit style computer that seemed familiar but unlike anything they&amp;rsquo;d seen before. I got to introduce many people to the stories of both the Commodore 65 and the MEGA65.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/blockbuster.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/blockbuster.jpeg 1280w, https://dansanderson.com/mega65/up-up-down-down/blockbuster_hu_d47ebc8df0d860ac.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/blockbuster_hu_eb6559596b981d4e.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/blockbuster.jpeg&#34;
        alt=&#34;The Last Blockbuster&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The Last Blockbuster&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;new-ti-994a-core&#34;&gt;New TI-99/4A core&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/ticore.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/ticore.jpeg 960w, https://dansanderson.com/mega65/up-up-down-down/ticore_hu_8f6043ef978d9ed0.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/ticore_hu_6d58d1026e567772.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/ticore.jpeg&#34;
        alt=&#34;Mega99, a TI-99/4A core by zeldin.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Mega99, a TI-99/4A core by zeldin.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;My very first computer was a Texas Instruments TI-99/4A, and now thanks to zeldin, I can recreate those childhood memories! &lt;a href=&#34;https://files.mega65.org?id=a25ce133-ed07-4ef7-8495-179d69c43ed0&#34;&gt;Mega99&lt;/a&gt; is a TI-99/4A core, written from scratch exclusively for the MEGA65. The core needs &lt;a href=&#34;https://ftp.whtech.com/System%20ROMs/MAME/&#34;&gt;the ROM files from the MAME project&lt;/a&gt; (&lt;code&gt;ti99_4a.zip&lt;/code&gt;, &lt;code&gt;ti99_fdc.zip&lt;/code&gt;, and &lt;code&gt;ti99_speech.zip&lt;/code&gt;) as well as the provided &lt;code&gt;mega99sp.bin&lt;/code&gt; file in the root of the SD card. Flash the core to a spare slot in the core selection menu.&lt;/p&gt;
&lt;p&gt;As of this writing, the core is only available for the R6 boards. This is not a matter of hardware capacity, and hopefully zeldin can produce a build for R3 owners in the future.&lt;/p&gt;
&lt;p&gt;Be sure to read the &lt;code&gt;README.md&lt;/code&gt; file for installation and usage instructions. The core matches the 99/4A CPU timing by default, and can also run in a turbo mode. And get yourself &lt;a href=&#34;http://dunfield.classiccmp.org/ti/usrguide.pdf&#34;&gt;the TI-99/4A User&amp;rsquo;s Guide&lt;/a&gt; to remind yourself how this thing works! Hint: the Mega key is the FUNC key, and many text entry features use it.&lt;/p&gt;
&lt;p&gt;Thank you zeldin for this excellent and nostalgic core!&lt;/p&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/shodan.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/shodan.png 1024w, https://dansanderson.com/mega65/up-up-down-down/shodan_hu_dde608819cc49a89.png 600w, https://dansanderson.com/mega65/up-up-down-down/shodan_hu_58e0c2c36c8edc8b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/shodan.png&#34;
        alt=&#34;Shodan, by Drex&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Shodan, by Drex&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Here are some recent demos uploaded to Filehost worth checking out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=26c503ff-571c-44a2-af02-46e8a5d8476d&#34;&gt;Shodan&lt;/a&gt;, by Drex.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=ce0c4812-5eab-428b-b220-524f6324c507&#34;&gt;3D functions&lt;/a&gt; and &lt;a href=&#34;https://files.mega65.org?id=032a01e4-219c-450d-9dee-051dbd7c8133&#34;&gt;Patterns&lt;/a&gt;, by adorigatti.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=1b20b366-9177-4739-8420-c74f911a7202&#34;&gt;HyperBallad&lt;/a&gt;, by MirageBD.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;h2 id=&#34;joytest65&#34;&gt;Joytest65&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/joytest65_1.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/joytest65_1.png 1040w, https://dansanderson.com/mega65/up-up-down-down/joytest65_1_hu_1a0304615e4f0e78.png 600w, https://dansanderson.com/mega65/up-up-down-down/joytest65_1_hu_23adec0e14b96e10.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/joytest65_1.png&#34;
        alt=&#34;joytest65, a joystick and paddle tester for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
joytest65, a joystick and paddle tester for the MEGA65
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This month&amp;rsquo;s Digest is all about joystick and paddle programming, so I made a joystick and paddle tester app to go with it. It includes documentation and assembly language source code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=671054f3-45ed-4b88-957c-fd7a55c67b2d&#34;&gt;Download joytest65 from Filehost&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-9-pin-connector&#34;&gt;The 9-pin connector&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_ports.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_ports.jpeg 1280w, https://dansanderson.com/mega65/up-up-down-down/9pin_ports_hu_3b3111bca0bae0db.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/9pin_ports_hu_1357fdae88f0a415.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_ports.jpeg&#34;
        alt=&#34;MEGA65 joystick ports, and a peripheral connector&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGA65 joystick ports, and a peripheral connector.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The C64 was one of several early computers that adopted the &lt;a href=&#34;https://en.wikipedia.org/wiki/Atari_joystick_port&#34;&gt;Atari joystick port&lt;/a&gt; standard from the &lt;a href=&#34;https://en.wikipedia.org/wiki/Atari_2600&#34;&gt;Atari 2600&lt;/a&gt; (1977), and supported the use of Atari game controllers to play C64 games. I&amp;rsquo;m most familiar with the classic &lt;a href=&#34;https://en.wikipedia.org/wiki/Atari_CX40_joystick&#34;&gt;Atari CX40 joystick&lt;/a&gt;, but there were &lt;a href=&#34;https://www.ataricompendium.com/game_library/controllers/controllers.html&#34;&gt;many others&lt;/a&gt;, and everyone has a favorite. Commodore used the Atari-style controller connector on everything from the VIC-20 to the Amiga, and they intended the C65 to have two 9-pin peripheral ports, just like the C64. The MEGA65 has two 9-pin peripheral ports on the left-hand side.&lt;/p&gt;
&lt;p&gt;Nintendo released the NES in the USA with a proprietary controller connector and more buttons, and the game console arms race that followed produced more custom connectors, more buttons, and more evolutions in game design language. Commodore made two attempts to follow suit in their final years, both using new protocols over the original Atari-style connector: the &lt;a href=&#34;https://en.wikipedia.org/wiki/Commodore_64_Games_System&#34;&gt;C64GS&lt;/a&gt; and the &lt;a href=&#34;https://en.wikipedia.org/wiki/Amiga_CD32&#34;&gt;Amiga CD32&lt;/a&gt;. These protocols were backwards compatible with older Commodore computers, and the new consoles also supported the one-button controllers and ran compatible games.&lt;/p&gt;
&lt;p&gt;Commodore also made several types of computer mice that used the 9-pin connector, especially the 1351 mouse for the 8-bit computers, and the Amiga mouse. As you probably know by now, your MEGA65 supports both types of mice, using built-in adapter logic to make the Amiga mouse appear to software as a 1351. See the &lt;a href=&#34;https://files.mega65.org/?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt;, for information on how to configure the mouse emulation mode. We won&amp;rsquo;t cover the mice protocols in this issue of the Digest.&lt;/p&gt;
&lt;p&gt;What follows is a description of how Atari and Commodore computers use the 9-pin connector for game controllers. Other 8-bit computers and early game consoles used the connector, but not necessarily the same wiring or protocols.&lt;/p&gt;
&lt;h2 id=&#34;joystick-fundamentals&#34;&gt;Joystick fundamentals&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_pinout.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_pinout.png&#34;
            width=&#34;261&#34;
            height=&#34;174&#34;
            alt=&#34;Diagram of the 9-pin connector and port, with pins numbered&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The 9-pin connector and port, with pins numbered.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A standard 9-pin one-button joystick tells the computer that the action button is being pressed by connecting pin #6 to pin #8 (the ground pin, labeled &amp;ldquo;GND&amp;rdquo;). This doesn&amp;rsquo;t require any fancy electronics, it&amp;rsquo;s typically just a button connected to these two pins. When the player presses down on the button, two pieces of metal in the button make contact, completing an electronic circuit. When the player releases the button, a mechanical spring-like action separates the two pieces of metal, breaking the circuit and signaling to the computer that the button was released. This kind of button is also known as a &lt;em&gt;momentary switch.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Pins #1, #2, #3, and #4 work similarly, representing the joystick directions up, down, left, and right, respectively, when connected to pin #8. The joystick indicates a diagonal direction by completing two circuits simultaneously, such as up and left. Typically, there are no fancy electronics involved here either. The joystick is built such that when the user pushes on the stick, it closes one or two momentary switches wired to those pins.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_joystick_inside.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_joystick_inside.jpeg 1213w, https://dansanderson.com/mega65/up-up-down-down/9pin_joystick_inside_hu_e4b102a09919fb98.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/9pin_joystick_inside_hu_29c35047e5f8812d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_joystick_inside.jpeg&#34;
        alt=&#34;Inside an Atari CX40 joystick: it&amp;amp;#39;s just membrane switches&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Inside an Atari CX40 joystick. It&#39;s just membrane switches.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Within the MEGA65, these pins are connected to the Complex Interface Adapter (CIA) chip, which translates these electronic signals into register values that can be read by a program. Try this: connect a joystick to port 2, and run the following simple program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 PRINT PEEK($DC00)
20 GOTO 10&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The program prints the number 127 repeatedly. Move the joystick and press the fire button. The number changes depending on which buttons are pressed.&lt;/p&gt;
&lt;p&gt;This register value is a bit field, where each button is assigned to a bit. If the button is not pressed, the bit is 1 (&amp;ldquo;high&amp;rdquo;). If the button is pressed, the bit is 0 (&amp;ldquo;low&amp;rdquo;). This is why the register value is 127 when no buttons are pressed: all of the bits associated with the buttons are &amp;ldquo;held high&amp;rdquo; until they are &amp;ldquo;pulled low&amp;rdquo; by the button presses. (The register has additional bits not connected to the joystick pins.)&lt;/p&gt;
&lt;p&gt;The one-button 8-direction joystick protocol can be summarized as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Buttons connect pin to GND; CIA bit = 0 when pressed&lt;/li&gt;
&lt;li&gt;Pin #1: Up, CIA bit 0&lt;/li&gt;
&lt;li&gt;Pin #2: Down, CIA bit 1&lt;/li&gt;
&lt;li&gt;Pin #3: Left, CIA bit 2&lt;/li&gt;
&lt;li&gt;Pin #4: Right, CIA bit 3&lt;/li&gt;
&lt;li&gt;Pin #6: Fire, CIA bit 4&lt;/li&gt;
&lt;li&gt;Pin #8: Ground (GND)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;%01111111 = 127

%01111110 = 126: up
%01111010 = 122: up and left
%01101010 = 106: up, left, and fire&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is the program&amp;rsquo;s responsibility to read these register values, do the math, then change the game state appropriately, such as to move the player sprite around the screen.&lt;/p&gt;
&lt;p&gt;Like the C64, the MEGA65 has two CIA chips. Only the first CIA is used to read the joystick ports. And yes, these are the same CIA chips that provide &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/&#34;&gt;timers and other features&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;the-cia-and-port-1&#34;&gt;The CIA and port 1&lt;/h3&gt;
&lt;p&gt;Register $DC00 represents joystick port 2. To read the status of joystick port 1, you read register $DC01.&lt;/p&gt;
&lt;p&gt;C64 owners remember this one: with a joystick connected to port 1 and the cursor at the &lt;code&gt;READY&lt;/code&gt; prompt, you can get junk to show up on the screen just by jiggling the stick around. This is no longer true with the MEGA65 in MEGA65 mode (as of release v0.96), but you can still reproduce this in &lt;code&gt;GO64&lt;/code&gt; mode or the C64 core. Try it!&lt;/p&gt;
&lt;p&gt;The C64 uses the CIA chip connected to the joystick ports for multiple purposes. This includes reading the keyboard. When you type on the keyboard, it pulls down the CIA bits in certain patterns, just like a joystick on port 1 does. This is why, when the C64 is expecting keyboard input, a joystick in port 1 moving around can seem like typing. Even though you can prevent this effect in code for a game, many C64 games simply assumed that most people would keep their joystick connected to port 2.&lt;/p&gt;
&lt;p&gt;The MEGA65 is better behaved because its keyboard handling uses a different mechanism that is not as reliant on the CIA chip. A couple of specific functions still test the CIA for specific key presses, but in general, port 1 joystick events are much less likely to interfere with the keyboard.&lt;/p&gt;
&lt;h3 id=&#34;reading-the-joystick-from-basic-65&#34;&gt;Reading the joystick from BASIC 65&lt;/h3&gt;
&lt;p&gt;BASIC 65 provides a handy function for reading the state of the joysticks. The &lt;code&gt;JOY(port)&lt;/code&gt; function returns a value that represents joystick activity on the requested port (1 or 2). Instead of a bit field, the &lt;code&gt;JOY()&lt;/code&gt; function returns a number from 0 to 8, where 0 means the joystick is in the center, and 1 through 8 are the eight directions counting clockwise from &amp;ldquo;up.&amp;rdquo; When the button is pressed, it adds 128 to this value. See the &lt;a href=&#34;https://files.mega65.org/?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;User&amp;rsquo;s Guide&lt;/a&gt; for a table and example program.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 PRINT JOY(2)
20 GOTO 10&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As of ROM beta version 920397, the &lt;code&gt;JOY()&lt;/code&gt; function can also read both joystick ports simultaneously, and report a merged result. To request this, use a port number of &amp;ldquo;3&amp;rdquo;: &lt;code&gt;JOY(3)&lt;/code&gt;. This is intended solely to allow a game to work with a single joystick in either port, so the player doesn&amp;rsquo;t have to change their joystick connections to play. It does not return a useful result when two joysticks are connected and moved simultaneously. If your game uses two joysticks, use &lt;code&gt;JOY(1)&lt;/code&gt; and &lt;code&gt;JOY(2)&lt;/code&gt; separately. This feature will be in the next MEGA65 stable release.&lt;/p&gt;
&lt;h3 id=&#34;reading-the-joystick-from-machine-code&#34;&gt;Reading the joystick from machine code&lt;/h3&gt;
&lt;p&gt;A machine code program can read the state of the joystick by accessing the CIA registers and interpreting the bits directly. For best results, such a program must take &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/&#34;&gt;interrupts&lt;/a&gt; into account if it leaves the &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/&#34;&gt;KERNAL interrupt handler&lt;/a&gt; active.&lt;/p&gt;
&lt;p&gt;The KERNAL interrupt handler messes with the CIA registers many times per second to process certain keyboard events. A program wanting a clean read of the CIA register must disable interrupts to prevent the handler from messing up the result.&lt;/p&gt;
&lt;p&gt;The program has to tell the CIA chip to ignore the state of the keyboard when reading the joystick. I won&amp;rsquo;t cover how this works in detail, just know that the way to do this is to write the value $FF to the data register ($DC00 or $DC01) before reading it.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the complete sequence for a clean read of port 2 in assembly language:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sei        ; Disable interrupts

ldx #$ff
stx $dc00  ; Lock out the keyboard lines on port 2

lda $dc00  ; A = port 2 pin state

ldx #$7f
stx $dc00  ; Restore the keyboard lines on port 2

cli        ; Re-enable interrupts&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;paddle-pairs-and-potentiometers&#34;&gt;Paddle pairs and potentiometers&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_paddles.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_paddles.jpeg 1584w, https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_hu_80a92a75390798f4.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_hu_da35355ddc84c1a5.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_paddles.jpeg&#34;
        alt=&#34;Paddles made by Commodore, and by Atari&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Paddles made by Commodore, and by Atari.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In addition to joysticks, the Atari controller standard also supports a &lt;a href=&#34;https://en.wikipedia.org/wiki/Paddle_(game_controller)&#34;&gt;paddle controller&lt;/a&gt;. A paddle uses a dial-like wheel instead of a joystick. A game can detect how far the wheel is turned by reading more registers. This controller is called a &amp;ldquo;paddle&amp;rdquo; after the seminal home computer game &lt;a href=&#34;https://en.wikipedia.org/wiki/Pong&#34;&gt;Pong&lt;/a&gt;, which used such a controller to manipulate a paddle in a virtual game of ping pong.&lt;/p&gt;
&lt;p&gt;Each joystick port supports &lt;em&gt;two&lt;/em&gt; paddles, each with its own dial and fire button. The MEGA65, Commodore 64, and Atari 2600 all have two joystick ports, for up to four paddle players. The two dial-like controls are also used together by peripherals such as light pens or mice, where the two inputs represent movement along X and Y axes.&lt;/p&gt;
&lt;p&gt;The paddle protocol is different from the joystick protocol. Electronically, the fire buttons are wired to joystick port pin #3 for the first paddle and pin #4 for the second paddle, connecting them to pin #8 (GND) when pressed. A program can read these pins using the CIA data registers, just like reading the joystick. The register bits read 0 when the button is pressed.&lt;/p&gt;
&lt;p&gt;The paddle dial itself is a &lt;em&gt;potentiometer&lt;/em&gt;, also known as a &lt;em&gt;variable resistor&lt;/em&gt; or &amp;ldquo;pot.&amp;rdquo; Instead of simply connecting or disconnecting the path between two pins like the fire button, the potentiometer forms an electrical connection between two pins through an amount of electrical resistance that the computer can measure. When the player turns the knob, the amount of resistance changes, indicating the position of the dial. The first paddle on a port connects signal pin #5 (&amp;ldquo;POTX&amp;rdquo;) to pin #7, where the computer provides a voltage of +5V. The second paddle on the port uses signal pin #9 (&amp;ldquo;POTY&amp;rdquo;) and pin #7.&lt;/p&gt;
&lt;p&gt;The paddle protocol:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Potentiometers connect pin to +5V&lt;/li&gt;
&lt;li&gt;Buttons connect pin to GND; CIA bit = 0 when pressed&lt;/li&gt;
&lt;li&gt;Pin #3: Paddle A button, CIA bit 2&lt;/li&gt;
&lt;li&gt;Pin #4: Paddle B button, CIA bit 3&lt;/li&gt;
&lt;li&gt;Pin #5: Paddle A analog (POTX)&lt;/li&gt;
&lt;li&gt;Pin #7: +5V&lt;/li&gt;
&lt;li&gt;Pin #8: Ground (GND)&lt;/li&gt;
&lt;li&gt;Pin #9: Paddle B analog (POTY)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;resistor-values-and-register-values&#34;&gt;Resistor values and register values&lt;/h3&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_inside.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_inside.jpeg 1297w, https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_inside_hu_f760a15cf5ba7d05.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_inside_hu_84d1aaff06ef4801.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_inside.jpeg&#34;
        alt=&#34;The inside of Commodore and Atari paddles.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The inside of Commodore and Atari paddles. My Commodore paddles have a 200 kΩ potentiometer and a smoothing capacitor. My Atari paddles have a 1 MΩ potentiometer, and no cap.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Strangely, Commodore used a different potentiometer in their own paddles compared to the ones by Atari, and the two paddle types produce different numbers when accessed from a Commodore program. It is &lt;a href=&#34;https://www.atariarchives.org/ecp/chapter_4.php&#34;&gt;generally understood&lt;/a&gt;, and &lt;a href=&#34;https://www.breadbox64.com/blog/paddle-battle/&#34;&gt;some have measured&lt;/a&gt;, that Commodore paddles use a potentiometer rated at 470 kΩ (kilo-ohms), and Atari paddles are rated at 1 MΩ (mega-ohms), with the measured resistance range a bit less but on that order of magnitude. This means that when an Atari paddle is connected to a Commodore, turning the knob goes from the minimum value to the maximum value in half the rotational distance (half the &amp;ldquo;throw&amp;rdquo;) than an official Commodore paddle. In practice, this can be both good and bad: shorter throw can result in faster play, but with less accuracy and a large &amp;ldquo;dead zone&amp;rdquo; where the resistance is above the maximum recognized by the computer.&lt;/p&gt;
&lt;p&gt;I wanted to know the actual resistance value range recognized by the MEGA65, so I started by measuring the resistance of my Commodore and Atari paddles with an ohmmeter. What I discovered was a bit of a surprise.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_range.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_range.jpeg 1000w, https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_range_hu_846c221a7c15ab88.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_range_hu_f7fd24187915a74.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/9pin_paddles_range.jpeg&#34;
        alt=&#34;The measured resistance values of Commodore paddles vs. Atari paddles&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Measuring the resistance values of my Commodore and Atari paddles with an ohmmeter. My Commodore paddles measured from 44 Ω to 166 kΩ, and my Atari paddles measured from 124 Ω to 782 kΩ. I put a piece of tape on the dial to illustrate the turn range.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I took some ohmmeter measurements of my Commodore and Atari paddles, and also tested the values returned by the BASIC 65 &lt;code&gt;POT()&lt;/code&gt; function, which returns a value from 0 to 255 based on the dial setting. Both paddles had a minimum resistance in the fully clockwise position, then increased counter-clockwise to their maximum. The Commodore paddles measured a minimum of 44 Ω to a maximum of 166 kΩ. The &lt;code&gt;POT()&lt;/code&gt; function returned a value of 220 at the maximum, not the full 255. Atari paddles had a higher resistance of 124 Ω at minimum to 782 kΩ at maximum. Here, the &lt;code&gt;POT()&lt;/code&gt; function returned the full 255 after only a third of a turn, with a whopping dead zone of two thirds of a rotation, returning 255 for that portion.&lt;/p&gt;
&lt;p&gt;So I opened the cases of both sets of paddles, and discovered that my Commodore paddles have a potentiometer rated at 200 kΩ, far less than the 470 kΩ that others have reported. My Commodore paddles also have a capacitor in parallel with the signal lines, which smoothes out the signal and shouldn&amp;rsquo;t affect the DC resistance, but is notable because it is absent from other paddles. I asked some friends to open theirs and they all reported 470 kΩ pots, so I must have some weird ones.&lt;/p&gt;
&lt;p&gt;While it&amp;rsquo;s reasonable in the abstract that a Commodore program should be able to detect the full range of motion of the Commodore paddle knob, it may have turned out to be unreasonable in practice. A game expecting the full value range to represent a full turn of the knob might be unplayable with Atari paddles, and vice versa. Perhaps Commodore decided to split the difference at some point and changed to a 470 kΩ potentiometer, and I just happen to have an earlier model of the paddles.&lt;/p&gt;
&lt;p&gt;Of course, it&amp;rsquo;s possible that a previous owner of my paddles replaced the pots with the unusual values and these didn&amp;rsquo;t come from Commodore.&lt;/p&gt;
&lt;h3 id=&#34;reading-paddles-from-basic-65&#34;&gt;Reading paddles from BASIC 65&lt;/h3&gt;
&lt;p&gt;As with joysticks, BASIC 65 has a function for reading paddles: &lt;code&gt;POT(paddle)&lt;/code&gt; returns a paddle position as a number between 0 and 255, and adds 256 if the paddle&amp;rsquo;s button is pressed. The paddles on joystick port 1 are #1 and #2, and the paddles on joystick port 2 are #3 and #4.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 PRINT POT(1), POT(2), POT(3), POT(4)
20 GOTO 10&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;the-mega65-paddle-registers&#34;&gt;The MEGA65 paddle registers&lt;/h3&gt;
&lt;p&gt;The MEGA65 has dedicated circuitry and registers for reporting the four paddle values. A MEGA65 machine code program can read these values directly from registers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$D620: Port 1, paddle X&lt;/li&gt;
&lt;li&gt;$D621: Port 1, paddle Y&lt;/li&gt;
&lt;li&gt;$D622: Port 2, paddle X&lt;/li&gt;
&lt;li&gt;$D623: Port 2, paddle Y&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The fire buttons on the two paddles work just like joystick buttons, and can be read directly from the CIA data register for the appropriate port.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s all a MEGA65 programmer needs to know. On the C64, the process is a little more elaborate, and it&amp;rsquo;s interesting to know why.&lt;/p&gt;
&lt;h3 id=&#34;reading-paddles-the-old-fashioned-way&#34;&gt;Reading paddles the old-fashioned way&lt;/h3&gt;
&lt;p&gt;The CIA chip only knows how to handle digital signals (1&amp;rsquo;s and 0&amp;rsquo;s), and can&amp;rsquo;t read a resistance value (an analog value in a range). Instead, it gets the help of another chip in the chipset more familiar with converting between analog and digital signals: the SID sound chip.&lt;/p&gt;
&lt;p&gt;To read a paddle value, a program first tells the CIA to connect the SID to one of the joystick ports. The program must then wait briefly before reading the value from a SID register. The SID needs a small amount of time to read the resistance value and update the register. During this time, the SID charges an internal capacitor that is connected to the signal and voltage lines of the controller. Once it is charged, the SID flips to a different circuit that discharges it. The SID determines the resistance of the paddle controller from the amount of time it takes to perform this charge-discharge process. To convert this to a value between 0 and 255, the SID needs 512 CPU cycles. At the end of this time, the SID updates its register value.&lt;/p&gt;
&lt;p&gt;512 machine cycles at a rate of 1 MHz takes about 1/1950th of a second. That doesn&amp;rsquo;t sound like a lot, but it can be a long wait for an action game, over 10% of the time it takes to draw a frame of graphics. Of course, the program is welcome to do other things during this time. A game loop could set the CIA select bits at the beginning of the frame, then read the paddle values near the end of the game logic, adding a busy-wait at the end as needed.&lt;/p&gt;
&lt;p&gt;The SID can only be connected to one joystick port at a time. To read paddles from both ports, a program must connect to the first port, wait the 512 cycles, read the SID registers, then connect to the second port, wait another 512 cycles, and read the SID registers again. A game that reads all four paddles may or may not need to be clever to use the waiting time wisely, depending on how much time the game needs per frame.&lt;/p&gt;
&lt;p&gt;If the program leaves the SID connected to a single port and takes over the hardware interrupt vectors (such that the KERNAL interrupt handler isn’t messing with the CIA connections), it can skip the wait and just read the SID register at its convenience. The register will contain the last stable value.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.c64-wiki.com/wiki/Paddle&#34;&gt;The C64 Wiki page on paddles&lt;/a&gt; has a diagram of the &lt;a href=&#34;https://en.wikipedia.org/wiki/RC_circuit&#34;&gt;resistor-capacitor circuit&lt;/a&gt; that the SID is using to measure the resistance value in the controller. I was confused at first because the diagram makes it look like the capacitor is provided by the paddle controller, outside of the joystick port. This is not the case: the SID provides the capacitor part of the RC circuit. The capacitor present in my Commodore paddles bridges the +5V and signal lines, and is there for smoothing purposes and is not part of the RC timing circuit. Other paddles don&amp;rsquo;t have the smoothing capacitor.&lt;/p&gt;
&lt;h3 id=&#34;the-c64-way-to-read-paddles-from-machine-code&#34;&gt;The C64 way to read paddles from machine code&lt;/h3&gt;
&lt;p&gt;A C64 machine code program must perform the full procedure to read an analog value from the SID chip: select the port to connect the SID chip, wait briefly, then read the result from a SID register.&lt;/p&gt;
&lt;p&gt;To select the port, set bits 6 and 7 of register $DC00: for joystick port 1, set bit 6 = 1 and bit 7 = 0; for joystick port 2, set bit 6 = 0, bit 7 = 1. This is the same address as the CIA data register for reading joystick pins on port 2, but you use this address even when connecting the SID to joystick port 1. That&amp;rsquo;s just how the CIA chip is wired.&lt;/p&gt;
&lt;p&gt;The program then waits briefly for the SID to get the value. On a C64, this relatively easy: perform a busy-wait loop for some number of iterations. Based on a reference table of cycle counts per instruction, you probably only need 103 or so repetitions of a loop, but it doesn’t hurt to wait longer. The C64 CPU runs at 1 MHz, so 512 CPU cycles is sufficient.&lt;/p&gt;
&lt;p&gt;(The MEGA65 normally runs its CPU at 40 MHz. To reproduce the SID reading procedure, you have two options: temporarily down-clock the CPU to 1 MHz for the busy-wait, or perform the busy-wait loop 40 times. Note that instruction cycle counts differ on the 45GS02 CPU than on the 6502.)&lt;/p&gt;
&lt;p&gt;After the delay, the values of the two paddles can be read from SID registers $D419 and $D41A. The ROM code that implements the BASIC &lt;code&gt;POT()&lt;/code&gt; function takes an additional step to &lt;em&gt;debounce&lt;/em&gt; the register value, which just means to wait until two consecutive reads of the register return the same value.&lt;/p&gt;
&lt;p&gt;Here is code for the complete procedure, reading the state of both paddles on port 2:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    ; Disable interrupts
    sei

    ; Down-clock MEGA65 CPU to 1 MHz
    ; FAST $D031.6 -&amp;gt; 0
    lda #$40
    trb $d031

    ; Connect SID to port 2 analog inputs
    lda #%10000000
    sta $dc00

    ; Wait for SID to read, ~512 1 MHz cycles
    ldx #$00
-   inx
    bne -

    ; Read port 2 paddles, with debounce
-   lda $d419
    cmp $d419
    bne -
    sta paddle2a

-   lda $d41a
    cmp $d41a
    bne -
    sta paddle2b

    ; Reset MEGA65 CPU to 40 MHz
    ; FAST $D031.6 -&amp;gt; 1
    lda #$40
    tsb $d031

    ; Re-enable interrupts
    cli
	
; ...

paddle2a:  !byte $00
paddle2b:  !byte $00&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;two-buttonsand-why-not-a-third&#34;&gt;Two buttons—and why not a third&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/Cheetah-Annihilator.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/Cheetah-Annihilator.jpg 1000w, https://dansanderson.com/mega65/up-up-down-down/Cheetah-Annihilator_hu_a754beee56040ee2.jpg 600w, https://dansanderson.com/mega65/up-up-down-down/Cheetah-Annihilator_hu_e962f0ee5ca3a031.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/Cheetah-Annihilator.jpg&#34;
        alt=&#34;The Cheetah Annihilator two-button joystick. Photo from c64-wiki.de.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Cheetah Annihilator two-button joystick. Photo from c64-wiki.de.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;a href=&#34;https://en.wikipedia.org/wiki/Commodore_64_Games_System&#34;&gt;Commodore 64 Games System&lt;/a&gt; (1990), aka the C64GS, repackaged the C64 into a keyboard-less console box. To enhance the console&amp;rsquo;s gaming potential, the &lt;a href=&#34;https://www.c64-wiki.de/wiki/Cheetah_Annihilator&#34;&gt;Cheetah Annihilator joystick&lt;/a&gt; had two buttons: a trigger button in the joystick grip, and a second button that could be detected separately in the base. This two-button protocol worked over the 9-pin connector and could be supported by any C64 game that knew about it. Only a few games were written to support it.&lt;/p&gt;
&lt;p&gt;Math wizards may notice that all nine of the joystick port pins have been assigned: up, down, left (or paddle A button), right (or paddle B button), paddle B (&amp;ldquo;POTY&amp;rdquo;), fire, +5V, GND, and paddle A (&amp;ldquo;POTX&amp;rdquo;). That&amp;rsquo;s nine. So how is the second button connected?&lt;/p&gt;
&lt;p&gt;In the two-button protocol, the second button uses paddle A&amp;rsquo;s analog line (pin #9, &amp;ldquo;POTX&amp;rdquo;). Unlike the other joystick buttons that connect their respective pins to pin #8 (GND, &amp;ldquo;pulled low&amp;rdquo;), this button connects pin #9 to pin #7 (+5V, &amp;ldquo;pulled high&amp;rdquo;), with a current-limiting resistor to protect the sensitive CIA and SID chips. (One &lt;a href=&#34;https://www.c64-wiki.com/wiki/Control_Port&#34;&gt;recommended resistance value&lt;/a&gt; I&amp;rsquo;ve seen is 270-330 ohms.) To a program, a button press looks like a paddle dial flipping between its minimum and maximum positions.&lt;/p&gt;
&lt;p&gt;The Cheetah Annihilator only had two action buttons, but if someone were to add a third button to such a controller, it would have an easy way to connect: just use the other paddle line (pin #5, &amp;ldquo;POTY&amp;rdquo;). This three-button protocol was uncommon in vintage joysticks, but is &lt;a href=&#34;http://wiki.icomp.de/wiki/DE-9_Joystick&#34;&gt;generally accepted&lt;/a&gt; by controller modders and homebrew controller makers, because it&amp;rsquo;s a natural extension of the two-button protocol, and doesn&amp;rsquo;t require fancy electronics beyond the button and safety resistor.&lt;/p&gt;
&lt;p&gt;The three-button protocol:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pin #1: Up, CIA bit 0&lt;/li&gt;
&lt;li&gt;Pin #2: Down, CIA bit 1&lt;/li&gt;
&lt;li&gt;Pin #3: Left, CIA bit 2&lt;/li&gt;
&lt;li&gt;Pin #4: Right, CIA bit 3&lt;/li&gt;
&lt;li&gt;Pin #5: Button C, via POTX&lt;/li&gt;
&lt;li&gt;Pin #6: Button A, CIA bit 4&lt;/li&gt;
&lt;li&gt;Pin #7: +5V&lt;/li&gt;
&lt;li&gt;Pin #8: Ground (GND)&lt;/li&gt;
&lt;li&gt;Pin #9: Button B, via POTY&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To read the complete state of a three-button controller, simply combine the techniques for joysticks and paddles. Here&amp;rsquo;s an example of reading all buttons from port 2 in BASIC:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 J = JOY(2)
20 D = J AND 128     : REM: THE DIRECTION
30 A = J &amp;gt; 127       : REM: BUTTON A
40 B = POT(3) &amp;lt; 128  : REM: BUTTON B
50 C = POT(4) &amp;lt; 128  : REM: BUTTON C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reading the additional buttons from machine code is similar to reading the paddle values. A C64 program must still connect the SID to the port, wait for the SID to sense the button value, then read the value from the SID register. A MEGA65 program can just read the paddle registers.&lt;/p&gt;
&lt;h2 id=&#34;five-buttons&#34;&gt;Five buttons??&lt;/h2&gt;
&lt;p&gt;An 8-way joystick with two or three action buttons brings Commodore gaming one step forward in 1980&amp;rsquo;s game design language. Math wizards may notice that the NES gamepad has not three but &lt;em&gt;four&lt;/em&gt; buttons: A, B, Start, and Select. Can we support all four with minimal changes to the protocol?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/crystalct/5plusbuttonsJoystick&#34;&gt;5plusbuttonsJoystick&lt;/a&gt;, by crystalct, specifies a five-button protocol using a neat trick: button #4 triggers &amp;ldquo;up&amp;rdquo; and &amp;ldquo;down&amp;rdquo; simultaneously, and button #5 is &amp;ldquo;left&amp;rdquo; and &amp;ldquo;right.&amp;rdquo; A normal joystick can&amp;rsquo;t activate these opposing directions at the same time, so they uniquely identify the buttons. This scheme has the disadvantage of not being able to use buttons #4 and #5 simultaneously with the joystick—pressing button #4 and &amp;ldquo;up&amp;rdquo; at the same time would only register the button—but they can still plausibly be used as Start and Select buttons, which aren&amp;rsquo;t typically combined with other buttons during play.&lt;/p&gt;
&lt;p&gt;crystalct has published the schematic and board design for a joystick that supports this protocol, and you can &lt;a href=&#34;https://www.pcbway.com/project/shareproject/DIY_5_buttons_joystick_for_Commodore_64_Vic20_autofire_943caf84.html&#34;&gt;order the board from PCBWay&lt;/a&gt;. It would be easy to hack a NES-style gamepad to support this with just a few wires. The two buttons are easy to detect with the CIA data registers, though they won&amp;rsquo;t work with the current version of BASIC 65&amp;rsquo;s &lt;code&gt;JOY()&lt;/code&gt; function, which interprets the directional buttons to direction values only.&lt;/p&gt;
&lt;p&gt;The project includes a C64 joystick test program also useful for trying out three-button controllers (&lt;a href=&#34;https://github.com/crystalct/5plusbuttonsJoystick/blob/main/Joystick5plus1Test.prg&#34;&gt;PRG download&lt;/a&gt;). It works with the C64 core; I had difficulty running it with the MEGA65 core in GO64 mode. crystalct also &lt;a href=&#34;http://wiki.icomp.de/wiki/DE-9_Joystick#C64&#34;&gt;personally modded dozens of games&lt;/a&gt; to add multi-button features—though none use the 4th and 5th buttons, as far as I can tell.&lt;/p&gt;
&lt;h2 id=&#34;more-buttons-and-bidirectional-protocols&#34;&gt;More buttons and bidirectional protocols&lt;/h2&gt;
&lt;p&gt;Game consoles that followed the NES had seven or eight buttons in addition to the directional pad. How far can we go, using the same 9-pin joystick port?&lt;/p&gt;
&lt;p&gt;The protocols we&amp;rsquo;ve discussed so far could all be considered &lt;em&gt;passive&lt;/em&gt; protocols: the controller can report the state of the joystick and buttons to the computer by mechanically completing circuits across the connector pins, and the computer does all the work to interpret these input signals. To be able to report more sophisticated inputs using the same pins, we need an &lt;em&gt;active&lt;/em&gt; protocol, where the computer not only reads signals from the controller, but also sends signals to the controller. Perhaps it&amp;rsquo;d be more accurate to call these &lt;em&gt;bidirectional&lt;/em&gt; protocols, because the output signals could be manipulating otherwise &amp;ldquo;passive&amp;rdquo; digital electronics in the controller, such as a key matrix. These days, microcontrollers are cheap, and modern game controllers contain tiny computers of their own, capable of an active dialog with the host computer.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/Amiga-CD32-Controller-L.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/Amiga-CD32-Controller-L.jpg 5460w, https://dansanderson.com/mega65/up-up-down-down/Amiga-CD32-Controller-L_hu_9a57c498b0556898.jpg 600w, https://dansanderson.com/mega65/up-up-down-down/Amiga-CD32-Controller-L_hu_cd54da34dfa82b3e.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/Amiga-CD32-Controller-L.jpg&#34;
        alt=&#34;Amiga CD32 game controller. Photo from Wikipedia.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Amiga CD32 game controller. Photo from Wikipedia.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Amiga CD32 game controller provided seven buttons: red, blue, green, and yellow action buttons, left and right shoulder buttons, and one menu button. It used the same 9-pin connector, and did so in a way that allowed the CD32 to support all previous Commodore-compatible passive controllers &lt;em&gt;and&lt;/em&gt; allowed the CD32 controller to be used as a passive two-button controller on other Commodores. This required the computer to treat pin #5 as an output pin to select either active or passive mode: the CD32 would hold this pin low relative to the +5V line to request the active protocol—something other Commodores wouldn&amp;rsquo;t do. When in active mode, the computer sends pulses to the controller on pin #6. With each pulse, the CD32 controller rotates through the seven buttons, reporting the status of each button on pin #9. This mechanism is called a &lt;em&gt;shift register&lt;/em&gt; and is typically implemented with a common shift register chip in the controller.&lt;/p&gt;
&lt;p&gt;While the backwards-and-forwards compatibility of this design is impressive, it rules out the ability for C64 programs to support a CD32 controller, because the C64 cannot treat pin #5 as an output. Perhaps someday we could add a CD32 controller mode to the MEGA65 core, but there just aren&amp;rsquo;t many CD32 controllers around. Would be a fun VHDL experiment, though.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/Sega-Genesis-6But-Cont.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/Sega-Genesis-6But-Cont.jpg 640w, https://dansanderson.com/mega65/up-up-down-down/Sega-Genesis-6But-Cont_hu_fd232814283e0fb6.jpg 600w, https://dansanderson.com/mega65/up-up-down-down/Sega-Genesis-6But-Cont_hu_deb84087bc244dbe.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/Sega-Genesis-6But-Cont.jpg&#34;
        alt=&#34;Sega Genesis six-button controller. Photo from Wikipedia.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Sega Genesis six-button controller. Photo from Wikipedia.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Sega game consoles also used a 9-pin connector, though they did not use Commodore-compatible pin assignments. The &lt;a href=&#34;https://en.wikipedia.org/wiki/Master_System&#34;&gt;Sega Master System&lt;/a&gt; started with &lt;a href=&#34;https://segaretro.org/Control_Pad_(Master_System)&#34;&gt;a passive two-button controller&lt;/a&gt; protocol, and the &lt;a href=&#34;https://en.wikipedia.org/wiki/Sega_Genesis&#34;&gt;Sega Genesis&lt;/a&gt; (aka Mega Drive) added more buttons (first &lt;a href=&#34;https://segaretro.org/Control_Pad_(Mega_Drive)&#34;&gt;3+1&lt;/a&gt; then &lt;a href=&#34;https://segaretro.org/Six_Button_Control_Pad_(Mega_Drive)&#34;&gt;6+1&lt;/a&gt;) with an active protocol: one pin was a dedicated output from the console that marched through two, four, or eight cycles, alternating high and low, and the definition for each of six input pins changed for each cycle. The full state table is a bit complex, trying to be backwards compatible with previous standards. (This appears to be based on timing? I got a bit lost trying to read about it.)&lt;/p&gt;
&lt;p&gt;I always feel obligated to mention: &lt;strong&gt;Do not connect a Sega Master System or Sega Genesis controller directly to a Commodore.&lt;/strong&gt; The incompatible wiring protocol could damage the delicate CIA chip. The MEGA65 is a bit more robust in this regard, but the MEGA65 core won&amp;rsquo;t assign the pins in a way that matches the controller.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/640px-ColecoVision-Controller-FL.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/640px-ColecoVision-Controller-FL.jpg 640w, https://dansanderson.com/mega65/up-up-down-down/640px-ColecoVision-Controller-FL_hu_532c0a73d44f6927.jpg 600w, https://dansanderson.com/mega65/up-up-down-down/640px-ColecoVision-Controller-FL_hu_73e4cd4ae43129a6.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/640px-ColecoVision-Controller-FL.jpg&#34;
        alt=&#34;ColecoVision Hand Controller. Photo from Wikipedia.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
ColecoVision Hand Controller. Photo from Wikipedia.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;These newer controllers weren&amp;rsquo;t the first to take advantage of bidirectional communication to support more buttons. The &lt;a href=&#34;https://en.wikipedia.org/wiki/ColecoVision&#34;&gt;ColecoVision Hand Controller&lt;/a&gt; sported the usual 8-way joystick, and also had a number pad with twelve buttons. Surprisingly, this protocol &lt;a href=&#34;https://old.pinouts.ru/Game/colecovision_controller_pinout.shtml&#34;&gt;only uses seven of the nine pins&lt;/a&gt;, and the computer selects between one-button joystick mode or number pad mode by connecting one of two pins to power. In number pad mode, each button is represented as a combination of the pin signals. For example, when the &amp;ldquo;5&amp;rdquo; button is pressed in this mode, pins #2 and #3 are pulled low. When the &amp;ldquo;4&amp;rdquo; button is pressed, pins #1, #2, and #3 are pulled low. This means that only one button can be recognized reliably at a time. If &amp;ldquo;4&amp;rdquo; and &amp;ldquo;5&amp;rdquo; are both pressed, only &amp;ldquo;4&amp;rdquo; is recognized.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/protopad_modes.gif&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/up-up-down-down/protopad_modes.gif&#34;
            width=&#34;438&#34;
            height=&#34;365&#34;
            alt=&#34;The Protovision Protopad, conceptual rendering by Protovision.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Protovision Protopad, conceptual rendering by Protovision.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;None of these protocols work with the Commodore 64, and due to the lack of a prevalent commercial implementation, there is no real consensus on a common protocol for Commodore 8-bit computers that supports more than three buttons. One glimmer of hope is the &lt;a href=&#34;https://www.protovision.games/shop/protopad/protopad.php&#34;&gt;in-progress Protovision Protopad&lt;/a&gt;, a project that intends to produce an eight-button controller (four action, two shoulder, two menu) with support for both the passive three-button protocol and a proprietary eight-button protocol, selectable by software. The active protocol uses an elegant and fast multiplexing technique compatible with the C64&amp;rsquo;s CIA bidirectional capabilities. It&amp;rsquo;s not clear if or when the hardware part of this project will come to fruition, but &lt;a href=&#34;https://www.protovision.games/files/Protopad_Development_Guide.zip&#34;&gt;the Protopad Development Guide&lt;/a&gt; defines the protocol. It&amp;rsquo;s a fun read. (Well I think it&amp;rsquo;s fun.)&lt;/p&gt;
&lt;p&gt;This brings us back to the topic of MEGA65 mainboard revisions. A Commodore-compatible active protocol game controller would use bidirectional communication over the joystick port data lines, and therefore would require an R6 mainboard. That is, if such a controller existed. I&amp;rsquo;m rooting for the Protopad, but in the meantime, I&amp;rsquo;m focusing on passive protocol controllers, which work with both R3 and R6 mainboards.&lt;/p&gt;
&lt;h2 id=&#34;modern-game-controllers-and-adapters&#34;&gt;Modern game controllers and adapters&lt;/h2&gt;
&lt;p&gt;You can find plenty of vintage Commodore-compatible one-button 9-pin game controllers at flea markets, computer conventions, and online auction websites. Many are still in working order, and hobbyists refurbish and re-sell them. You can also get new 9-pin game controllers ranging from hand-assembled hobbyist projects to limited run Kickstarters to fully manufactured products.&lt;/p&gt;
&lt;p&gt;There are also quite a few hobbyist electronics projects to make adapters for non-Commodore game controllers, both new and vintage, so that they work as Commodore 9-pin game controllers. A few of these implement the three-button protocol, or have a way to switch between multiple protocols. You can buy some of these pre-assembled; others are only available as schematics, and require ordering the parts separately and assembling them with a soldering iron.&lt;/p&gt;
&lt;p&gt;The following are just a few examples of useful and interesting game controllers and adapters.&lt;/p&gt;
&lt;h3 id=&#34;game-controllers&#34;&gt;Game controllers&lt;/h3&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/rgb_mega65_gamepad.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/rgb_mega65_gamepad.jpeg 470w, https://dansanderson.com/mega65/up-up-down-down/rgb_mega65_gamepad_hu_8db9a563645a67c4.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/rgb_mega65_gamepad_hu_c0cc62e925e39c40.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/rgb_mega65_gamepad.jpeg&#34;
        alt=&#34;MEGA65-themed one-button &amp;#43; up gamepad controller, by RetroGameBoyz.com.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGA65-themed one-button + &#34;up&#34; gamepad controller, by RetroGameBoyz.com.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;RetroGameBoyz gamepads.&lt;/strong&gt; Mike of &lt;a href=&#34;https://retrogameboyz.com&#34;&gt;retrogameboyz.com&lt;/a&gt; has been making new game controllers for vintage computers since 2017. Mike offers a wide variety of styles, platforms, and configurations. My favorites are the NES-style game pads, which include 9-pin connectors, long cables, and attractive decorative faceplates. Mike even makes &lt;a href=&#34;https://retrogameboyz.com/products/mega-65-them-commodore-64-atari-2600-flashback-9-x-controller-joystick-up-to-jump-map-gamepad&#34;&gt;a MEGA65-themed game pad&lt;/a&gt;! This one supports the one-button protocol, and wires the second action button to &amp;ldquo;up,&amp;rdquo; which is used as &amp;ldquo;jump&amp;rdquo; in many C64 platform games. I&amp;rsquo;m working with Mike—well, I&amp;rsquo;ve asked Mike and he&amp;rsquo;s doing all the work—to produce a custom MEGA65-themed controller that supports the three-button protocol, for future MEGA65 multi-button games.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/commotron.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/commotron.jpg 886w, https://dansanderson.com/mega65/up-up-down-down/commotron_hu_8747e04188560b74.jpg 600w, https://dansanderson.com/mega65/up-up-down-down/commotron_hu_a6abc49fbb0a98f4.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/commotron.jpg&#34;
        alt=&#34;The Commotron Gamepad Turbo 2000 Super wireless gamepad controller.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Commotron Gamepad Turbo 2000 Super wireless gamepad controller.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;The Commotron wireless gamepad.&lt;/strong&gt; The &lt;a href=&#34;https://shop.tentelian.com/Commotron-Gamepad-Turbo-2000-Super-p500731320&#34;&gt;Commotron Gamepad Turbo 2000 Super&lt;/a&gt; is a fully assembled gamepad with two unique properties. For one, it&amp;rsquo;s wireless, with a dongle and a range of six meters. And for two, it supports six remappable button layouts including an &amp;ldquo;up&amp;rdquo; button in addition to the three-button protocol. It&amp;rsquo;s currently sold out in the Commotron store, but they&amp;rsquo;re taking pre-orders for more, and &lt;a href=&#34;https://retro8bitshop.com/product/new-gamepad-c64-style-wireless/&#34;&gt;third-party sellers still have some&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The Commotron powers on into a mode compatible with the three-button protocol described above, where button &amp;ldquo;1&amp;rdquo; is the primary fire button. I couldn&amp;rsquo;t find the instructions for the Commotron online, so for the benefit of future web searchers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Buttons: directional pad (up, down, left, right), Map, Auto; and four action buttons, starting right-most going counterclockwise: 1, 2, 3, and &amp;ldquo;up.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Button 1 is the primary fire button, for one-button games. In C64 mode, buttons 2 and 3 are POTX and POTY, respectively. The &amp;ldquo;up&amp;rdquo; button triggers the &amp;ldquo;up&amp;rdquo; direction signal, good for &amp;ldquo;jump&amp;rdquo; in one-button platform games.&lt;/li&gt;
&lt;li&gt;The controller takes two AAA batteries. The dongle connects to the joystick port and is powered by the computer.&lt;/li&gt;
&lt;li&gt;Both the controller and the dongle have a light on them:
&lt;ul&gt;
&lt;li&gt;Off: no power, or in standby mode.&lt;/li&gt;
&lt;li&gt;Blinking: waiting to connect.&lt;/li&gt;
&lt;li&gt;On: connected.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;To connect, press the Auto button.&lt;/li&gt;
&lt;li&gt;To select a preset, hold the Map button and press a direction:
&lt;ul&gt;
&lt;li&gt;Left: Commodore/ZX Spectrum mode (the default). POTX and POTY connect to +5V when active, per the three-button protocol.&lt;/li&gt;
&lt;li&gt;Up: Amiga and Atari ST mode. These computers connect these pins to GND when active.&lt;/li&gt;
&lt;li&gt;Right: Atari 7800 mode. Buttons 1 and 2 are &amp;ldquo;right&amp;rdquo; fire; button 3 is &amp;ldquo;left&amp;rdquo; fire.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You can swap the functions of button 1 and the &amp;ldquo;up&amp;rdquo; button. To swap, hold Map and press Down.&lt;/li&gt;
&lt;li&gt;You can enable auto-fire to have the buttons trigger repeatedly while held down. To toggle auto-fire mode, press Auto. To change the fire rate, hold Map and press an action button:
&lt;ul&gt;
&lt;li&gt;Button 1: 3 clicks per second&lt;/li&gt;
&lt;li&gt;Button 2: 5 clicks per second&lt;/li&gt;
&lt;li&gt;Button 3: 8 clicks per second&lt;/li&gt;
&lt;li&gt;Button &amp;ldquo;up&amp;rdquo;: 13 clicks per second&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/DecanterSet_WB_Front_PDP.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/DecanterSet_WB_Front_PDP.jpeg 750w, https://dansanderson.com/mega65/up-up-down-down/DecanterSet_WB_Front_PDP_hu_4a56bee5550b1f24.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/DecanterSet_WB_Front_PDP_hu_3e5c9d0574881344.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/DecanterSet_WB_Front_PDP.jpeg&#34;
        alt=&#34;Atari decanter set.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Atari decanter set.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Neo-Atari controllers.&lt;/strong&gt; &lt;a href=&#34;https://atari.com/&#34;&gt;The modern-day company that owns the Atari trademark&lt;/a&gt; has made a largely successful play for our nostalgia-filled hearts with recreations of vintage consoles with varying degrees of authenticity and modernity. This includes new versions of the classic 9-pin game controllers, including the &lt;a href=&#34;https://atari.com/products/cx40-joystick&#34;&gt;CX40+ joystick&lt;/a&gt;, the &lt;a href=&#34;https://atari.com/products/cx30-paddle-controller&#34;&gt;CX30+ paddles&lt;/a&gt;, and the &lt;a href=&#34;https://atari.com/products/cx78-gamepad&#34;&gt;CX78+ two-button gamepad&lt;/a&gt;. (We didn&amp;rsquo;t get the Atari CX78 in the USA back in the day, so this is news to me!) &lt;a href=&#34;https://atari.com/products/wireless-cx40-joystick-atari&#34;&gt;Wireless models of the CX40+&lt;/a&gt; and &lt;a href=&#34;https://atari.com/products/wireless-cx78-gamepad-atari&#34;&gt;the CX78+&lt;/a&gt; are available for pre-order, and will include both 9-pin and USB-A wireless dongles, so you can use them with emulators on a PC &lt;em&gt;and&lt;/em&gt; with vintage and retro hardware. I haven&amp;rsquo;t tested this model of paddles yet and would expect them to support the Atari resistance range.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/hyperkin_ranger.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/hyperkin_ranger.jpg 1000w, https://dansanderson.com/mega65/up-up-down-down/hyperkin_ranger_hu_2f1a56e5dd8c36a5.jpg 600w, https://dansanderson.com/mega65/up-up-down-down/hyperkin_ranger_hu_135145073cb73ed8.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/hyperkin_ranger.jpg&#34;
        alt=&#34;The Hyperkin Ranger one-button gamepad, with paddle knob.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Hyperkin Ranger one-button gamepad, with paddle knob.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Hyperkin 9-pin controllers.&lt;/strong&gt; &lt;a href=&#34;https://hyperkin.com/&#34;&gt;Hyperkin&lt;/a&gt; makes a series of retro gaming consoles, as well as game controller peripherals for consoles old and new. Two of their controllers are compatible with Commodore and Atari computers. The &lt;a href=&#34;https://www.amazon.com/Hyperkin-Trooper-Controller-not-machine-specific/dp/B07M5HYTZL&#34;&gt;Hyperkin Trooper&lt;/a&gt; most resembles the classic Atari CX40, with the fire button duplicated for left-handed and right-handed play. The &lt;a href=&#34;https://www.amazon.com/Hyperkin-Premium-Gamepad-not-machine-specific/dp/B08227NQ3Z&#34;&gt;Hyperkin Ranger&lt;/a&gt; is a gamepad-style controller with one fire button, and even includes a single paddle wheel in a unique design. The Ranger also supports left-handed and right-handed play with a switch. Both the Trooper and the Ranger are in stock at Amazon.com.&lt;/p&gt;
&lt;p&gt;Note: The Ranger&amp;rsquo;s paddle wheel is &lt;em&gt;useless&lt;/em&gt; on Commodores. The potentiometer covers the full Atari range, 0 Ω to 1 MΩ. Less than a fifth of the throw registers between 0 and 255 with the SID, worse than an Atari paddle. I can barely get a middle value to register in my joystick-paddle tester, and can&amp;rsquo;t imagine using this paddle knob for Commodore gaming.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/up-up-down-down/arcader.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/up-up-down-down/arcader.jpeg 1992w, https://dansanderson.com/mega65/up-up-down-down/arcader_hu_1d58f2e47a7fa1b7.jpeg 600w, https://dansanderson.com/mega65/up-up-down-down/arcader_hu_d634f9e9922867dc.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/up-up-down-down/arcader.jpeg&#34;
        alt=&#34;The ArcadeR modern joystick, with arcade-quality parts.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The ArcadeR modern joystick, with arcade-quality parts.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Ultimate ArcadeR Classic.&lt;/strong&gt; The &lt;a href=&#34;https://ultimatemister.com/product/ultimate-joystick-arcader-sanwa-db9-black/&#34;&gt;ArcadeR&lt;/a&gt; is a one-button protocol 9-pin joystick built to last. It uses arcade-quality parts and is designed to be repairable and moddable, including auto-fire options. The joystick has quite a bit of travel, for better and for worse, and the switches make satisfying click sounds.&lt;/p&gt;
&lt;h3 id=&#34;controller-adapters&#34;&gt;Controller adapters&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Retro Rewind C64 Genesis adapter.&lt;/strong&gt; This pre-assembled adapter &lt;a href=&#34;https://retrorewind.ca/64-amiga-genesis-adapter&#34;&gt;converts a Sega Genesis controller to a C64/Amiga controller&lt;/a&gt;. It supports both the one-button + &amp;ldquo;up&amp;rdquo; button configuration and a C64GS-style two-button configuration, selectable by a jumper (a little metal piece you push onto some pins on the adapter). Another jumper changes which pin is used for the second action button: POTX for &amp;ldquo;C64&amp;rdquo; mode and POTY for &amp;ldquo;Amiga&amp;rdquo; mode. Use this with a vintage Sega Genesis controller, or combine it with the &lt;a href=&#34;https://www.8bitdo.com/retro-receiver-genesis-mega-drive/&#34;&gt;8BitDo wireless Genesis-compatible controller&lt;/a&gt; for cable-free multi-button gaming.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;sega-adapter.&lt;/strong&gt; If you&amp;rsquo;re handy with a soldering iron, the &lt;a href=&#34;https://github.com/eyvind/sega-adapter&#34;&gt;sega-adapter project&lt;/a&gt; is a Sega Genesis controller adapter with some cool features. It supports both the one-button + &amp;ldquo;up&amp;rdquo; protocol and the three-button protocol, and you can switch between them by holding the Start button. This project was tested extensively with the &lt;a href=&#34;https://www.8bitdo.com/retro-receiver-genesis-mega-drive/&#34;&gt;8BitDo wireless Genesis-compatible controller&lt;/a&gt;. The microcontroller code is open source, so you can customize it with your own features. Note the special instruction to invert the 2nd and 3rd button signals to comply with the C64 version of the three-button protocol.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;mouSTer.&lt;/strong&gt; I would put the &lt;a href=&#34;https://github.com/willyvmm/mouSTer?tab=readme-ov-file&#34;&gt;mouSTer multi-function USB 9-pin adapter&lt;/a&gt; at the top of my list for lots of reasons, except they&amp;rsquo;re sold out everywhere, and not available as a DIY board either. This clever versatile device is the best way to connect a modern USB mouse to the MEGA65 or other Commodores, and it also adapts USB gamepads and joysticks with support for the three-button protocol, as well as crystalct&amp;rsquo;s 5plusbuttonsJoystick protocol. It&amp;rsquo;s highly configurable: to upload new configuration, put &lt;a href=&#34;https://github.com/willyvmm/mouSTer/blob/main/MOUSTER.INI&#34;&gt;a configuration file&lt;/a&gt; on a USB stick and shove the stick into the adapter. I love it, but yeah, it&amp;rsquo;s currently unavailable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unijoysticle 2.&lt;/strong&gt; &lt;a href=&#34;https://github.com/ricardoquesada/unijoysticle2&#34;&gt;This bare board project&lt;/a&gt; connects to both joystick ports simultaneously, and pairs with any modern Bluetooth game controller. The C64 model supports the three-button protocol and the 5plusbuttonsJoystick protocol. Normally for sale on Tindie, this one is also &lt;a href=&#34;https://www.tindie.com/products/riq/unijoysticle-2-c64-gamepad-for-commodore-64/&#34;&gt;out of stock&lt;/a&gt;, though designs are available under an open hardware license so you can make your own.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SNES controller adapters.&lt;/strong&gt; &lt;a href=&#34;https://snes2c64.readthedocs.io/en/latest/&#34;&gt;snes2c64&lt;/a&gt; and &lt;a href=&#34;https://github.com/Hojo-Norem/PadSwitcher64&#34;&gt;PadSwitcher64&lt;/a&gt; are two projects with interesting takes on multi-button support. snes2c64 adapts the six-button SNES controller to a three-button C64 controller, using a programmable Arduino Nano for custom button mapping and auto-fire options. PadSwitcher64 connects to &lt;em&gt;both&lt;/em&gt; 9-pin joystick ports to support all six SNES buttons with a proprietary passive protocol.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I&amp;rsquo;m most excited about the possibility of the three-button protocol for MEGA65 games. It&amp;rsquo;s relatively easy to find pre-assembled controllers, easy to implement in software and modified hardware, compatible with both R3 and R6 mainboards, and is the closest thing we have to an implemented standard for multi-button Commodore-compatible game controllers. I&amp;rsquo;ll let you know what Mike and I come up with for controllers and software support. If you can get your hands on a Commotron, or are handy enough to build a sega-adapter, those are also good options.&lt;/p&gt;
&lt;p&gt;Give &lt;a href=&#34;https://files.mega65.org?id=671054f3-45ed-4b88-957c-fd7a55c67b2d&#34;&gt;joytest65&lt;/a&gt; a try and let me know how it works for your game controllers.&lt;/p&gt;
&lt;p&gt;Happy gaming!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/up-up-down-down/M65Digest_2024Oct.mp3" length="60285376" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>3014</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/up-up-down-down/9pin_cx40.jpeg"/>
      
    </item>
    
    <item>
      <title>Greetings from Chicagoland</title>
      <link>https://dansanderson.com/mega65/chicagoland/</link>
      <pubDate>Mon, 16 Sep 2024 13:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/chicagoland/</guid>
      <description>&lt;p&gt;Greetings from Chicagoland. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for September 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Greetings from Chicagoland. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for September 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/chicagoland/M65Digest_2024Sept.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/M65Digest_2024Sept.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Greetings from Chicagoland
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/pizza.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/pizza.jpeg 640w, https://dansanderson.com/mega65/chicagoland/pizza_hu_91c6df9c8f804434.jpeg 600w, https://dansanderson.com/mega65/chicagoland/pizza_hu_49231f22e06081ec.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/pizza.jpeg&#34;
        alt=&#34;Eat Pizza sign, from Giordano&amp;amp;#39;s in Schaumburg, Illinois&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Eat Pizza, from Giordano&#39;s in Schaumburg, Illinois
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s a busy month! I just got back from the Vintage Computer Festival Midwest (VCFMW), the large-and-getting-larger-every-year vintage computer show. This was my first visit at this particular show, and it was great fun. I bring back a few photos, a few stories, and too much stuff from the free table.&lt;/p&gt;
&lt;p&gt;But first, the news.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;catching-up-on-pre-orders-mainboards-now-available-separately&#34;&gt;Catching up on pre-orders; mainboards now available separately&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/mainboard.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/mainboard.jpg 1200w, https://dansanderson.com/mega65/chicagoland/mainboard_hu_8201dd59321a1f5b.jpg 600w, https://dansanderson.com/mega65/chicagoland/mainboard_hu_53996b28e5219ba7.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/mainboard.jpg&#34;
        alt=&#34;The MEGA65 mainboard, now available separately&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The MEGA65 mainboard, now available separately&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Trenz Electronic is making steady progress on shipping all of the pending MEGA65 preorders, on schedule to get everyone taken care of by the end of the calendar year. &lt;a href=&#34;https://shop.trenz-electronic.de/en/TE0765-06-T001CK-MEGA65-highly-advanced-C64-and-C65-compatible-8-bit-computer?c=564&#34;&gt;A new pre-order for a MEGA65 placed today&lt;/a&gt; should have a lead time of only a few months. If you placed a pre-order and have received an email with an invoice, be sure to submit payment promptly. Invoiced but unpaid orders expire within a few weeks, to allocate inventory to others waiting on a pre-order. (Thankfully, you can just re-make your expired order, and you&amp;rsquo;ll receive it fairly soon.)&lt;/p&gt;
&lt;p&gt;With this milestone comes some exciting news! Trenz Electronic is &lt;a href=&#34;https://shop.trenz-electronic.de/en/TE0765-06-T002CK-MEGA65-Mainboard-without-housing?c=564&#34;&gt;now accepting preorders for MEGA65 mainboards&lt;/a&gt; without the enclosure, keyboard, or floppy drive. This is great for electronics projects, custom enclosures, or just keeping a spare. You can &lt;a href=&#34;https://github.com/MEGA65/mega65-kbd-pcb&#34;&gt;make your own keyboard&lt;/a&gt; with some effort, and the floppy drive is a standard IDE drive and cable. The standalone mainboards are expected to ship in mid-2025.&lt;/p&gt;
&lt;p&gt;Many owners of the 2022 edition of the MEGA65 (mainboard revision R3A) asked for the ability to replace the mainboard with the latest hardware revision (R6), and it&amp;rsquo;s great that Trenz is providing this option. This is just my opinion, but if you simply want a MEGA65 with the revised hardware, you might get a better result buying a complete new computer, and selling your 2022 edition on the secondary market. The mainboard is more than half the cost of the computer, and unless you want to keep the spare R3 board, you&amp;rsquo;re unlikely to recoup that cost after an upgrade. Of course, there are no guarantees on the secondary market, but it&amp;rsquo;s worth giving it a thought. Personally, I own two MEGA65s and a spare board, a Nexys dev board—and dozens of other computers. But you might not want to follow my example.&lt;/p&gt;
&lt;p&gt;Speaking of owning lots of computers, Trenz has lifted the one-per-person limitation on MEGA65 pre-orders. If you want to outfit a classroom, hand out MEGA65s at parties, or just make a cool fort out of the boxes, now is your chance!&lt;/p&gt;
&lt;p&gt;Thanks as always to everyone at Trenz Electronic for their partnership on the MEGA65 project.&lt;/p&gt;
&lt;h2 id=&#34;filehost-messaging-feature&#34;&gt;Filehost messaging feature&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/fh_msg_notif.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/chicagoland/fh_msg_notif.png&#34;
            width=&#34;96&#34;
            height=&#34;100&#34;
            alt=&#34;Filehost new message notification&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Filehost new message notification&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt;, our community file and information sharing board, has a new feature! You can now receive private notifications from the system, and send and receive private messages with other users. If you have a pending notification or incoming message, a red dot will appear on the user icon in the upper right corner.&lt;/p&gt;
&lt;p&gt;To receive incoming notifications and messages, you must enable them: go to User menu &amp;gt; User Settings, check &amp;ldquo;Allow to receive messages from users&amp;rdquo; and &amp;ldquo;Inform me about comments on my entries,&amp;rdquo; then click Submit.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/fh_msg_settings.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/chicagoland/fh_msg_settings.png&#34;
            width=&#34;657&#34;
            height=&#34;193&#34;
            alt=&#34;Filehost message settings&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Filehost message settings&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To access your messages: User menu &amp;gt; Messages.&lt;/p&gt;
&lt;p&gt;To start a new private conversation with another user: click the plus sign next to Subjects, select the user, enter a subject, then enter the first message. Only users who have enabled incoming messages appear in the list of users.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/fh_msg_new.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/chicagoland/fh_msg_new.png&#34;
            width=&#34;466&#34;
            height=&#34;260&#34;
            alt=&#34;Starting a new conversation&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Starting a new conversation&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To add to an existing conversation: select the subject from the list, then scroll to the bottom of the conversation and enter the next message.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/fh_msg_add.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/chicagoland/fh_msg_add.png&#34;
            width=&#34;482&#34;
            height=&#34;436&#34;
            alt=&#34;Adding to an existing conversation&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Adding to an existing conversation&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Huge thanks to Tayger for this new feature, and all of his work on this essential community resource!&lt;/p&gt;
&lt;h2 id=&#34;new-c64-core-documentation&#34;&gt;New C64 core documentation&lt;/h2&gt;
&lt;p&gt;Boris has been working on &lt;a href=&#34;https://kugelblitz360.github.io/C64MEGA65DOCS/&#34;&gt;extended documentation for the C64 core&lt;/a&gt;. The docs are now &amp;ldquo;feature complete,&amp;rdquo; with coverage of every feature and common task, including how to install JiffyDOS or use the built-in RAM expansion unit (REU). Be sure to send Boris your feedback and thanks, via Discord or email. Thank you, Boris!&lt;/p&gt;
&lt;h2 id=&#34;recent-filehost-uploads&#34;&gt;Recent Filehost uploads&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/pelota.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/pelota.png 640w, https://dansanderson.com/mega65/chicagoland/pelota_hu_c0e755a313e908f4.png 600w, https://dansanderson.com/mega65/chicagoland/pelota_hu_d45ec9f88687d852.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/pelota.png&#34;
        alt=&#34;Pelota, a single-player paddle game, by SirLazarus&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Pelota, a single-player paddle game, by SirLazarus&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A few recent Filehost uploads for you to try:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=6b16a719-23f5-444d-8f5d-1c6e391e7220&#34;&gt;Quadratic Equation Solver&lt;/a&gt;, by fredrikr, an equation root finder&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=ea68dc29-314c-4bde-96d1-81f20ee41c80&#34;&gt;3D 4-in-a-row&lt;/a&gt;, by fredrikr, a 4x4x4 two-player tile placement game&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=e8a9c2f8-43e2-4ded-9333-0a9581186eba&#34;&gt;Pelota&lt;/a&gt;, by SirLazarus, a single-player paddle game; requires a recent ROM beta&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=25e387cb-0a49-46d1-b719-859cca9926e1&#34;&gt;Hang the DJ&lt;/a&gt;, by mk9, a Hangman-style word game&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=1d856de4-fa57-46cd-a993-b5d21a7b736c&#34;&gt;romlister&lt;/a&gt;, by nobruinfo, a small utility to list which ROMs you have on your SD card&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;h2 id=&#34;greetings-from-chicagoland&#34;&gt;Greetings from Chicagoland!&lt;/h2&gt;
&lt;p&gt;I just flew back from &lt;a href=&#34;https://vcfmw.org/&#34;&gt;Vintage Computer Festival Midwest&lt;/a&gt; and boy are my arms tired. Literally. I took my MEGA65, printed table displays, a bunch of backup equipment, and bundles of &lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;45GS02 mousepads&lt;/a&gt; to give away. I use &lt;a href=&#34;https://www.amazon.com/gp/product/B00SSFAPVI&#34;&gt;this weatherproof hard case&lt;/a&gt; when I travel with my MEGA65, and I always carry it onto the plane and put it in the overhead bin. For this trip, the less delicate stuff went into a large checked bag. Who knew 100 mousepads would be so heavy! Thankfully, everything made it there and back safely.&lt;/p&gt;
&lt;p&gt;The event took place at the Renaissance Schaumburg Convention Center Hotel, in Schaumburg, Illinois, in the &lt;a href=&#34;https://en.wikipedia.org/wiki/Chicago_metropolitan_area&#34;&gt;Chicagoland&lt;/a&gt; area. The show consumed an entire expo floor and a separate presentation space for talks. This venue is also a nice hotel, and many exhibitors and visitors stayed here or in a nearby Embassy Suites. I didn&amp;rsquo;t take enough photos to do justice to the scale of this show, but hopefully you can get a sense of it.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcf1.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcf1.jpeg 480w, https://dansanderson.com/mega65/chicagoland/vcf1_hu_85677c36c922810.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcf1_hu_5e98c09c2743db6f.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcf1.jpeg&#34;
        alt=&#34;The Renaissance Schaumburg Convention Center Hotel, in Schaumburg, Illinois, USA&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Renaissance Schaumburg Convention Center Hotel, in Schaumburg, Illinois, USA
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcf2.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcf2.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcf2_hu_671b85c221909a3b.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcf2_hu_c628de1fa1c7d9fb.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcf2.jpeg&#34;
        alt=&#34;The hotel atrium&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The hotel atrium
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcf3.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcf3.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcf3_hu_e6a8ccc4b3c752a6.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcf3_hu_e5514ae46f44b6e1.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcf3.jpeg&#34;
        alt=&#34;Entrance to the convention center expo floor&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Entrance to the convention center expo floor
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcf4.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcf4.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcf4_hu_591a527ca59c5aea.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcf4_hu_59982bd2b8a702f6.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcf4.jpeg&#34;
        alt=&#34;Setting up the expo floor, before opening&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Setting up the expo floor, before opening
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I prepared a bunch of table tchotchkes, more than I actually needed, including a colorful banner, an informational standee, a &amp;ldquo;demo&amp;rdquo; booklet that someone could use to launch and browse software on the SD card, and various boxed software and accessories. I didn&amp;rsquo;t have a good way to hang the banner, so it ended up being more of a tablecloth, but it still added some color. I also made business cards with a full-color photo on one side and links to resources on the other. And a custom t-shirt to wear, because why not.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcf5_booth.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcf5_booth.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcf5_booth_hu_c760fc07b8fe5e04.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcf5_booth_hu_fbde0d22d83c6e2c.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcf5_booth.jpeg&#34;
        alt=&#34;My MEGA65 table at VCFMW, before opening&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
My MEGA65 table at VCFMW, before opening
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_demobook1.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_demobook1.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_demobook1_hu_b4983501c8d1ea63.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_demobook1_hu_b53c01c91de93c83.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_demobook1.jpeg&#34;
        alt=&#34;My MEGA65 demo booklet (cover)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
My MEGA65 demo booklet (cover)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_demobook2.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_demobook2.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_demobook2_hu_bf49ee401905af3f.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_demobook2_hu_9115c3ce6e544428.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_demobook2.jpeg&#34;
        alt=&#34;My MEGA65 demo booklet, intro disk instructions&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
My MEGA65 demo booklet, intro disk instructions
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_demobook3.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_demobook3.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_demobook3_hu_a2b87adb0f961c87.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_demobook3_hu_81a584efb498f6bf.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_demobook3.jpeg&#34;
        alt=&#34;My MEGA65 demo booklet, software catalog&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
My MEGA65 demo booklet, software catalog
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_cards.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_cards.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_cards_hu_96fb9f043ac0408a.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_cards_hu_5428d9fe482d2ba5.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_cards.jpeg&#34;
        alt=&#34;Info card giveaways&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Info card giveaways
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_shirt.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_shirt.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_shirt_hu_40fb74871eb3d07.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_shirt_hu_b8bfd200498009b9.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_shirt.jpeg&#34;
        alt=&#34;Custom t-shirt for me to wear&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Custom t-shirt for me to wear
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;ladies-and-gentlemen-the-commodore-65&#34;&gt;Ladies and gentlemen: the Commodore 65&lt;/h3&gt;
&lt;p&gt;My table included my MEGA65, Jim Happel&amp;rsquo;s MEGA65, and two original Commodore 65 prototypes owned by Jim Brain. After having been on the MEGA65 project for two years, it was a real thrill to be able to see a C65 prototype and the MEGA65 side by side. It was also the best conversation starter: most passersby knew the C64 and never heard of the C65, so I could just point to the C65 first, then tell the rest of the story. Several people knew of the C65 and were excited to see it in person, taking selfies with the computer. I took a bunch of photos myself for future reference.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_1.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_1.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_1_hu_549590b963948228.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_1_hu_e59ff7e4346154ff.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_1.jpeg&#34;
        alt=&#34;The Commodore 65, developer unit #23, rev 2A mainboard&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Commodore 65, developer unit #23, rev 2A mainboard
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2_hu_c4d48766ad7f9b4f.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2_hu_334a72e37313a202.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2.jpeg&#34;
        alt=&#34;The Commodore 65, rear view&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Commodore 65, rear view
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_3.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_3.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_3_hu_501793de1a04c8b4.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_3_hu_f714c9405025f159.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_3.jpeg&#34;
        alt=&#34;C65 keyboard close-up&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
C65 keyboard close-up
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_4.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_4.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_4_hu_ddde43a2f49088d8.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_4_hu_da3a6081e5ba568b.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_4.jpeg&#34;
        alt=&#34;The C65, powered on, at the READY prompt&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The C65, powered on, at the READY prompt
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I tried to spend some time with Jim Brain&amp;rsquo;s copies of the demo disks, both on the C65 and on the MEGA65. It was a sobering reminder of how the C65 prototypes were not ready to be software platforms that the demo disks were hard-coded to specific versions of the ROM. Disks were generally not working on the C65. I could list directories but not load files. I got the IFF slideshow disk to work on the MEGA65—and of course I forgot about the topless woman until it showed up right as some young kids were walking up to the table.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65demodisks.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65demodisks.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65demodisks_hu_2b655d07442db138.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65demodisks_hu_c6c754d051d31e7c.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65demodisks.jpeg&#34;
        alt=&#34;Jim Brain&amp;amp;#39;s copies of the C65 demo disks&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Jim Brain&#39;s copies of the C65 demo disks
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_demorom.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_demorom.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_demorom_hu_7469c549c356bfe3.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_demorom_hu_b5eeb3504c3a575a.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_demorom.jpeg&#34;
        alt=&#34;The demos were hard-coded to specific versions of the C65 prototype ROM&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The demos were hard-coded to specific versions of the C65 prototype ROM
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One especially fun find was a message that Fred Bowen posted to the comp.sys.cbm Usenet group on September 17, 1993, subject line, &amp;ldquo;What&amp;rsquo;s a C-65???&amp;rdquo; Fred&amp;rsquo;s message puts the date of the liquidation sale around July 1993, and claims the prototypes numbered around 50. (According to Brian Bagnall&amp;rsquo;s &lt;em&gt;Commodore: The Final Years&lt;/em&gt;, &amp;ldquo;By 1991, Commodore had at least 205 pilot production C65 machines. &amp;lsquo;We had a room full of them at one point,&amp;rsquo; says [chip designer Bill] Gardei. &amp;lsquo;If you counted all the variants, 205 would not be an unreasonable guess.&amp;rsquo;&amp;rdquo;) In the message that follows, &amp;ldquo;Grapevine&amp;rdquo; refers to The Grapevine Group Inc. of Suffern, New York, one of two companies known to have acquired and re-sold the prototypes.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_bowen1.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_bowen1.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_bowen1_hu_4db952e132a82cf6.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_bowen1_hu_d8e036686ab807e9.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_bowen1.jpeg&#34;
        alt=&#34;A message from Fred Bowen, part 1&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A message from Fred Bowen, part 1
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_bowen2.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_bowen2.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_bowen2_hu_a5646b191c0aca6b.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_bowen2_hu_f9713a7a4d1ca56f.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_bowen2.jpeg&#34;
        alt=&#34;A message from Fred Bowen, part 2&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A message from Fred Bowen, part 2
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;From: &lt;code&gt;fred@cbmvax.cbm.commodore.com&lt;/code&gt; (Fred Bowen)&lt;br&gt;
Newsgroups: comp.sys.cbm&lt;br&gt;
Subject: Re: What&amp;rsquo;s a C-65???&lt;br&gt;
Date: 17 Sep 93 14:56:25 GMT&lt;br&gt;
&amp;hellip;&lt;/p&gt;
&lt;p&gt;Apparently Grapevine picked up some C65&amp;rsquo;s during Commodore&amp;rsquo;s liquidation of its warehouse/storage areas a couple of months ago.&lt;/p&gt;
&lt;p&gt;What is a C65? A product that almost made it out the door. What you&amp;rsquo;re seeing are &amp;ldquo;alpha&amp;rdquo; pilot-production units. There were only something like 50 units made, and a dozen or more of these were distributed around engineering, system developers, etc. Obviously, they were never meant to be sold to the public, but&amp;hellip;&lt;/p&gt;
&lt;p&gt;CPU CSG65CE02, running at 3.54MHz&lt;br&gt;
RAM 128K, expansion to ~8MB&lt;br&gt;
ROM 128K, including C65 mode (v10.0), C64 (v2.2) mode, &amp;amp; DOS&lt;br&gt;
Video CSG4567 &amp;ldquo;VIC-III&amp;rdquo;&lt;br&gt;
I/O Built-in DMA/blitter&lt;br&gt;
Built-in 6511-type UART, supports MIDI data rate.&lt;br&gt;
All C64 ports: parallel, expansion, etc.&lt;br&gt;
new RAM expansion port, accessible by DMA and video chips.&lt;/p&gt;
&lt;p&gt;I guess that&amp;rsquo;s enough for now. But be warned- these boards are very out of date-the ROMs, PLA&amp;rsquo;s, etc. are pre-pre-preALPHA, there are absolutely NO spare parts (so if it breaks, that&amp;rsquo;s it!), all systems are PAL (but they display okay on regular 1084-type monitors in analog mode). Oh, and there aren&amp;rsquo;t any manuals. I&amp;rsquo;m surprised that Grapevine can sell them as &amp;ldquo;new&amp;rdquo; equipment. Buyer beware, and all that.&lt;/p&gt;
&lt;p&gt;All things considered, not a bad machine, though. I still use mine :-)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At some point during the conference, some guy I&amp;rsquo;d never met showed up at the table and started opening the C65 case. I politely but firmly discouraged him from touching it without Jim Brain&amp;rsquo;s permission. The guy smiled and introduced himself as Jim Brain. 😅 We were having some difficulty with non-functioning keys on one of the C65s, and Jim noticed a small break in the keyboard ribbon cable that will need repair. Thankfully, and amazingly, Jim has two C65s, so we temporarily swapped the keyboards to form a fully functioning unit. Jim was careful to keep track of the fact that we swapped the keyboards, so they could be reunited with their original cases later.&lt;/p&gt;
&lt;p&gt;The C65 prototype is held together with &lt;em&gt;one screw&lt;/em&gt; in the front-right of the case near the floppy drive. The rest of the case is all plastic tabs, to make it easy to open and repair. I got to see and photograph the internals of both machines. Developer unit #23 contained the revision 2A mainboard, and a memory expansion module.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_jim_c65d23.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_jim_c65d23.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_jim_c65d23_hu_960da0db77568e2.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_jim_c65d23_hu_bbf85f727663b010.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_jim_c65d23.jpeg&#34;
        alt=&#34;Jim Brain and C65 developer unit #23, with the case open&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Jim Brain and C65 developer unit #23, with the case open
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65d23.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65d23.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65d23_hu_f969d531790c5e52.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65d23_hu_40c66673132a1631.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65d23.jpeg&#34;
        alt=&#34;The inside of D23, with the memory expansion module&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The inside of D23, with the memory expansion module
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_d23_closeup.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_d23_closeup.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_d23_closeup_hu_bf5a4c0dc889742.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_d23_closeup_hu_71b27479e3f54d4f.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_d23_closeup.jpeg&#34;
        alt=&#34;Another D23 internals close-up&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Another D23 internals close-up
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2b.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2b.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2b_hu_5bb07427145c7602.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2b_hu_1f738d66c0de26c7.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_c65_2b.jpeg&#34;
        alt=&#34;An inside look at Jim&amp;amp;#39;s other C65, with a rev 2B board&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An inside look at Jim&#39;s other C65, with a rev 2B board
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;As impressive as the C65 is as a historical artifact, I&amp;rsquo;m relieved to realize that I don&amp;rsquo;t want to own one. Not that that was ever an option, with working units &lt;a href=&#34;https://gizmodo.com/commodore-65-prototype-ebay-30-000-dollars-1848823604&#34;&gt;selling on eBay for $30,000&lt;/a&gt;. A recent auction for a &lt;em&gt;broken&lt;/em&gt; one ended north of $12,000. The prototype plastic is weird, the keyboards are mushy compared to a good condition production C128, and the working ones barely work and are difficult to maintain. I&amp;rsquo;m grateful for collectors like Jim for keeping them alive as long as possible and sharing them with the world. And I&amp;rsquo;m grateful for the MEGA65 for not only letting me access a piece of this history in my own home, but for being a satisfying instrument of recreational computing in its own right.&lt;/p&gt;
&lt;h2 id=&#34;reactions&#34;&gt;Reactions&lt;/h2&gt;
&lt;p&gt;Quite a few people saw the &lt;code&gt;READY.&lt;/code&gt; prompt and wanted to type their own &lt;code&gt;GOTO 10&lt;/code&gt; program. Several young kids took the time to write a longer program, though they did it all from memory and didn&amp;rsquo;t bother exploring the manual. I ended up standing in front of the table and doing guided demos for most of the time. &lt;em&gt;First Shot&lt;/em&gt;, &lt;em&gt;Maniac Mansion&lt;/em&gt;, and &lt;em&gt;Unicone&lt;/em&gt; attracted attention. Nobody bothered with the &amp;ldquo;demo&amp;rdquo; booklet, even with encouragement. I&amp;rsquo;m still glad I made the demo book: the full-color screenshots made it something you could flip through in seconds, and get a glimpse without having to wait for software to load.&lt;/p&gt;
&lt;p&gt;I had stacks of the mousepads on the table. At first I was concerned that if I gave away the mousepads for free that they would disappear quickly, and wouldn&amp;rsquo;t provide much promotional value, so I had intended to maybe sell them at cost, and even made a little for-sale sign for it. I figured out within the first few hours that this wasn&amp;rsquo;t going to be a problem. I took down my for-sale sign and just arbitrarily handed mousepads to people that seemed even remotely interested in programming. At the end of the last day, I ran around the floor looking for coders I admired by reputation, and used mousepad gifts as excuses to say hi.&lt;/p&gt;
&lt;p&gt;I had many good conversations with many people with a wide variety of interests and backgrounds, and I handed out many business cards. Greetz to all the new newsletter subscribers!&lt;/p&gt;
&lt;h2 id=&#34;expo-highlights&#34;&gt;Expo highlights&lt;/h2&gt;
&lt;p&gt;Many of the Commodore exhibits were colocated together in a common section. There ended up being so much diversity in the exhibits that you almost couldn&amp;rsquo;t tell they were related by platform. I was delighted that my table was next to the brilliant &lt;a href=&#34;http://cityxen.net/&#34;&gt;CityXen&lt;/a&gt;, who were showing off &amp;ldquo;&lt;a href=&#34;https://www.youtube.com/watch?v=ggbDzyFjCME&#34;&gt;Whackadoodle&lt;/a&gt;,&amp;rdquo; their C64-powered whack-a-mole game with giant colorful light-up arcade controller, along with a miniature version with &lt;a href=&#34;http://cityxen.net/2024/08/whackadoodle-custom-controllers/&#34;&gt;custom handheld controllers&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_cityxen.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_cityxen.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_cityxen_hu_477bd13575a3820a.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_cityxen_hu_958d47d81d674dd8.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_cityxen.jpeg&#34;
        alt=&#34;CityXen table at VCFMW (photo taken during set-up day)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
CityXen table at VCFMW (photo taken during set-up day)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;June of the excellent &lt;a href=&#34;https://nybblesandbytes.net/&#34;&gt;Nybbles &amp;amp; Bytes&lt;/a&gt; was also in my area, demoing and distributing her unique C128 game, &lt;a href=&#34;https://nybblesandbytes.net/blog/vcfmw19.html&#34;&gt;Nybbles: Legend of the Drunken Snake&lt;/a&gt;. When you first start playing, Nybbles looks like a traditional snake game, until just moments later you eat something unusual and things get utterly wild. The game uses &lt;em&gt;two displays&lt;/em&gt;, and manipulates both the VIC-II and the VDC in ways I have never seen before. I waited to the end of the show to buy one to give others a chance, and I did indeed end up with one of the last copies to be distributed on floppy disk. Be sure to subscribe to the &lt;a href=&#34;https://www.youtube.com/nybblesandbytes&#34;&gt;Nybbles &amp;amp; Bytes YouTube channel&lt;/a&gt; for future updates and technical details about the game.&lt;/p&gt;
&lt;p&gt;Right around the corner, I met Craig of &lt;a href=&#34;https://bitbinders.com/&#34;&gt;BitBinders&lt;/a&gt;, maker of 1581 clone floppy disk drives. I was especially impressed by his unique dual drive units, available in both vertically and horizontally arranged variants. I bought one of the horizontal units immediately. Craig already knew about the MEGA65, and we discussed the un-produced Commodore 1565 external drive, and how a modern clone would make a great MEGA65 accessory (along with the expansion board that provides the 1565 mini-DIN connector).&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_bitbinders.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_bitbinders.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_bitbinders_hu_68d90b778b5f09ae.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_bitbinders_hu_23f59f573062d7ea.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_bitbinders.jpeg&#34;
        alt=&#34;1581 clone disk drives by BitBinders&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
1581 clone disk drives by BitBinders
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There isn&amp;rsquo;t enough space to show all the photos of cool and unusual computers I saw throughout the show, but I had such a strong reaction to this one I have to include it. I&amp;rsquo;ve wanted a &lt;a href=&#34;https://en.wikipedia.org/wiki/HERO_(robot)&#34;&gt;Heathkit Hero 1 robot kit&lt;/a&gt; all of my life, having only known it through advertisements in magazines. This is the first time I&amp;rsquo;ve ever seen a Hero in person. The Hero Jr., on its 40th anniversary, was sharing a table with two &lt;a href=&#34;https://en.wikipedia.org/wiki/Topo_(robot)&#34;&gt;Androbot Topo&lt;/a&gt; robots.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_robots.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_robots.jpeg 640w, https://dansanderson.com/mega65/chicagoland/vcfmw_robots_hu_78eb19883baf1753.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_robots_hu_cca244067fc6541a.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_robots.jpeg&#34;
        alt=&#34;Heathkit Hero Jr. and two Androbot Topos&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Heathkit Hero Jr. and two Topo Androbots
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_herojr.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_herojr.jpeg 480w, https://dansanderson.com/mega65/chicagoland/vcfmw_herojr_hu_80d1a3d126cf5b2d.jpeg 600w, https://dansanderson.com/mega65/chicagoland/vcfmw_herojr_hu_61cd88f8e3d05efd.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/vcfmw_herojr.jpeg&#34;
        alt=&#34;Hero Jr. close-up&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Hero Jr. close-up
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;VCFMW is as much a swap meet as a share-out, and about half of the show floor was for sale. Many exhibitors had new and vintage items for sale, and VCFMW also held an auction of unusual items donated by exhibitors to help fund the event. What really gives the convention a pervasive electric air is the ominous entity known as &lt;em&gt;the Free Table.&lt;/em&gt; People leave stuff to give away, and other people take stuff they like, a waxing and waning of trash and treasure throughout the convention. The table is largely unsupervised, which gives the added thrill of worrying that something that isn&amp;rsquo;t free might get taken. (This has happened.) The table this year was well labeled, with a useful partition between the free table and the next table over, so it was pretty chill.&lt;/p&gt;
&lt;p&gt;I knew I was flying home, and I&amp;rsquo;m kind of at my limit for hardware anyway, so pretty much nothing on the free table interested me. I saw some &amp;rsquo;90s-era Microsoft software in original boxes pass across the table. My big finds were all books, where at least one person was shedding a nerd&amp;rsquo;s bonanza of famous titles on computer science and programming. I grabbed what I could carry, and left behind some of my favorite books just because I know I already owned them. I was glad to see the good ones eventually found new owners.&lt;/p&gt;
&lt;p&gt;Of course, with the bundles of mousepads, booth decor, and equipment, my luggage was already quite full and quite heavy. The books pushed my checked bag over the weight limit, and ended up costing me a $100 heavy bag fee. So not exactly free. Still a decent haul.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I owe huge thanks to Jim Happel (jim_64 on Discord) for making my VCFMW trip possible. Jim encouraged me to make the trek in the first place, and provided logistical, technical, and moral support throughout the experience. Jim also introduced me to many excellent people in the community whom I&amp;rsquo;ve known only by reputation online and I now consider friends. This was such a good time, I&amp;rsquo;m eager to visit the other annual shows around the country as time and budget allows, with my MEGA65 in its carrying case.&lt;/p&gt;
&lt;p&gt;Thanks to everyone for your kind words and feedback on &lt;a href=&#34;https://github.com/dansanderson/easyasm65&#34;&gt;EasyAsm&lt;/a&gt; v0.1. I&amp;rsquo;ve only received a couple of bug reports—which just means you&amp;rsquo;re not trying hard enough to break it! I hope to start a revision as soon as I&amp;rsquo;m through this very busy month. I&amp;rsquo;m working on the draft of this year&amp;rsquo;s community survey, I&amp;rsquo;m dropping off a kid at college, and I still have the &lt;a href=&#34;https://www.retrogamingexpo.com/&#34;&gt;Portland Retro Gaming Expo&lt;/a&gt; in a couple of weeks.&lt;/p&gt;
&lt;p&gt;Special thanks to all of my supporters, who are making my promotional tours and other projects possible. If you like what I&amp;rsquo;m doing, please consider becoming a supporter. Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/chicagoland/beef.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/chicagoland/beef.jpeg 640w, https://dansanderson.com/mega65/chicagoland/beef_hu_e615da80a3f03a6b.jpeg 600w, https://dansanderson.com/mega65/chicagoland/beef_hu_a246b38046f859fe.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/chicagoland/beef.jpeg&#34;
        alt=&#34;Portillo&amp;amp;#39;s&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Portillo&#39;s, home of &#34;unrivaled Chicago street food&#34;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/chicagoland/M65Digest_2024Sept.mp3" length="23325376" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1166</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/chicagoland/pizza.jpeg"/>
      
    </item>
    
    <item>
      <title>EasyAsm</title>
      <link>https://dansanderson.com/mega65/introducing-easyasm/</link>
      <pubDate>Mon, 26 Aug 2024 00:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/introducing-easyasm/</guid>
      <description>&lt;p&gt;EasyAsm. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for August 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;EasyAsm. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for August 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/introducing-easyasm/M65Digest_2024Aug.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/M65Digest_2024Aug.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
EasyAsm
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/easyasm-2.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/introducing-easyasm/easyasm-2.png 320w, https://dansanderson.com/mega65/introducing-easyasm/easyasm-2_hu_f5a0784277a2b4a0.png 600w, https://dansanderson.com/mega65/introducing-easyasm/easyasm-2_hu_14e157b88516a230.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/introducing-easyasm/easyasm-2.png&#34;
        alt=&#34;A snippet of assembly language source code&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A snippet of assembly language source code
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There&amp;rsquo;s tons of new stuff for you to download and try this month! kibo has launched a new implementation of a classic graphic adventure game engine capable of playing Maniac Mansion. The group Megastyle has released several new MEGA65 titles. And I&amp;rsquo;m launching a project of my own: an on-device assembly language programming tool for the MEGA65, called EasyAsm.&lt;/p&gt;
&lt;p&gt;Much to discuss, let&amp;rsquo;s get started!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;scumm-v2-player-by-kibo&#34;&gt;SCUMM v2 player, by kibo&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/mm.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/introducing-easyasm/mm.jpg 1990w, https://dansanderson.com/mega65/introducing-easyasm/mm_hu_853295785ad2bb9e.jpg 600w, https://dansanderson.com/mega65/introducing-easyasm/mm_hu_88fa215ecc010eb7.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/introducing-easyasm/mm.jpg&#34;
        alt=&#34;Maniac Mansion, running on a MEGA65 with kibo&amp;amp;#39;s SCUMM v2 player&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Maniac Mansion, running on a MEGA65 with kibo&amp;rsquo;s SCUMM v2 player.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You can now play the LucasArts graphic adventure-comedy game &lt;em&gt;Maniac Mansion&lt;/em&gt; directly on your MEGA65!&lt;/p&gt;
&lt;p&gt;kibo made &lt;a href=&#34;https://files.mega65.org?id=744279a9-7ee4-40c7-b34d-26d4c06d4685&#34;&gt;a new implementation of the SCUMM v2 game engine&lt;/a&gt; for the MEGA65 capable of playing the classic game, which he calls &amp;ldquo;MegaSPUTM.&amp;rdquo; This hugely impressive project uses the game data files from the Amiga version, and supports full color graphics, digitized sound, and multiple input devices.&lt;/p&gt;
&lt;p&gt;To play &lt;em&gt;Maniac Mansion,&lt;/em&gt; you need to acquire the original game data files. If you own the disks, you can use Amiga disk management tools to extract the &lt;code&gt;.LFL&lt;/code&gt; files. MegaSPUTM works with both the English and German versions of the data files.&lt;/p&gt;
&lt;p&gt;The full procedure takes a few minutes. I got it up and running like so:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download &lt;a href=&#34;https://files.mega65.org?id=744279a9-7ee4-40c7-b34d-26d4c06d4685&#34;&gt;kibo&amp;rsquo;s SCUMM v2 engine&lt;/a&gt; from Filehost. Expand the &lt;code&gt;.zip&lt;/code&gt; archive to produce D81 disk image files &lt;code&gt;mm1.d81&lt;/code&gt; and &lt;code&gt;mm2.d81&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Retrieve the &lt;code&gt;.LFL&lt;/code&gt; files from the &lt;code&gt;rooms/&lt;/code&gt; folder of the first disk of &lt;em&gt;Maniac Mansion&lt;/em&gt; for the Amiga. If your media is in the form of an ADF disk image, there are several tools you can use. I found &lt;a href=&#34;https://www.stef.be/adfviewer/&#34;&gt;this cute browser-based ADF reader&lt;/a&gt;, which does everything locally on your computer and doesn&amp;rsquo;t require uploading data to a remote server. It&amp;rsquo;s a bit obnoxious that you have to select and &amp;ldquo;download&amp;rdquo; each &lt;code&gt;.LFL&lt;/code&gt; file individually, but it works, and doesn&amp;rsquo;t require installing anything.&lt;/li&gt;
&lt;li&gt;Use a D81 disk image tool to place the &lt;code&gt;.LFL&lt;/code&gt; files from the first ADF onto &lt;code&gt;mm1.d81&lt;/code&gt;. Here too you have your choice of tools. I like &lt;a href=&#34;https://droid64.sourceforge.net/&#34;&gt;droid64&lt;/a&gt;, a Java UI application. If you use &lt;a href=&#34;https://style64.org/dirmaster&#34;&gt;DirMaster&lt;/a&gt; and possibly some others, you may need to rename the files to use lowercase &lt;code&gt;.lfl&lt;/code&gt; before adding them to the disk. (droid64 will lowercase it in transit.)&lt;/li&gt;
&lt;li&gt;Repeat steps 2 and 3 for the 2nd game disk and &lt;code&gt;mm2.d81&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Transfer &lt;code&gt;mm1.d81&lt;/code&gt; and &lt;code&gt;mm2.d81&lt;/code&gt; to the root of your MEGA65&amp;rsquo;s SD card.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now on the MEGA65, &lt;code&gt;MOUNT&lt;/code&gt; and &lt;code&gt;BOOT&lt;/code&gt; the &lt;code&gt;mm1.d81&lt;/code&gt; disk image. Crank those speakers, and use a joystick or a mouse!&lt;/p&gt;
&lt;p&gt;The original Maniac Mansion game included a printed booklet entitled &amp;ldquo;Nuke&amp;rsquo;m Alarms Owner&amp;rsquo;s Disarmament Quick Reference Guide,&amp;rdquo; which was needed early in the game. Similar to SCUMM VM and Disney&amp;rsquo;s own re-release of Maniac Mansion, this is not needed when playing the game with MegaSPUTM.&lt;/p&gt;
&lt;p&gt;C programmers, don&amp;rsquo;t miss &lt;a href=&#34;https://github.com/ki-bo/megasputm&#34;&gt;the source code&lt;/a&gt;, which is chock full of examples of how to do common and interesting things on the MEGA65 in C.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/mmdisks.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/introducing-easyasm/mmdisks.jpg 4032w, https://dansanderson.com/mega65/introducing-easyasm/mmdisks_hu_4b4e090b16e134c2.jpg 600w, https://dansanderson.com/mega65/introducing-easyasm/mmdisks_hu_e80047c5bdd8a271.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/introducing-easyasm/mmdisks.jpg&#34;
        alt=&#34;kibo&amp;amp;#39;s original Maniac Mansion game disks, with which his engine was tested&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;kibo&amp;rsquo;s original Maniac Mansion game disks, with which his engine was tested.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;new-titles-from-megastyle&#34;&gt;New titles from Megastyle&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/mega_invaders.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/introducing-easyasm/mega_invaders.png 880w, https://dansanderson.com/mega65/introducing-easyasm/mega_invaders_hu_271fb0f82f8511ea.png 600w, https://dansanderson.com/mega65/introducing-easyasm/mega_invaders_hu_16f2cc7783ce3ba.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/introducing-easyasm/mega_invaders.png&#34;
        alt=&#34;Mega Invaders, from Megastyle&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Mega Invaders, from Megastyle.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The group &lt;a href=&#34;https://megastyle.itch.io/&#34;&gt;Megastyle&lt;/a&gt; has not one, not two, but &lt;em&gt;three&lt;/em&gt; releases for the MEGA65 this month!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=4aa0893b-ac22-4e8a-a0de-d01da76c9fe2&#34;&gt;Mega Invaders&lt;/a&gt; (&lt;a href=&#34;https://megastyle.itch.io/mega-invaders&#34;&gt;itch.io link&lt;/a&gt;), an homage to Space Invaders, is a MEGA65 original with all of the nostalgic arcade game graphics and sounds you crave. Be sure to switch to PAL video mode before running the game. Joystick in port 2.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=2fe95f8f-191d-4765-b81d-65b01ad506ea&#34;&gt;Omega Race&lt;/a&gt; (&lt;a href=&#34;https://megastyle.itch.io/omega65-race&#34;&gt;itch.io link&lt;/a&gt;) is a direct port of the VIC-20 space war game to the MEGA65. Nearly all of the VIC-20 code is intact, with only small patches required to get it to run.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;https://files.mega65.org?id=9d34a8a1-16b2-470f-92ae-61c642b3af30&#34;&gt;Skramble&lt;/a&gt;, also a VIC-20 port, you fly over a landscape, destroying enemies. Check out &lt;a href=&#34;https://fgasking.wordpress.com/2006/05/24/game-spotlight-skramble/&#34;&gt;the blog article&lt;/a&gt; about the original game for the impressive technical details of how an unexpanded VIC could render such large levels.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t miss all the great C64 and Amiga titles in &lt;a href=&#34;https://megastyle.itch.io/&#34;&gt;Megastyle&amp;rsquo;s catalog&lt;/a&gt;. Their &lt;a href=&#34;https://megastyle.itch.io/esb-by-megastyle&#34;&gt;Empire Strikes Back&lt;/a&gt; remake is one of my all-time C64 faves.&lt;/p&gt;
&lt;h2 id=&#34;snake65-by-piramania&#34;&gt;Snake65, by piramania&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/snake65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/introducing-easyasm/snake65.png 704w, https://dansanderson.com/mega65/introducing-easyasm/snake65_hu_a8b2324270984cd8.png 600w, https://dansanderson.com/mega65/introducing-easyasm/snake65_hu_22cda74cd8fac583.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/introducing-easyasm/snake65.png&#34;
        alt=&#34;Snake65, by piramania&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Snake65, by piramania.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=7953b089-a257-4b5c-844e-546266049ffc&#34;&gt;Snake65&lt;/a&gt; by piramania is a modern take on a classic. It features six levels of challenging snake gameplay and charming music, and is written entirely in BASIC 65. Use W, A, S, and D on the keyboard as controls.&lt;/p&gt;
&lt;h2 id=&#34;mondrian-simulator-by-drex&#34;&gt;Mondrian Simulator, by Drex&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/mondrian.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/introducing-easyasm/mondrian.png 1024w, https://dansanderson.com/mega65/introducing-easyasm/mondrian_hu_a8d2aa2c03ccae80.png 600w, https://dansanderson.com/mega65/introducing-easyasm/mondrian_hu_69354eeeb996950c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/introducing-easyasm/mondrian.png&#34;
        alt=&#34;Mondrian Simulator, by Drex&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Mondrian Simulator, by Drex.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=5ef96200-a884-4968-a447-cd1e9661031b&#34;&gt;Mondrian Simulator&lt;/a&gt;, by Drex, is a MEGA65 demo that generates artwork in the style of abstract artist &lt;a href=&#34;https://en.wikipedia.org/wiki/Piet_Mondrian&#34;&gt;Piet Mondrian&lt;/a&gt;. Press S to start a meditative slideshow.&lt;/p&gt;
&lt;h2 id=&#34;mega65-command-line-tools-v10&#34;&gt;MEGA65 Command Line Tools v1.0&lt;/h2&gt;
&lt;p&gt;The MEGA65 project includes &lt;a href=&#34;https://github.com/mega65/mega65-tools&#34;&gt;a collection of command-line tools&lt;/a&gt; for development and testing, using a &lt;a href=&#34;https://dansanderson.com/mega65/welcome/using-jtag.html&#34;&gt;JTAG adapter&lt;/a&gt; to remotely control a MEGA65 from a PC. These tools have recently acquired new features for transferring files, ROMs, and programs over Ethernet, as well as a revised tool for core management. The &lt;a href=&#34;https://dansanderson.com/mega65/welcome/transferring-files.html&#34;&gt;M65Connect&lt;/a&gt; desktop application uses these tools behind the scenes, and I use these tools regularly as part of a &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/&#34;&gt;cross-development workflow&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can now download a formal release package of the latest command-line toolkit, version 1.0. Get it for &lt;a href=&#34;https://files.mega65.org?id=m65tools-windows&#34;&gt;Windows&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=m65tools-macos&#34;&gt;macOS&lt;/a&gt;, and &lt;a href=&#34;https://files.mega65.org?id=m65tools-linux&#34;&gt;Linux&lt;/a&gt;. The tools in this package:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;m65&lt;/code&gt; : A multi-tool for testing, debugging, and interacting with the MEGA65 over a JTAG/UART serial adapter.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mega65_ftp&lt;/code&gt; : Transfer files to and from the MEGA65 SD card, via Ethernet or JTAG/UART.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;etherload&lt;/code&gt; : Send programs and ROMs to the MEGA65&amp;rsquo;s memory over Ethernet for testing.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;coretool&lt;/code&gt; : Convert MEGA65 bitstreams to cores, and manage core metadata. Requires Python 3.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;romdiff&lt;/code&gt; : A binary patch generator, used for producing ROM patches.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mac users, remember to remove the &amp;ldquo;quarantine&amp;rdquo; attribute of the tools before using them: &lt;code&gt;xattr -d com.apple.quarantine m65.osx&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;new-list-of-alternate-cores&#34;&gt;New list of alternate cores&lt;/h2&gt;
&lt;p&gt;Looking for alternate cores available for the MEGA65? Boris Schneider-Johne has taken over maintaining the cores list from sy2002, and it now has an easy-to-remember address. Visit &lt;a href=&#34;https://cores.mega65.org/&#34;&gt;cores.mega65.org&lt;/a&gt; to be redirected to the new list. Thanks to Boris for preparing and maintaining this documentation!&lt;/p&gt;
&lt;h2 id=&#34;september-conferences&#34;&gt;September conferences&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/cloth_banner.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/introducing-easyasm/cloth_banner.jpeg 1280w, https://dansanderson.com/mega65/introducing-easyasm/cloth_banner_hu_78406bde7b7e44bb.jpeg 600w, https://dansanderson.com/mega65/introducing-easyasm/cloth_banner_hu_fe498db0fe66a77e.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/introducing-easyasm/cloth_banner.jpeg&#34;
        alt=&#34;MEGA65 booth display banner, draped over my couch&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MEGA65 booth display banner, draped over my couch.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A quick update on those September conferences in the USA: I still plan to be at the &lt;a href=&#34;https://vcfmw.org/&#34;&gt;Vintage Computer Festival Midwest&lt;/a&gt;, September 7-8 in Schaumburg, Illinois. For the first time in the show&amp;rsquo;s history, VCFMW received more talk proposals than available slots, and my proposal was not selected this year. I&amp;rsquo;m grateful that they have a presentation track at all, with a full-time volunteer staff to make quality recordings for YouTube. I have confirmed that we&amp;rsquo;ll have a table—and we might even have a real Commodore 65 next to the MEGA65!&lt;/p&gt;
&lt;p&gt;I splurged on getting some fun booth display items printed professionally, something I&amp;rsquo;ve always wanted to try. The cloth banner and table signage turned out very nicely. I also placed a bulk order of 45GS02 CPU quick reference mousepads.&lt;/p&gt;
&lt;p&gt;I, my MEGA65, and my mousepads will also be at the &lt;a href=&#34;https://www.retrogamingexpo.com/&#34;&gt;Portland Retro Gaming Expo&lt;/a&gt;, September 28-29 in Portland, Oregon. Come say hi, if you can!&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;introducing-easyasm&#34;&gt;Introducing EasyAsm&lt;/h2&gt;
&lt;p&gt;EasyAsm is a new assembly language programming tool for the MEGA65. EasyAsm runs entirely on the computer, with no need for a separate PC. It is designed to work with the existing MEGA65 environment, to give you as much control and understanding of the computer as possible, and to take advantage of the MEGA65&amp;rsquo;s existing programming workflow. EasyAsm provides a powerful subset of the syntax and features of the &lt;a href=&#34;https://sourceforge.net/projects/acme-crossass/&#34;&gt;Acme cross-assembler&lt;/a&gt;, so that you can use it with the assembly language programming examples in the documentation and in this Digest, as well as for larger programs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php&#34;&gt;Download EasyAsm from Filehost&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;See &lt;a href=&#34;https://github.com/dansanderson/easyasm65/&#34;&gt;the Github repo&lt;/a&gt; for full documentation and source code, and to file bug reports and feature requests.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Note:&lt;/em&gt; Assembling to disk requires a recent ROM beta version, 920401 or later. This will also work in the upcoming v0.97 MEGA65 platform release.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I was inspired to write EasyAsm while playing with vintage on-device assemblers for the Commodore 64. Many of these used the C64&amp;rsquo;s built-in BASIC line editor for entering assembly language source code, giving the programmer a familiar environment for managing code without the overhead of a proprietary text editor application or file management system. I realized that not only was this possible on the MEGA65, the MEGA65 could do it better and more intuitively thanks to its powerful memory management architecture, and a little-known feature of BASIC 65: &lt;em&gt;Edit mode.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;an-important-note&#34;&gt;An important note&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Save your work to disk, early and often.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Writing a program for a microcomputer using the microcomputer itself comes with the inherent risk that a bug in your program will interfere with your programming environment. EasyAsm preserves your source code in memory while you are testing your program, but this cannot be guaranteed to work if the program does something unexpected.&lt;/p&gt;
&lt;p&gt;By design, EasyAsm does &lt;em&gt;not&lt;/em&gt; force you to save your work to disk before testing your program. Please remember to do this yourself.&lt;/p&gt;
&lt;p&gt;With this announcement, I am releasing the first version of EasyAsm, which I&amp;rsquo;m calling &amp;ldquo;version 0.1.&amp;rdquo; I have tested it to the best of my ability, but it may still have bugs, including bugs that may lose data. If you find any bugs, &lt;a href=&#34;https://github.com/dansanderson/easyasm65/issues&#34;&gt;please report them&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id=&#34;a-canonical-first-program&#34;&gt;A canonical first program&lt;/h2&gt;
&lt;p&gt;To start an EasyAsm session, mount and boot the &lt;code&gt;EASYASM.D81&lt;/code&gt; disk image:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MOUNT &amp;#34;EASYASM.D81&amp;#34;
BOOT&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/easyasm_1b.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/introducing-easyasm/easyasm_1b.png 948w, https://dansanderson.com/mega65/introducing-easyasm/easyasm_1b_hu_fa75676951fdc529.png 600w, https://dansanderson.com/mega65/introducing-easyasm/easyasm_1b_hu_3635c484e315df96.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/introducing-easyasm/easyasm_1b.png&#34;
        alt=&#34;EasyAsm loaded into memory, and the OK prompt&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
EasyAsm loaded into memory, and the OK prompt
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This loads EasyAsm into memory, then returns to a blinking cursor. This is still your usual command prompt, but something is different: instead of the cursor blinking below the word &lt;code&gt;READY&lt;/code&gt;, it blinks below the word &lt;code&gt;OK&lt;/code&gt;. This is how you know the MEGA65 is in Edit mode.&lt;/p&gt;
&lt;p&gt;Try entering the following program at the &lt;code&gt;OK&lt;/code&gt; prompt. To enter the blank line on line 20, type &lt;code&gt;20&lt;/code&gt; then press &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Space&lt;/kbd&gt;, then press &lt;kbd&gt;Return&lt;/kbd&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 !TO &amp;#34;SIMPLE&amp;#34;, RUNNABLE
20
30   INC $D020
40   RTS&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Type &lt;code&gt;LIST&lt;/code&gt; to see the listing.&lt;/p&gt;
&lt;p&gt;Before doing anything else, save this source file to disk:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DSAVE &amp;#34;SIMPLE.S&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, press the &lt;kbd&gt;Help&lt;/kbd&gt; key to open the EasyAsm menu.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/introducing-easyasm/easyasm-3.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/introducing-easyasm/easyasm-3.png 948w, https://dansanderson.com/mega65/introducing-easyasm/easyasm-3_hu_4dcbf218f9c40f43.png 600w, https://dansanderson.com/mega65/introducing-easyasm/easyasm-3_hu_1b489c6e40ec8476.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/introducing-easyasm/easyasm-3.png&#34;
        alt=&#34;The EasyAsm menu&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The EasyAsm menu (as of v0.1)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Select option #1: Assemble and Test. (Press the &lt;kbd&gt;1&lt;/kbd&gt; key.) EasyAsm assembles the program, then runs it. In this case, the program you entered does two things: it changes the color of the border (&lt;code&gt;inc $d020&lt;/code&gt;), then ends the program (&lt;code&gt;rts&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Type &lt;code&gt;LIST&lt;/code&gt; again. The source code is in memory, and you can continue to make changes to the program.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s make a small improvement. The register at hexadecimal address $D020 controls the border color, but this is not obvious from the program listing. It&amp;rsquo;d be better to assign a label to this value, so it&amp;rsquo;s easier to see what&amp;rsquo;s going on. Insert the label definition with line 25, and replace line 30:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;25 BORDER = $D020
30   INC BORDER&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save the source file to disk again, this time using the &lt;code&gt;@&lt;/code&gt; symbol to tell &lt;code&gt;DSAVE&lt;/code&gt; to replace the existing file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DSAVE &amp;#34;@SIMPLE.S&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Press &lt;kbd&gt;Help&lt;/kbd&gt; then &lt;kbd&gt;1&lt;/kbd&gt; to assemble and run the program again, to confirm that it still works.&lt;/p&gt;
&lt;h2 id=&#34;using-edit-mode&#34;&gt;Using Edit mode&lt;/h2&gt;
&lt;p&gt;Edit mode is very similar to the usual BASIC mode. You can type any BASIC command at the prompt, and it&amp;rsquo;ll do it right away. The main difference is that when you type a numbered line, instead of treating it as BASIC code, Edit mode treats it as PETSCII text. The DSAVE and DLOAD commands also have special behavior in Edit mode, operating on &lt;em&gt;sequential files&lt;/em&gt; (type &lt;code&gt;SEQ&lt;/code&gt;) instead of &lt;em&gt;program files&lt;/em&gt; (type &lt;code&gt;PRG&lt;/code&gt;). You can use Edit mode to write any kind of text file, like a (very) simple word processor. With EasyAsm, you can use it to write assembly language programs.&lt;/p&gt;
&lt;p&gt;Editing works just like in BASIC. When you enter a new line, the program updates based on the line number, either inserting the line in sequence or replacing an existing line of that number. To delete a line, enter just the number, then press &lt;kbd&gt;Return&lt;/kbd&gt;. All of the built-in tools for line editing, such as the &lt;code&gt;AUTO&lt;/code&gt; and &lt;code&gt;RENUMBER&lt;/code&gt; commands, are available in Edit mode. See the &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;User&amp;rsquo;s Guide&lt;/a&gt; for information about these commands.&lt;/p&gt;
&lt;p&gt;Type &lt;code&gt;DIR&lt;/code&gt; to see the list of files on the disk. Notice that the &lt;code&gt;SIMPLE.S&lt;/code&gt; file you created is of type &lt;code&gt;SEQ&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Type &lt;code&gt;NEW&lt;/code&gt; to clear program memory. Type &lt;code&gt;LIST&lt;/code&gt; again to confirm that the source code is no longer in memory. Then re-load the source file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DLOAD &amp;#34;SIMPLE.S&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Type &lt;code&gt;LIST&lt;/code&gt;. The source file is the same—but the line numbers have changed!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1000 !TO &amp;#34;SIMPLE&amp;#34;, RUNNABLE
1010
1020 BORDER = $D020
1030   INC BORDER
1040   RTS&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a notable difference between Edit mode and BASIC mode: Edit mode does not include the line numbers when it saves the file. This is usually what you want when editing a text file, and for EasyAsm, the line numbers don&amp;rsquo;t affect how the program is assembled. However, it does mean that if you try to organize your code using groups of line numbers like you might in a large BASIC program, that organization effort is not saved between sessions.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll want to get familiar with the &lt;code&gt;RENUMBER&lt;/code&gt; command, which can insert a range of unused line numbers in the middle of your source code. For example, to renumber all lines from 1030 onward so that they start at number 2000 counting by 10s, thereby leaving a gap of available line numbers between 1030 and 2000:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RENUMBER 2000,10,1030-&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EasyAsm enables Edit mode automatically when you boot the disk. To disable Edit mode and return to BASIC mode, use this command: &lt;code&gt;EDIT OFF&lt;/code&gt; To re-enable Edit mode: &lt;code&gt;EDIT ON&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Remember that when you&amp;rsquo;re in BASIC mode, the prompt says &amp;ldquo;READY,&amp;rdquo; and when you&amp;rsquo;re in Edit mode, the prompt says &amp;ldquo;OK.&amp;rdquo; Take care to notice which mode you are in before typing in lines of a program, and before loading or saving source files. If you type a line of assembly language source while in BASIC mode, it will attempt to interpret the line as BASIC code, and produce incorrect results. And if you try to &lt;code&gt;DSAVE&lt;/code&gt; the source file while in BASIC mode, it&amp;rsquo;ll save as a PRG file.&lt;/p&gt;
&lt;h2 id=&#34;assembling-to-disk&#34;&gt;Assembling to disk&lt;/h2&gt;
&lt;p&gt;With the &lt;code&gt;SIMPLE&lt;/code&gt; program&amp;rsquo;s source code in memory, press &lt;kbd&gt;Help&lt;/kbd&gt; to open the EasyAsm menu. Now select option #2: Assemble to Disk. EasyAsm assembles the program, but instead of running it, it creates a new PRG file on disk, named &lt;code&gt;&amp;quot;SIMPLE&amp;quot;&lt;/code&gt;. You specify the name of the program file using the &lt;code&gt;!to&lt;/code&gt; directive in the code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 !TO &amp;#34;SIMPLE&amp;#34;, RUNNABLE&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Type &lt;code&gt;DIR&lt;/code&gt; to see the &lt;code&gt;SIMPLE&lt;/code&gt; program file of type &lt;code&gt;PRG&lt;/code&gt; alongside the &lt;code&gt;SIMPLE.S&lt;/code&gt; source file of type &lt;code&gt;SEQ&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I like to use a &lt;code&gt;.S&lt;/code&gt; suffix for source code filenames, then omit the suffix for the program name. Take care to not use the same name for the source file and the program file, so that EasyAsm does not overwrite your source file with the program file.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s try out the new program. Switch back to BASIC mode, then load and run the &lt;code&gt;SIMPLE&lt;/code&gt; program, like any other program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;EDIT OFF
DLOAD &amp;#34;SIMPLE&amp;#34;
RUN&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The program changes the border color, then exits.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/&#34;&gt;a previous Digest&lt;/a&gt;, we used the Acme cross-assembler to make a program like this, using a lengthy preamble to produce a runnable program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;!cpu m65
!to &amp;#34;hello.prg&amp;#34;, cbm

* = $2001

!8 $12,$20,$0a,$00,$fe,$02,$20,$30,$3a,$9e,$20
!pet &amp;#34;$2014&amp;#34;
!8 $00,$00,$00

	inc $d020
	rts&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would work in EasyAsm just as well: EasyAsm supports the &lt;code&gt;cbm&lt;/code&gt; output type similar to Acme. But EasyAsm has a feature that makes this easier. When you tell the &lt;code&gt;!to&lt;/code&gt; directive to make a &lt;code&gt;runnable&lt;/code&gt; file, EasyAsm generates this preamble for you, including setting the program counter. In fact, this &lt;code&gt;cbm&lt;/code&gt; listing and the &lt;code&gt;runnable&lt;/code&gt; version you typed produce exactly the same output.&lt;/p&gt;
&lt;p&gt;The PRG file contains your program and only your program. Give it to your friends so they too can change the colors of their borders!&lt;/p&gt;
&lt;h2 id=&#34;how-to-stop-a-running-program&#34;&gt;How to stop a running program&lt;/h2&gt;
&lt;p&gt;When you assemble-and-test your assembly language program, EasyAsm attempts to recreate the memory layout that your program will see when it runs from disk. To do this, it first copies your source code out of program memory, so it can replace it with the assembled program for testing. EasyAsm watches for the program to exit using the &lt;code&gt;rts&lt;/code&gt; instruction, then copies the source file back into program memory so you can continue to edit it.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s nice, but it&amp;rsquo;s not always possible—or even desired. A typical machine code program never exits. A broken machine code program might get stuck before it can exit.&lt;/p&gt;
&lt;p&gt;Try entering a slightly different program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 !TO &amp;#34;FOREVER&amp;#34;, RUNNABLE
20
30 LOOP:
40   INC $D020
50   JMP LOOP&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assemble and run the program. This program changes the border color repeatedly, in an infinite loop. It does not exit.&lt;/p&gt;
&lt;p&gt;To interrupt this program and return to BASIC, hold &lt;kbd&gt;Run/Stop&lt;/kbd&gt; and press &lt;kbd&gt;Restore&lt;/kbd&gt;. The program stops, and the MEGA65 Monitor starts. Type &lt;code&gt;X&lt;/code&gt; then press &lt;kbd&gt;Return&lt;/kbd&gt; to exit the Monitor and return to the &lt;code&gt;OK&lt;/code&gt; prompt.&lt;/p&gt;
&lt;p&gt;Now type &lt;code&gt;LIST&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Uh oh, there&amp;rsquo;s something wrong with the first line! EasyAsm did not see the program exit with the &lt;code&gt;rts&lt;/code&gt; instruction, so it didn&amp;rsquo;t get a chance to restore the source file. The assembled instructions are still in program memory, having overwritten the source.&lt;/p&gt;
&lt;p&gt;When this happens—and it will happen often—use menu option #9 to tell EasyAsm to bring back the source file. Press &lt;kbd&gt;Help&lt;/kbd&gt;, then press &lt;kbd&gt;9&lt;/kbd&gt;. Type &lt;code&gt;LIST&lt;/code&gt; again to see the restored source.&lt;/p&gt;
&lt;h2 id=&#34;how-easyasm-uses-memory&#34;&gt;How EasyAsm uses memory&lt;/h2&gt;
&lt;p&gt;EasyAsm tries to maintain a minimal memory footprint while you are editing your source code, and while your program is running. This allows you to use all the tools at your disposal for editing, and allows your program to use most of the computer, while still retaining a useful on-device workflow.&lt;/p&gt;
&lt;p&gt;Of course, EasyAsm has to live somewhere. This is what EasyAsm needs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EasyAsm reserves the memory ranges $1E00-$1EFF (256 bytes of bank 0) and $8700000-$87FFFFF (1 megabyte of Attic RAM). If your program overwrites any of this memory, you will need to reload EasyAsm, and any stashed source code data may not be recoverable.&lt;/li&gt;
&lt;li&gt;EasyAsm reserves the right to overwrite $50000-$5FFFF (all 64KB of bank 5) when you invoke EasyAsm. Your program can use this memory while it is running, but the state of this memory may change when EasyAsm is running. Overwriting this memory may inhibit EasyAsm&amp;rsquo;s ability to return to the &lt;code&gt;OK&lt;/code&gt; prompt on &lt;code&gt;rts&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;EasyAsm will refuse to assemble to addresses $1E00-$1EFF when assembling to memory, or when assembling a &lt;code&gt;runnable&lt;/code&gt; program to disk (because the bootstrap routine may use it in the future). This restriction does not apply when assembling to disk in &lt;code&gt;cbm&lt;/code&gt; mode.&lt;/p&gt;
&lt;p&gt;If your program needs to use $1E00-$1EFF for its own purposes, that&amp;rsquo;s entirely fine. Just be aware that it will interfere with the EasyAsm workflow.&lt;/p&gt;
&lt;h2 id=&#34;whats-next-for-easyasm&#34;&gt;What&amp;rsquo;s next for EasyAsm?&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m fairly confident that I could have used this initial version of EasyAsm to write many of the programs I&amp;rsquo;ve written for the MEGA65 so far. There are a few features I want to add to really make it feel like a complete assembler:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!binary&lt;/code&gt;: embed a file of binary data into a program (such as graphics or sound assets)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!source&lt;/code&gt;: use multiple source files to describe a program (such as with reusable libraries), and to produce programs larger than Edit mode&amp;rsquo;s 44 KB memory limit for a single source file&lt;/li&gt;
&lt;li&gt;Inspect an annotated source listing with program counter and byte values next to the original source lines (Acme&amp;rsquo;s &amp;ldquo;report&amp;rdquo; feature)&lt;/li&gt;
&lt;li&gt;Inspect a list of label definitions (Acme&amp;rsquo;s &amp;ldquo;symbol list&amp;rdquo; feature)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have a roadmap of other feature ideas that I&amp;rsquo;m considering, though they&amp;rsquo;ll take more substantial work and I want to see if anyone actually uses EasyAsm first. 😇 To me, the most important of these would be &lt;em&gt;macros,&lt;/em&gt; a feature of Acme and other assemblers that makes programs easier to write, test, and manage. It&amp;rsquo;s possible to write substantial programs without macros—the MEGA65 ROM source has no macros in it at all—but macros are a powerful way to organize code, reuse common structures, and mitigate some of the fragility of the low-level language.&lt;/p&gt;
&lt;p&gt;As clever as Edit mode is, it would be nice to have a more modern IDE-like text editor as an option. Personally, I&amp;rsquo;d love the experience of building a nice text editor, and I want to try it someday. I intentionally designed EasyAsm so that it could be integrated into other projects, so anyone else&amp;rsquo;s programming tools could use it.&lt;/p&gt;
&lt;p&gt;I wrote EasyAsm from scratch in pure assembly language. I learned a lot about assembly language from this experience, and will be &lt;del&gt;milking this for content&lt;/del&gt; writing about this in future episodes of the Digest.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I included a few sample programs on the D81 disk image based on previous Digest and blog articles. Try loading their source files and assembling them. The longest file on the disk right now is my assembly language implementation of &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/&#34;&gt;Robot Finds Kitten&lt;/a&gt;, 35 KB of source that assembles in six seconds.&lt;/p&gt;
&lt;p&gt;Want to see continued development of EasyAsm, or my other projects like this Digest? Please consider becoming a patron. Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I hope you try EasyAsm, and I hope it makes it easier to get started with assembly language programming. Let me know how it goes!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/introducing-easyasm/M65Digest_2024Aug.mp3" length="31444576" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1572</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/introducing-easyasm/easyasm-2.png"/>
      
    </item>
    
    <item>
      <title>Let&#39;s paint!</title>
      <link>https://dansanderson.com/mega65/lets-paint/</link>
      <pubDate>Wed, 17 Jul 2024 22:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/lets-paint/</guid>
      <description>&lt;p&gt;Let&amp;rsquo;s paint! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for July 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Let&amp;rsquo;s paint! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for July 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/lets-paint/M65Digest_2024July.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/M65Digest_2024July.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Let&#39;s paint!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/canvas.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/lets-paint/canvas.png 696w, https://dansanderson.com/mega65/lets-paint/canvas_hu_44c17b4c3d154242.png 600w, https://dansanderson.com/mega65/lets-paint/canvas_hu_aba0a438131baf23.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/lets-paint/canvas.png&#34;
        alt=&#34;A blank canvas&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A blank canvas.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I feel like painting today. Let&amp;rsquo;s paint!&lt;/p&gt;
&lt;p&gt;Oh, uh, but first&amp;hellip;&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;my-talk-at-pacommex-nw-is-online&#34;&gt;My talk at PaCommEx NW is online&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/pacommex2024.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/lets-paint/pacommex2024.png 1110w, https://dansanderson.com/mega65/lets-paint/pacommex2024_hu_d419b19b556cea1a.png 600w, https://dansanderson.com/mega65/lets-paint/pacommex2024_hu_bc6fccc94e9ae57a.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/lets-paint/pacommex2024.png&#34;
        alt=&#34;The title slide of my talk at Pacific Commodore Expo Northwest&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;My talk at Pacific Commodore Expo Northwest&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;My talk about the MEGA65 at Pacific Commodore Expo Northwest 2024, &lt;a href=&#34;https://www.youtube.com/watch?v=QY1Zj5tIhL4&#34;&gt;Lessons from My First Two Years with the MEGA65&lt;/a&gt;, is now on YouTube. My thanks to Robert Bernardo for producing the event, to Stephen Jones and &lt;a href=&#34;https://sdf.org/&#34;&gt;SDF.org&lt;/a&gt; for sponsoring, and to everyone who attended. We had three MEGA65s on the floor this year, including &lt;a href=&#34;https://www.youtube.com/watch?v=HYT8zUi7axQ&#34;&gt;a live unboxing&lt;/a&gt; of a freshly delivered unit!&lt;/p&gt;
&lt;h2 id=&#34;mega65-at-the-vintage-computer-festival-midwest-september-7-8-2024&#34;&gt;MEGA65 at the Vintage Computer Festival Midwest, September 7-8, 2024&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/vcfmw.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/lets-paint/vcfmw.png 1262w, https://dansanderson.com/mega65/lets-paint/vcfmw_hu_324ad7afdc307ee3.png 600w, https://dansanderson.com/mega65/lets-paint/vcfmw_hu_7ae9b3c9949dca17.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/lets-paint/vcfmw.png&#34;
        alt=&#34;Vintage Computer Festival Midwest, image of the website&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Vintage Computer Festival Midwest.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;m working up plans to be at the &lt;a href=&#34;https://vcfmw.org/&#34;&gt;Vintage Computer Festival Midwest&lt;/a&gt;, September 7-8, 2024, at the Schaumburg Convention Center in Schaumburg, Illinois near Chicago. This large show attracts enthusiasts from all over the USA and Canada, and is a regular pilgrimage for collectors, computer clubs, YouTubers, and makers of modern retro computers and peripherals. Admission is free.&lt;/p&gt;
&lt;p&gt;This year, I&amp;rsquo;ll be collaborating with Jim Happel (jim_64) on a MEGA65 table. I&amp;rsquo;ve also applied for a speaking slot to deliver a revised version of the &amp;ldquo;Lessons from&amp;hellip;&amp;rdquo; talk, though those won&amp;rsquo;t be announced until next month, so, fingers crossed. 🤞&lt;/p&gt;
&lt;h2 id=&#34;mega65-at-the-portland-retro-gaming-expo-september-27-29-2024&#34;&gt;MEGA65 at the Portland Retro Gaming Expo, September 27-29, 2024&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/prge.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/lets-paint/prge.png 357w, https://dansanderson.com/mega65/lets-paint/prge_hu_4f42167c00096351.png 600w, https://dansanderson.com/mega65/lets-paint/prge_hu_ebc001cc336171d8.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/lets-paint/prge.png&#34;
        alt=&#34;The Portland Retro Gaming Expo&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The Portland Retro Gaming Expo.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;My MEGA65 and I will be at the &lt;a href=&#34;https://retrogamingexpo.com/&#34;&gt;Portland Retro Gaming Expo&lt;/a&gt;, September 27-29, 2024, in Portland, Oregon, USA. PRGE is one of the largest vintage video gaming shows in the Pacific Northwest, and this year they&amp;rsquo;re doing a home computing exhibition. Come for the interactive volunteer-run computer exhibits, then stay for the weekend of talks, playable arcade games, and the vendor floor. I&amp;rsquo;m not doing a talk at this one, but I&amp;rsquo;ll have my own table in the home computing area.&lt;/p&gt;
&lt;p&gt;PRGE is a &lt;a href=&#34;https://checkout.conventions.leapevent.tech/eh/Portland_Retro_Gaming_Expo_2024?cc=F99&#34;&gt;ticketed event&lt;/a&gt; at the Oregon Convention Center. If you&amp;rsquo;re visiting from out of town, get your hotel rooms reserved early—and make sure to leave time to explore Portland!&lt;/p&gt;
&lt;h2 id=&#34;c64-core-v51-released&#34;&gt;C64 core v5.1 released&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/c64.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/lets-paint/c64.jpg 1024w, https://dansanderson.com/mega65/lets-paint/c64_hu_764a3b9f8282dda0.jpg 600w, https://dansanderson.com/mega65/lets-paint/c64_hu_f9e7b4205011d76a.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/lets-paint/c64.jpg&#34;
        alt=&#34;The Commodore 64 core for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The Commodore 64 core for the MEGA65&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=896a012f-59e4-456c-b91f-7e989b958241&#34;&gt;The C64 core for the MEGA65&lt;/a&gt;, one of the best things you can do for your favorite computer, has a new update. Version 5.1 adds support for the R6 mainboard, the board in all MEGA65s being delivered this year, and can take advantage of the R6 board&amp;rsquo;s bidirectional expansion port lines for Kung Fu Flash, MSSIAH, and freezer cartridge support. This update also includes improvements for all mainboards, including the ability to share the MEGA65&amp;rsquo;s Real-Time Clock with GEOS, using an appropriate driver.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t forget that the MEGA65 has a new feature that can select the C64 core automatically when a C64 cartridge is installed. If your MEGA65 was delivered this year, your firmware is already up to date with this feature. If you have an older MEGA65, you can update to the v0.96 release in &amp;ldquo;slot 0&amp;rdquo; to get this feature. See the &lt;a href=&#34;https://files.mega65.org/?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt;, for upgrade instructions.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/MJoergen/C64MEGA65/blob/master/VERSIONS.md&#34;&gt;the C64 core release notes&lt;/a&gt; for details on all of the changes.&lt;/p&gt;
&lt;h2 id=&#34;retrocombs-mega65-video-users-guide&#34;&gt;retroCombs MEGA65 Video User&amp;rsquo;s Guide&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/retrocombs.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/lets-paint/retrocombs.png 1347w, https://dansanderson.com/mega65/lets-paint/retrocombs_hu_fadccfbbac82ca22.png 600w, https://dansanderson.com/mega65/lets-paint/retrocombs_hu_daeeacf29e17dec0.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/lets-paint/retrocombs.png&#34;
        alt=&#34;retroCombs MEGA65 User&amp;amp;#39;s Guide video series&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;retroCombs MEGA65 User&amp;rsquo;s Guide video series.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;retroCombs is producing &lt;a href=&#34;https://www.youtube.com/playlist?list=PLRVBh2hjFTomDGwIT7uPMJv4zH9JAUSVG&#34;&gt;a video series based on the MEGA65 User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt;. Steven is going chapter by chapter, reviewing the material, and presenting it in an entertaining and easy-to-understand fashion. It&amp;rsquo;s the perfect video companion to the Guide, and a useful resource in its own right, with additional tips not mentioned in the book. Steven just released &lt;a href=&#34;https://www.youtube.com/watch?v=C-PNB9rlzV4&amp;amp;list=PLRVBh2hjFTomDGwIT7uPMJv4zH9JAUSVG&amp;amp;index=5&#34;&gt;the video for chapter 4&lt;/a&gt;, and intends to complete the series for the entire book.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/@retroCombs&#34;&gt;Subscribe to retroCombs&lt;/a&gt; to make sure you don&amp;rsquo;t miss a video!&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;canvas&#34;&gt;Canvas&lt;/h2&gt;
&lt;p&gt;I need a canvas to paint on. Something 320 pixels wide and 200 pixels tall is good enough to start. I just want to use the 32 built-in colors for now, so a bit depth of 5 is plenty. (Five binary bits can express up to 32 values: 2 x 2 x 2 x 2 x 2 = 32.) I&amp;rsquo;ll use screen number 0.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SCREEN 0,320,200,5&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, that&amp;rsquo;s fine. I can&amp;rsquo;t see what I&amp;rsquo;m typing now because the text is behind the painting, but I can hold &lt;kbd&gt;Run/Stop&lt;/kbd&gt; and tap &lt;kbd&gt;Restore&lt;/kbd&gt; to get back to the text screen.&lt;/p&gt;
&lt;p&gt;Blank canvases are intimidating. Whenever I buy a new notebook, I always scribble nonsense on the first page, so I&amp;rsquo;m not afraid to make mistakes on the other pages. I&amp;rsquo;ll take a swipe with some white paint (color 1).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PEN 1
LINE 20,30,300,180&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can specify locations on the canvas using numbers, one for the distance in pixels across from the left (the X coordinate), and one for the distance down from the top (the Y coordinate). With a 320 x 200 screen, coordinate X=0 Y=0 is the top-left corner, and X=319 Y=199 is the bottom-right corner. I drew my line from the position X=20 Y=30 to X=300 Y=180.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/palette.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/lets-paint/palette.png&#34;
            width=&#34;422&#34;
            height=&#34;316&#34;
            alt=&#34;The MEGA65 system palette of 32 colors&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 system palette of 32 colors.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The 32 colors of the built-in palette are listed in the &lt;a href=&#34;https://files.mega65.org?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;MEGA65 User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt;, appendix E. The first 16 of these are also written on the fronts of the number keys on the keyboard from &lt;kbd&gt;1&lt;/kbd&gt; to &lt;kbd&gt;8&lt;/kbd&gt;, in two rows: colors 0 through 7 are the top row (&amp;ldquo;Blk&amp;rdquo; through &amp;ldquo;Yel&amp;rdquo;), and colors 8 through 15 are the bottom row (&amp;ldquo;Orng&amp;rdquo; through &amp;ldquo;L Gry&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;I need to switch back to the canvas to see my white line. I&amp;rsquo;ll set my screen 0 to be both the canvas I&amp;rsquo;m drawing on and the canvas I&amp;rsquo;m looking at.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SCREEN SET 0,0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I notice that typing &lt;code&gt;SCREEN 0,320,200,5&lt;/code&gt; again will not switch back to the existing canvas, it&amp;rsquo;ll open a new blank one. Here&amp;rsquo;s a way to clear an already-opened canvas, by filling it with color #6 (blue):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SCREEN CLR 6&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Flipping back and forth between the text screen and the canvas is a bit cumbersome. I think I&amp;rsquo;ll put all of my painting commands into a BASIC program. This way, the MEGA65 can recreate my picture by following my painting instructions, and I can save my program to a floppy disk.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SCREEN 0,320,200,5
20 PEN 1
30 LINE 20,30,300,170

DSAVE &amp;#34;LINE&amp;#34;

RUN&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can press &lt;kbd&gt;Run/Stop&lt;/kbd&gt; + &lt;kbd&gt;Restore&lt;/kbd&gt; to get back to text mode, make changes to the program, and &lt;code&gt;RUN&lt;/code&gt; it again to see the result.&lt;/p&gt;
&lt;p&gt;If I wanted to give this program to someone else, they might enjoy being able to exit back to text mode by pressing a key. Here&amp;rsquo;s a simple way to do that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;9998 GETKEY A$
9999 SCREEN CLOSE 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In addition to lines, BASIC has commands for drawing dots, and drawing shapes of several kinds, both filled and unfilled. I&amp;rsquo;m just messing around, changing the numbers to see how they change the picture.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;40 PEN 2
50 DOT 4,4
60 DOT 5,5
70 DOT 6,4
80 DOT 7,5
90 DOT 8,4

100 PEN 3
110 BOX 180,10,240,50
120 BOX 200,30,260,70,1

130 PEN 4
140 CIRCLE 50,150,24
150 CIRCLE 70,130,24,1

160 PEN 5
170 ELLIPSE 180,150,50,20
180 ELLIPSE 160,130,50,20,1

190 PEN 6
200 POLYGON 250,100,40,40,5
210 POLYGON 270,120,40,40,5,,,,1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, the User&amp;rsquo;s Guide has more information on how these commands work, including some additional interesting features.&lt;/p&gt;
&lt;p&gt;Here is a simple picture I made.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5 BORDER 0
10 SCREEN 0,320,200,5
20 PEN 27:BOX 0,0,319,30,1
30 PEN 28:BOX 0,31,319,60,1
40 PEN 29:BOX 0,61,319,90,1
50 PEN 30:BOX 0,91,319,120,1
60 PEN 0:CIRCLE 220,280,200,1
70 BOX 200,60,240,60,230,90,210,90,1
80 BOX 200,48,240,48,250,60,190,60,1
90 BOX 210,42,213,42,213,48,210,48,1
100 PEN 7:BOX 222,65,227,65,226,72,223,72,1
110 PEN 11:CIRCLE 213,36,4,1
120 CIRCLE 223,33,3,1
130 CIRCLE 232,31,4,1&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;computer-art&#34;&gt;Computer art&lt;/h2&gt;
&lt;p&gt;Wherever there&amp;rsquo;s a number in a computer program, there could also be some computation that produces a number. This can turn math formulas, variables, and flow control structures into their own kind of computational paintbrush.&lt;/p&gt;
&lt;p&gt;I want to try a simple grid pattern with regularly spaced lines. Instead of writing out all of the coordinates for each line, I&amp;rsquo;ll have the MEGA65 figure it out for me.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5 BORDER 0
10 SCREEN 0,320,200,5
20 PEN 1
30 FOR X=0 TO 319 STEP 20
40 LINE X,0,X,199
50 NEXT X
60 FOR Y=0 TO 199 STEP 20
70 LINE 0,Y,319,Y
80 NEXT Y&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can tell the computer how to calculate a number. Or, I can just let the computer pick a number at random. The computer can use its own imagination to paint a picture, in accordance with my instructions. (well actually computers don&amp;rsquo;t have imaginations and random numbers aren&amp;rsquo;t really random and whatever it&amp;rsquo;s fun)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5 BORDER 0
10 SCREEN 0,320,200,5
20 PEN RND(1)*32
30 LINE RND(1)*320,RND(1)*200,RND(1)*320,RND(1)*200
40 GOTO 20&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;BASIC 65 has some mathematical functions that can help paint interesting pictures, if I can remember enough geometry.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5 BORDER 0
10 SCREEN 0,320,200,5
20 FOR Z=0 TO 4
30 PEN RND(1)*32
40 R=RND(1)*40+20
50 CX=RND(1)*200+60
60 CY=RND(1)*80+60
70 FOR A=0 TO 2*π STEP 2*π/30
80 LINE CX,CY,CX+COS(A)*R,CY+SIN(A)*R
90 NEXT A
100 NEXT Z&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Those symbols on line 70 are the Greek letter pi (π), which I typed with &lt;kbd&gt;Shift&lt;/kbd&gt; + up-arrow. In BASIC 65, this is the geometric constant pi, defined as the circumference of a circle divided by its diameter. Someone check my math.&lt;/p&gt;
&lt;h2 id=&#34;graphing-calculator&#34;&gt;Graphing calculator&lt;/h2&gt;
&lt;p&gt;I keep my MEGA65 on my desk and sometimes just use it as a simple calculator, typing a question mark &lt;code&gt;?&lt;/code&gt; followed by an arithmetic expression at the &lt;code&gt;READY.&lt;/code&gt; prompt to get a quick answer. I wonder if I could make the MEGA65 into a graphing calculator.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 DEF FN Y(X) = SIN(X*9)+1.5
2 XL = -3 : XH = 3
3 YL = -1 : YH = 4
4 REM ======================
5 BORDER 0
10 SCREEN 0,320,200,5
20 REM ==== DRAW AXES
30 PEN 12
40 IF 0 &amp;lt; XL OR XH &amp;lt; 0 THEN 70
50 V = 0:L = XL:H = XH:SC = 320:GOSUB 1000:XC = C
60 LINE XC,0,XC,199
70 IF 0 &amp;lt; YL OR YH &amp;lt; 0 THEN 100
80 V = 0:L = YL:H = YH:SC = 200:GOSUB 1000:YC = 199-C
90 LINE 0,YC,319,YC
94 IF XC &amp;gt; 351 THEN XC = 351
95 IF YC &amp;gt; 192 THEN YC = 192
100 CHAR 0,YC+1,1,1,2,STR$(XL)
110 CHAR 39-LEN(STR$(XH)),YC+1,1,1,2,STR$(XH)
120 CHAR XC/8+1,0,1,1,2,STR$(YH)
130 CHAR XC/8+1,191,1,1,2,STR$(YL)
140 REM ==== DRAW FUNCTION
150 PEN 7
160 PX = 0
170 V = FN Y(XL):L = YL:H = YH:SC = 200:GOSUB 1000:PY = SC-C
180 FOR X = XL TO XH STEP (XH-XL)/160
190 V = X:L = XL:H = XH:SC = 320:GOSUB 1000:NX = C
200 V = FN Y(X):L = YL:H = YH:SC = 200:GOSUB 1000:NY = SC-C
210 LINE PX,PY,NX,NY
220 PX = NX : PY = NY
230 NEXT X
999 END
1000 REM ==== SCALE V TO C WITHIN RANGE (L,H) BY SC
1010 C = (V-L)/(H-L)*SC
1020 IF C &amp;gt; SC THEN C = SC
1030 IF C &amp;lt; 0 THEN C = 0
1040 RETURN&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Huh&amp;hellip; That&amp;rsquo;s interesting&amp;hellip;&lt;/p&gt;
&lt;p&gt;I think I got the gist of this right. The first few lines define the function to be plotted, and the domain (&lt;code&gt;XL&lt;/code&gt; to &lt;code&gt;XH&lt;/code&gt;) and range (&lt;code&gt;YL&lt;/code&gt; to &lt;code&gt;YH&lt;/code&gt;) to use for the graph.&lt;/p&gt;
&lt;p&gt;The subroutine starting on line 1000 scales a value &lt;code&gt;V&lt;/code&gt; to screen coordinate &lt;code&gt;C&lt;/code&gt; within value range (&lt;code&gt;L&lt;/code&gt;,&lt;code&gt;H&lt;/code&gt;) scaled by &lt;code&gt;SC&lt;/code&gt;. For example, to convert an X value to a horizontal screen coordinate, I set &lt;code&gt;V&lt;/code&gt; to the X value, &lt;code&gt;L&lt;/code&gt; to &lt;code&gt;XL&lt;/code&gt;, &lt;code&gt;H&lt;/code&gt; to &lt;code&gt;XH&lt;/code&gt;, and &lt;code&gt;SC&lt;/code&gt; to 320 (the pixel width of the screen). The subroutine returns with &lt;code&gt;C&lt;/code&gt; set to the horizontal screen coordinate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;190 V = X:L = XL:H = XH:SC = 320:GOSUB 1000:NX = C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I use this subroutine for every such conversion. Importantly, I need to invert the vertical coordinate that comes back from this, because math graphs go up as Y values increase, but screen coordinates go down. So &lt;code&gt;PX = C&lt;/code&gt;, and &lt;code&gt;PY = SC-C&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To keep this simple, I only draw a zero-axis if the zero is within the range/domain, and I don&amp;rsquo;t bother with tick marks. I use the &lt;code&gt;CHAR&lt;/code&gt; command to print the range/domain values close to the zero-axis lines, if appropriate, making sure they stay on screen.&lt;/p&gt;
&lt;p&gt;To draw the function itself, I calculate a starting point based on its value for the leftmost point on the screen, &lt;code&gt;FN Y(XL)&lt;/code&gt;, then loop over 160 evenly spaced points between &lt;code&gt;XL&lt;/code&gt; and &lt;code&gt;XH&lt;/code&gt;. For each iteration, I draw a line from the previous point to the next. &lt;code&gt;PX&lt;/code&gt;/&lt;code&gt;NX&lt;/code&gt; and &lt;code&gt;PY&lt;/code&gt;/&lt;code&gt;NY&lt;/code&gt; are the previous and next horizontal and vertical screen coordinates.&lt;/p&gt;
&lt;p&gt;Real graphing calculators are pretty sophisticated. They need to be to produce something useful under all circumstances. For example, I just allow a graph that goes off the top or bottom of the screen to squash up against the edge. The &lt;code&gt;LINE&lt;/code&gt; command doesn&amp;rsquo;t mind receiving fractional coordinates, but it will complain if I give it values outside of the screen. This could be improved by calculating exactly where the graph crosses the edge. But I&amp;rsquo;m painting here, not building something useful.&lt;/p&gt;
&lt;p&gt;Also my sine graphs have a bit of a cowlick in some spots, for some reason. I&amp;rsquo;m guessing this is hitting up against the range limits of BASIC 65 floating point numbers. Math is hard. 🤷 Moving on&amp;hellip;&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/lets-paint/cowlick.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/lets-paint/cowlick.png&#34;
            width=&#34;161&#34;
            height=&#34;124&#34;
            alt=&#34;A graph of the BASIC 65 sine function (actually a cropped photo of actor Austin Butler&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A graph of the BASIC 65 sine function?
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;paintbrush&#34;&gt;Paintbrush&lt;/h2&gt;
&lt;p&gt;Painting with code is fun, but this computer can do more than use hand-entered numbers or numbers derived from math and randomness. I can also write a program that changes numbers interactively based on keys I press on the keyboard. Here&amp;rsquo;s the simplest version of this idea:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SCREEN 0,320,200,5
20 X=100:Y=100
30 PEN 1
40 DOT X,Y
50 GETKEY A$
60 IF A$=CHR$(17) AND Y&amp;lt;199 THEN Y=Y+1
70 IF A$=CHR$(29) AND X&amp;lt;319 THEN X=X+1
80 IF A$=CHR$(145) AND Y&amp;gt;0 THEN Y=Y-1
90 IF A$=CHR$(157) AND X&amp;gt;0 THEN X=X-1
100 GOTO 40&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This operates similarly to our &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/&#34;&gt;Robot Finds Kitten&lt;/a&gt; experiment from a while back. The program maintains a cursor position in the X and Y variables. It waits for a keypress, then compares it to the PETSCII codes for the cursor keys. After it confirms the cursor position won&amp;rsquo;t leave the screen, it changes the cursor position, then draws a dot. I can move the dot around the screen, and it leaves a trail, like an &lt;a href=&#34;https://en.wikipedia.org/wiki/Etch_A_Sketch&#34;&gt;Etch-a-Sketch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I could also make this controllable with a joystick, with almost no changes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SCREEN 0,320,200,5
20 X=100:Y=100
30 PEN 1
40 J=JOY(2)
50 DOT X,Y
60 IF J=5 AND Y&amp;lt;199 THEN Y=Y+1
70 IF J=3 AND X&amp;lt;319 THEN X=X+1
80 IF J=1 AND Y&amp;gt;0 THEN Y=Y-1
90 IF J=7 AND X&amp;gt;0 THEN X=X-1
100 GOTO 40&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whoa! Uh, slow down there, partner:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;55 SLEEP 0.01&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This only supports four directions of movement, and actually feels like it sticks when I accidentally press the joystick in a diagonal direction. The &lt;code&gt;JOY()&lt;/code&gt; function returns different values for diagonals. (See the &lt;a href=&#34;https://files.mega65.org/?id=a5081244-a976-4a21-9153-27cca13fd613&#34;&gt;User&amp;rsquo;s Guide&lt;/a&gt;.) This should work.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;60 IF (J=4 OR J=5 OR J=6) AND Y&amp;lt;199 THEN Y=Y+1
70 IF (J=2 OR J=3 OR J=4) AND X&amp;lt;319 THEN X=X+1
80 IF (J=8 OR J=1 OR J=2) AND Y&amp;gt;0 THEN Y=Y-1
90 IF (J=8 OR J=7 OR J=6) AND X&amp;gt;0 THEN X=X-1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&amp;rsquo;d be nice if I had more control over the paintbrush behavior. Maybe if it doesn&amp;rsquo;t draw unless I press the button?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;50 IF J AND 128 THEN DOT X,Y:J=J AND 127&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;JOY()&lt;/code&gt; returns a value 0 through 8 representing the joystick direction, plus 128 if the fire button is pressed. I&amp;rsquo;m using a bitwise &lt;code&gt;AND&lt;/code&gt; both to test the button on its own, and to erase the button part of the value for the rest of the comparisons.&lt;/p&gt;
&lt;p&gt;OK that works, but now I can&amp;rsquo;t really see what I&amp;rsquo;m doing. Before, it was always drawing, so I could usually see where it will draw next when I move. Now it&amp;rsquo;s only drawing when the button is pressed. I need some kind of cursor on the display that doesn&amp;rsquo;t draw into the image itself.&lt;/p&gt;
&lt;p&gt;On Commodores, that&amp;rsquo;s what sprites are for. &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/&#34;&gt;We covered sprites&lt;/a&gt;, yeah? I&amp;rsquo;m just going to use the built-in arrow sprite for now:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;15 SPRITE 0,1

45 MOVSPR 0,X+24,Y+50&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember that the sprite coordinate system is not the same as the screen coordinate system inside the border. The upper corner for a sprite is X=24, Y=50, so I need to add these values to the &lt;code&gt;MOVSPR&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s pretty good&amp;hellip; Looks like there might be &lt;a href=&#34;https://github.com/MEGA65/mega65-core/issues/810&#34;&gt;a bug in sprite coordinates over bitplanes&lt;/a&gt;. We&amp;rsquo;ll have to look into that.&lt;/p&gt;
&lt;p&gt;That arrow cursor reminds me, I could also write this to use the mouse. This simplifies the code quite a bit because the KERNAL does its own range checking on the mouse position. My program just needs to read the mouse position, check for the button press, and draw a dot there if it is pressed. I still need to offset the mouse coordinates when I draw, this time in the other direction because &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Y&lt;/code&gt; are set to sprite coordinates by the &lt;code&gt;RMOUSE&lt;/code&gt; command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SCREEN 0,320,200,5
20 MOUSE ON,1
30 PEN 1
40 RMOUSE X,Y,B
50 IF B THEN DOT X-24,Y-50
60 GOTO 40&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;rsquo;s neat! The dots are a bit spread apart though. I wonder if I can combine this with the technique in the graphing calculator to get a smoother line while the button is pressed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SCREEN 0,320,200,5
20 MOUSE ON,1
30 PEN 1
40 PX=-1
50 RMOUSE X,Y,B
60 IF B&amp;lt;&amp;gt;128 THEN PX=-1:GOTO 50
70 X=X-24:Y=Y-50
80 IF PX=-1 THEN 100
90 LINE PX,PY,X,Y
100 PX=X:PY=Y
110 GOTO 50&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hmmm&amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;41 SPRITE 0,1,1

51 GET A$:IF A$&amp;lt;&amp;#34;1&amp;#34; OR A$&amp;gt;&amp;#34;9&amp;#34; THEN 60
52 PEN VAL(A$)
53 SPRITE 0,1,VAL(A$)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Maybe&amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;90 CIRCLE X+RND(1)*10-5,Y+RND(1)*10-5,RND(1)*5,1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And what about&amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;42 SC=1

61 SC=SC-1
62 IF SC&amp;gt;0 THEN 70
63 SOUND 1,RND(1)*65535,5
64 SC=50&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oh, here&amp;rsquo;s an idea&amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;90 LINE PX,PY,X,Y
91 LINE 320-PX,PY,320-X,Y
92 LINE PX,200-PY,X,200-Y
93 LINE 320-PX,200-PY,320-X,200-Y&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;That was fun!&lt;/p&gt;
&lt;p&gt;Did I forget to include screenshots of my paintings? Ah, well. I suppose you can always just type these in and see what happens.&lt;/p&gt;
&lt;p&gt;If you liked this one, please consider supporting the Digest with a contribution. I hope to continue making more of these, and your support goes a long way to making that possible. Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Happy painting! See you next month.&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/lets-paint/M65Digest_2024July.mp3" length="56205376" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>2810</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/lets-paint/canvas.png"/>
      
    </item>
    
    <item>
      <title>KERNAL of Truth</title>
      <link>https://dansanderson.com/mega65/kernal-of-truth/</link>
      <pubDate>Mon, 17 Jun 2024 20:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/kernal-of-truth/</guid>
      <description>&lt;p&gt;KERNAL of Truth. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for June 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;KERNAL of Truth. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for June 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/kernal-of-truth/M65Digest_2024Jun.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/M65Digest_2024Jun.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
KERNAL of Truth
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/trenz2024_2.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/kernal-of-truth/trenz2024_2.jpg 1541w, https://dansanderson.com/mega65/kernal-of-truth/trenz2024_2_hu_a7050e213f88ef9b.jpg 600w, https://dansanderson.com/mega65/kernal-of-truth/trenz2024_2_hu_ba9eac6c97ad0098.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/kernal-of-truth/trenz2024_2.jpg&#34;
        alt=&#34;Pallets of MEGA65 parts, courtesy Trenz Electronic&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pallets of MEGA65 parts, courtesy Trenz Electronic
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Summer of MEGA65 begins! The latest delivery batch is in progress, and many preorder holders are receiving their new favorite computer.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re new to this Digest, welcome! Here you&amp;rsquo;ll find news about the MEGA65 and community projects, and interactive feature articles of things you can try for yourself. Read the Digest while next to your MEGA65 and PC for the best experience.&lt;/p&gt;
&lt;p&gt;Also, every Digest has a read-aloud audio edition. Click the audio player at the top of the email or website, or subscribe to &amp;ldquo;Dan&amp;rsquo;s MEGA65 Digest&amp;rdquo; in your podcast player. I don&amp;rsquo;t know how many people listen to it, but I enjoy making it.&lt;/p&gt;
&lt;p&gt;In this Digest, we&amp;rsquo;ll start taking a look at the MEGA65 KERNAL, the main operating system of the computer. We&amp;rsquo;ll build off of last month&amp;rsquo;s discussion of interrupts and the CPU memory map, and try writing a MEGA65 version of a classic KERNAL extension: a desktop time-of-day clock.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s get started!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;batch-3-is-arriving&#34;&gt;Batch #3 is arriving!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/trenz2024_1.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/kernal-of-truth/trenz2024_1.jpg 2373w, https://dansanderson.com/mega65/kernal-of-truth/trenz2024_1_hu_69ca29d7a040e23e.jpg 600w, https://dansanderson.com/mega65/kernal-of-truth/trenz2024_1_hu_46500a595941c0b.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/kernal-of-truth/trenz2024_1.jpg&#34;
        alt=&#34;MEGA65s being tested, courtesy Trenz Electronic&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MEGA65s being tested, courtesy Trenz Electronic&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;MEGA65 home computers are now arriving with their new owners! Trenz Electronic has begun sending out the third manufacturing batch, and will continue to fulfill pre-orders steadily. Congrats and welcome to everyone receiving a new bundle of joy!&lt;/p&gt;
&lt;p&gt;Back in January, we were able to confirm with Trenz that this manufacturing batch will be large enough to cover all preorders placed up to that point. I continue to use that as a conservative estimate. New preorders placed in the last few months may need to wait a bit longer—or maybe not. For all we know, Trenz may be able to make quick work of another batch and get everyone taken care of. Rest assured that everyone involved in this project &lt;em&gt;wants&lt;/em&gt; you to have a MEGA65 as soon as possible.&lt;/p&gt;
&lt;p&gt;Of course, &lt;a href=&#34;https://shop.trenz-electronic.de/en/TE0765-06-T001CK-MEGA65-highly-advanced-C64-and-C65-compatible-8-bit-computer?c=564&#34;&gt;you can still order the MEGA65&lt;/a&gt; if you haven&amp;rsquo;t already. Tell your friends!&lt;/p&gt;
&lt;h2 id=&#34;mega65-at-the-pacific-commodore-expo-northwest-june-22-23-2024&#34;&gt;MEGA65 at the Pacific Commodore Expo Northwest, June 22-23, 2024&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/pacommex.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/kernal-of-truth/pacommex.png 656w, https://dansanderson.com/mega65/kernal-of-truth/pacommex_hu_658906bb30dd9456.png 600w, https://dansanderson.com/mega65/kernal-of-truth/pacommex_hu_b3b497ceda2a881.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/kernal-of-truth/pacommex.png&#34;
        alt=&#34;Pacific Commodore Expo Northwest; image from a talk I gave in 2023&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Pacific Commodore Expo Northwest.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If you&amp;rsquo;re near Seattle, Washington, USA this month, I will be presenting the MEGA65 at the &lt;a href=&#34;https://portcommodore.com/dokuwiki/doku.php?id=pacommex:start&#34;&gt;Pacific Commodore Expo Northwest&lt;/a&gt;, June 22-23, 2024. Admission is free. The space is cozy and filled with Commodores, and this year we have access to additional space for presentations. I&amp;rsquo;ll have my MEGA65 at a table all weekend for people to try.&lt;/p&gt;
&lt;p&gt;I gave &lt;a href=&#34;https://www.youtube.com/watch?v=vYTTn3fLNxc&#34;&gt;a talk on the MEGA65 at last year&amp;rsquo;s PaCommEx NW&lt;/a&gt; that went reasonably well, despite being hastily planned. Here&amp;rsquo;s hoping that I&amp;rsquo;ll have this year&amp;rsquo;s talk figured out in time. 😬&lt;/p&gt;
&lt;h2 id=&#34;the-silent-enigma&#34;&gt;The Silent Enigma&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/enigma.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/kernal-of-truth/enigma.png 655w, https://dansanderson.com/mega65/kernal-of-truth/enigma_hu_7779b2ba4a24c5dd.png 600w, https://dansanderson.com/mega65/kernal-of-truth/enigma_hu_1fe8c686fedca8be.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/kernal-of-truth/enigma.png&#34;
        alt=&#34;The Silent Enigma, by Gurce&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The Silent Enigma, by Gurce&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=4003af71-8f8d-48ff-a303-f0eac34dd465&#34;&gt;The Silent Enigma&lt;/a&gt; is a new demo by Gurce, based on &lt;a href=&#34;https://www.youtube.com/watch?v=_iCDTMkTduE&#34;&gt;the song by Anathema&lt;/a&gt;. Gurce wrote the demo in BASIC 65 with the Eleven IDE, with assembly language helper routines in &lt;a href=&#34;https://files.mega65.org?id=3b101d41-5128-4a21-879c-0cf7988edfec&#34;&gt;Mega Assembler&lt;/a&gt; and &lt;a href=&#34;https://sourceforge.net/projects/acme-crossass/&#34;&gt;Acme&lt;/a&gt;, and an extended version of &lt;a href=&#34;https://files.mega65.org?id=a3b2c04a-2a22-4913-8005-308dfe9e7971&#34;&gt;grim-fandango&amp;rsquo;s MEGAPLOT library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The current version of the demo requires customized versions of the MEGA65 core and ROM to run on MEGA65 hardware. Gurce discovered a need for a new feature of the KERNAL for combining BASIC and machine code routines, and also discovered a core bug while getting it to work. We&amp;rsquo;re working on getting these improvements into the core platform. In the meantime, Gurce is &lt;a href=&#34;https://gurce.net/silent.zip&#34;&gt;distributing modified core and ROM files with the demo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Check out &lt;a href=&#34;https://youtu.be/FtYOagApWcM&#34;&gt;retroComb&amp;rsquo;s video debuting The Silent Enigma&lt;/a&gt;, along with an interview with Gurce. And don&amp;rsquo;t miss the Eleven and assembly language source files included on the disk!&lt;/p&gt;
&lt;h2 id=&#34;lala-the-magical-preview&#34;&gt;Lala The Magical (preview)&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/lala.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/kernal-of-truth/lala.png 640w, https://dansanderson.com/mega65/kernal-of-truth/lala_hu_13baf72d6f09922b.png 600w, https://dansanderson.com/mega65/kernal-of-truth/lala_hu_fa643f51879bf626.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/kernal-of-truth/lala.png&#34;
        alt=&#34;Lala the Magical (preview) for the MEGA65, by Majikeyric&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Lala the Magical (preview) for the MEGA65, by Majikeyric&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Majikeyric is previewing a new game for the MEGA65! &lt;a href=&#34;https://files.mega65.org?id=a0182829-1a5a-4e3a-a666-b52eafaa3ec9&#34;&gt;Lala the Magical (preview)&lt;/a&gt; is an adorable puzzle platformer, with parallax scrolling areas and tons of enemies and collectibles. It&amp;rsquo;s based on &lt;a href=&#34;https://dosgames.com/game/lala-the-magical-prologue/&#34;&gt;the PC DOS game by the Mojon Twins&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In the ancient ruins (province of Badajoz) lives Lala with her teacher. She is learning magic but still has a long way to go.&lt;/p&gt;
&lt;p&gt;“Tell me about the Sky Palace” – asks Lala, and her teacher tells her again about the three Power Gems hidden inside. “I’d love to see them”, but Lala’s teacher would say no… “It’s too dangerous, and powerful magic is required to traverse the palace”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can play the preview with a joystick. Sound, music, and polish are in progress. I&amp;rsquo;m looking forward to the final product!&lt;/p&gt;
&lt;h2 id=&#34;wonder-boy-core&#34;&gt;Wonder Boy core&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/wonderboy.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/kernal-of-truth/wonderboy.png 165w, https://dansanderson.com/mega65/kernal-of-truth/wonderboy_hu_58770b82f073941.png 600w, https://dansanderson.com/mega65/kernal-of-truth/wonderboy_hu_3f5200f1ee194468.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/kernal-of-truth/wonderboy.png&#34;
        alt=&#34;Wonder Boy, arcade core by muse&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Wonder Boy, arcade core by muse&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;muse continues his series of arcade cores with &lt;a href=&#34;https://files.mega65.org?id=7365cb17-4375-45d3-a833-a89a38266c5e&#34;&gt;Wonder Boy&lt;/a&gt;. This colorful side-runner will have you running, jumping, and even skateboarding across the landscape, collecting fruit and dodging creatures.&lt;/p&gt;
&lt;p&gt;This core is available for both R3 (2022) and R6 (2024) MEGA65s. Be sure to use the correct version for your system, and &lt;a href=&#34;https://github.com/sho3string/SEGASYS1MEGA65&#34;&gt;follow the installation instructions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Arcade cores use the MEGA65&amp;rsquo;s FPGA to fully recreate arcade game chipsets with a high degree of accuracy. Thanks to muse for his continued dedication to the arcade core library!&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;the-role-of-the-kernal&#34;&gt;The role of the KERNAL&lt;/h2&gt;
&lt;p&gt;In computer architecture, the &lt;em&gt;kernel&lt;/em&gt; is the center of a computer&amp;rsquo;s operating system. It manages access to hardware such as the keyboard, storage devices, and peripherals, as well as other common facilities. Programs—including the rest of the operating system—access these facilities by interacting with the kernel.&lt;/p&gt;
&lt;p&gt;The Commodore KERNAL has played this role in Commodore 8-bit computers all the way back to the Commodore PET. The proper name, spelled with an &amp;ldquo;A&amp;rdquo; and all uppercase, &lt;a href=&#34;https://en.wikipedia.org/wiki/KERNAL#The_name&#34;&gt;is credited&lt;/a&gt; to an honest misspelling of the word &amp;ldquo;kernel&amp;rdquo; by developer Robert Russell that made its way into the VIC-20 programmer&amp;rsquo;s manual. While the KERNAL has evolved substantially across the line all the way up to the Commodore 65, its role in the computer and many of its key features and interfaces have remained largely the same since 1977.&lt;/p&gt;
&lt;p&gt;In total, a Commodore computer&amp;rsquo;s operating system consists of the KERNAL, the BASIC interpreter, and the screen editor. The machine code for the operating system is etched into a ROM chip, wired to be the first thing the CPU sees when it wakes up. If the KERNAL detects that a C64-style cartridge is connected, it passes control to the cartridge. Otherwise, the KERNAL starts the screen editor, from which the user can load and run programs, type other commands, or start programming in BASIC. These three components tend to share some responsibilities, and the distinctions between them can be a bit blurry in some places, but that&amp;rsquo;s the general idea.&lt;/p&gt;
&lt;p&gt;(There&amp;rsquo;s an interesting historical exception to the start-up procedure. The Commodore 64 was designed with support for cartridges made for the Commodore MAX, aka &amp;ldquo;Ultimax&amp;rdquo; or &amp;ldquo;VC-10.&amp;rdquo; An Ultimax cartridge connects directly to the 6510 chip&amp;rsquo;s I/O lines in a way that causes the CPU to go directly to the cartridge for its first instructions. The Ultimax did not have its own operating system: it relied on the connected cartridge for everything.)&lt;/p&gt;
&lt;h2 id=&#34;programming-with-the-kernal&#34;&gt;Programming with the KERNAL&lt;/h2&gt;
&lt;p&gt;There are three main ways the KERNAL participates in the execution of programs: KERNAL subroutine calls, the KERNAL IRQ handler, and vectors.&lt;/p&gt;
&lt;h3 id=&#34;kernal-subroutines&#34;&gt;KERNAL subroutines&lt;/h3&gt;
&lt;p&gt;A program can call subroutines in the KERNAL code to perform tasks and interact with the KERNAL&amp;rsquo;s systems. Here&amp;rsquo;s a simple machine code program that writes a short message to the screen by calling the KERNAL subroutine BSOUT:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bsout = $ffd2

    lda #&amp;#39;H&amp;#39;
    jsr bsout
    lda #&amp;#39;I&amp;#39;
    jsr bsout
    lda #13
    jsr bsout&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The BSOUT routine writes a single character to the current output device, which by default is the screen editor. The program sets the accumulator to the character to be written as a PETSCII code, then calls BSOUT with the JSR instruction to address $FFD2. The subroutine does all of the work to write the character, then returns.&lt;/p&gt;
&lt;p&gt;The screen editor does a lot of work here. It maintains a text cursor—the same one that you type with at the READY prompt—that has a position on the screen, and a draw state including the text color and other attributes. When it receives a character from the program via BSOUT, the screen editor figures out what changes to make to screen and character attribute memory, moves the cursor position, and scrolls the screen up if the text runs off the bottom. (&lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/&#34;&gt;Other PETSCII codes&lt;/a&gt; change the draw state or cursor position in other ways.)&lt;/p&gt;
&lt;p&gt;The screen editor is a full-fledged built-in application that behaves like &lt;a href=&#34;https://en.wikipedia.org/wiki/Computer_terminal&#34;&gt;an input/output terminal&lt;/a&gt;. Your program writes to and reads from this terminal using KERNAL subroutines.&lt;/p&gt;
&lt;h3 id=&#34;the-kernal-subroutine-jump-table&#34;&gt;The KERNAL subroutine jump table&lt;/h3&gt;
&lt;p&gt;$FFD2 is not actually the memory location of the BSOUT subroutine. Instead, the KERNAL keeps a JMP instruction at that address that goes to the actual subroutine code. Each KERNAL subroutine available to programs has one of these, in a fixed memory location called a &lt;em&gt;jump table&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_jumptable.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_jumptable.png&#34;
            width=&#34;277&#34;
            height=&#34;372&#34;
            alt=&#34;The program, KERNAL subroutine, and jump table, in memory&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The program, KERNAL subroutine, and jump table, in memory.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The jump table provides a critical layer of compatibility across different versions of the KERNAL. Your program needs an explicit address to where it can jump, to invoke the subroutine. When the KERNAL developers inevitably need to relocate the subroutine code to a different address in a new version of the operating system, they can just update the address in the jump table, and your program (and everyone else&amp;rsquo;s) will continue to run correctly because the jump table itself doesn&amp;rsquo;t move.&lt;/p&gt;
&lt;p&gt;I recently added an appendix to &lt;a href=&#34;https://files.mega65.org/?id=d668168c-1fef-4560-a530-77e9e237536d&#34;&gt;the MEGA65 Compendium&lt;/a&gt; describing all of the KERNAL subroutines and how to use them, including jump table addresses, CPU register arguments, and example programs. Check it out, and let me know what you think!&lt;/p&gt;
&lt;h3 id=&#34;the-kernal-raster-irq&#34;&gt;The KERNAL raster IRQ&lt;/h3&gt;
&lt;p&gt;As we covered in detail &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/&#34;&gt;in last month&amp;rsquo;s Digest&lt;/a&gt;, you can program the VIC video chip to tell the CPU when its raster beam is at a given vertical location on the screen. This triggers an &lt;em&gt;interrupt&lt;/em&gt; that causes the CPU to call a special kind of subroutine known as an &lt;em&gt;interrupt handler.&lt;/em&gt; A typical use of the vertical raster beam interrupt is to have a chunk of program code that gets called many times per second at regular intervals. This allows the program to be organized as if it is two programs running side by side: a main program that runs normally, and a short secondary program kicked along by the interrupt.&lt;/p&gt;
&lt;p&gt;The KERNAL uses this raster interrupt in this way. It installs an interrupt handler that pays regular attention to KERNAL subsystems while the user&amp;rsquo;s program is running. The KERNAL IRQ handler drives behaviors of the screen editor such as blinking the cursor and checking for special keyboard combinations like &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;Shift&lt;/kbd&gt;, and behaviors of BASIC such as sprite move animations (from the &lt;code&gt;MOVSPR&lt;/code&gt; command) and music playback (from the &lt;code&gt;PLAY&lt;/code&gt; command).&lt;/p&gt;
&lt;p&gt;Most programs can just take for granted that the KERNAL is doing its own thing with the raster IRQ. As we saw last month, only one IRQ handler can be installed at a time, so a program that wants to take over the IRQ handler must disable the KERNAL. But the KERNAL has a way it can share its IRQ handler with a program, so they can both play&amp;hellip;&lt;/p&gt;
&lt;h3 id=&#34;kernal-vectors&#34;&gt;KERNAL vectors&lt;/h3&gt;
&lt;p&gt;The KERNAL generously offers programs the ability to replace or extend some of the KERNAL&amp;rsquo;s own subroutines. In these cases, when the KERNAL wants to call one of its own subroutines, it looks up the address in a table. This table is initialized to the address of the KERNAL&amp;rsquo;s version of the subroutine, so without changes, everything behaves normally. A program can replace that address with an address of its own, so the KERNAL calls the program&amp;rsquo;s routine instead. This indirect address is called a &lt;em&gt;vector&lt;/em&gt;, because of how it points to where the KERNAL will go.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_vector1.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_vector1.png&#34;
            width=&#34;594&#34;
            height=&#34;472&#34;
            alt=&#34;How the KERNAL uses a vector table, before and after a customization&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
How the KERNAL uses a vector table, before and after a customization.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A program can replace a KERNAL routine by re-pointing a vector, but this is a heavy task in most cases. Much more common is to extend the existing KERNAL routine with additional functionality. It works like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Read the address of the original KERNAL routine from the vector table.&lt;/li&gt;
&lt;li&gt;Write that address into a JMP instruction at the end of the program&amp;rsquo;s custom routine.&lt;/li&gt;
&lt;li&gt;Re-point the vector to the beginning of the custom routine.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now when the KERNAL calls the vector, control goes to the custom routine. The custom routine does some custom things, then jumps to the KERNAL&amp;rsquo;s original routine. The KERNAL routine still does the heavy lifting, and the custom routine just adds a bit of extra functionality.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_vector2.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_vector2.png&#34;
            width=&#34;594&#34;
            height=&#34;224&#34;
            alt=&#34;A custom vector routine returning to the KERNAL&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A custom vector routine returning to the KERNAL.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This is how the KERNAL can share its IRQ handler. In the middle of the KERNAL&amp;rsquo;s IRQ handler, it calls a vector that points right back at the rest of the IRQ handler. A program can use the vector to insert its own routine that gets called as part of the KERNAL&amp;rsquo;s raster IRQ. This way, the program can combine the KERNAL IRQ and its custom IRQ routine, all running alongside its main program code.&lt;/p&gt;
&lt;p&gt;Custom vectors remain installed when your program returns to BASIC. This allows a program to extend KERNAL behaviors used by BASIC and the screen editor. The custom IRQ vector is especially fun for this. A game written in BASIC can invoke a small amount of machine code to install an IRQ vector that plays a SID music file, and this music plays in the background while BASIC runs the rest of the game. You could even listen to SID music while writing your BASIC program, with the playback routine running alongside the screen editor!&lt;/p&gt;
&lt;p&gt;Note that &lt;kbd&gt;Run/Stop&lt;/kbd&gt; + &lt;kbd&gt;Restore&lt;/kbd&gt; will reset KERNAL vectors. There are ways to prevent this, but we won&amp;rsquo;t cover them here for now. In general, this is a good thing, so you can get the system back to normal when a bug in a vector routine gets out of control.&lt;/p&gt;
&lt;h2 id=&#34;the-vector-accessor&#34;&gt;The VECTOR accessor&lt;/h2&gt;
&lt;p&gt;The KERNAL keeps its vector table in its own private memory location. To read from or write to the vector table, a program calls a KERNAL subroutine that copies the table to or from the program&amp;rsquo;s memory. The full procedure for installing an extension vector routine is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Call VECTOR, telling it to copy the vector table to program memory.&lt;/li&gt;
&lt;li&gt;Copy the original vector address from the table into a JMP instruction at the end of the custom routine.&lt;/li&gt;
&lt;li&gt;Write the address of the custom routine to the program&amp;rsquo;s copy of the vector table.&lt;/li&gt;
&lt;li&gt;Call VECTOR again, telling it to copy the vector table from program memory into KERNAL memory.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Some Commodore programmers are accustomed to reading and writing custom vector addresses directly from internal KERNAL memory, without using the VECTOR routine. For the MEGA65, it is important for programs to use the VECTOR accessor routine, and to not depend on the internal KERNAL memory address. Just like how the jump table protects your program from KERNAL subroutines jiggling around between ROM versions, the VECTOR accessor protects your program from the KERNAL vector table jiggling in the same way.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll try an example below. See the entry for VECTOR in the &amp;ldquo;KERNAL Jump Table&amp;rdquo; appendix of the Compendium for a complete explanation, along with a description of the vector table.&lt;/p&gt;
&lt;h2 id=&#34;a-bit-more-about-the-map&#34;&gt;A bit more about the MAP&lt;/h2&gt;
&lt;p&gt;Last month, we briefly considered the CPU memory map, just enough to understand that the KERNAL assigns itself into the $E000-$FFFF address range so it can take over the IRQ handler address stored at $FFFE-$FFFF. We ditched the KERNAL by zeroing out the memory map, so all 16-bit addresses referred to RAM in the MEGA65&amp;rsquo;s first (well, zeroth) 64K memory bank.&lt;/p&gt;
&lt;p&gt;I will continue to avoid a complete description of the MAP register—see the &amp;ldquo;Memory&amp;rdquo; chapter of the Compendium for that—but it&amp;rsquo;s worth knowing a bit more about how the KERNAL uses MAP when integrating with it using jump table entries and vectors.&lt;/p&gt;
&lt;h3 id=&#34;mapping-16-bit-addresses-to-28-bit-addresses&#34;&gt;Mapping 16-bit addresses to 28-bit addresses&lt;/h3&gt;
&lt;p&gt;Recall that the CPU sees 64KB of memory at a time, using 16-bit addresses $0000 to $FFFF. The MEGA65 has a much larger 28-bit address space, $000.0000 to $FFF.FFFF. The memory map assigns 8KB regions of the 16-bit space to parts of the 28-bit space, and a program can reconfigure this map with the CPU instructions &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;eom&lt;/code&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_map1.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_map1.png&#34;
            width=&#34;604&#34;
            height=&#34;231&#34;
            alt=&#34;The CPU MAP associates 16-bit addresses with 28-bit addresses&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The CPU MAP associates 16-bit addresses with 28-bit addresses.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There are actually a few ways the CPU can read and write memory using full 28-bit addresses without changing the map. Crucially, the CPU can only execute machine code instructions via 16-bit addresses. In other words, to execute code somewhere in the MEGA65&amp;rsquo;s memory, the memory map must have an 8KB region mapped to that location. Instructions like JMP use the 16-bit address into the memory map to find that code.&lt;/p&gt;
&lt;h3 id=&#34;two-kernal-maps&#34;&gt;Two KERNAL maps&lt;/h3&gt;
&lt;p&gt;When the MEGA65 starts, it runs BASIC, the screen editor, and the KERNAL all together to power the familiar READY prompt, blinking cursor, program line editor, and library of BASIC commands. The operating system code that powers all of this lives in bank 3. There&amp;rsquo;s a lot of it, so in this mode, most of the memory map points to bank 3. Specifically, $2000 to $BFFF refer to $3.2000 to $3.BFFF, and $E000 to $FFFF refer to $3.E000 to $3.FFFF.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_basicmap.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/kernal-of-truth/kernal_basicmap.png&#34;
            width=&#34;651&#34;
            height=&#34;162&#34;
            alt=&#34;The BASIC MAP&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The BASIC MAP.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If the operating system is hogging most of the 16-bit addresses, where does our program code live? The KERNAL has two tricks up its sleeve, one for BASIC, and one for machine code.&lt;/p&gt;
&lt;p&gt;A BASIC program lives in RAM in bank 0, starting at address $0.2001. The BASIC interpreter uses the CPU&amp;rsquo;s ability to read from 28-bit addresses to access BASIC program code. The machine code for the interpreter lives in memory starting at $3.2000, and is mapped in to 16-bit addresses starting at $2000. The interpreter itself reads the BASIC code from MEGA65 RAM directly using 28-bit addresses starting at $0.2000. (You&amp;rsquo;ll get used to it.)&lt;/p&gt;
&lt;p&gt;A typical standalone assembly language program, the kind we start with the &lt;code&gt;RUN&lt;/code&gt; command, starts with a short BASIC program that consists of a &lt;code&gt;SYS&lt;/code&gt; command and the address of the beginning of the machine code, such as $2014. The machine code lives right next to the BASIC starter code, in bank 0 from $0.2014 onward. The CPU can&amp;rsquo;t execute this machine code when the BASIC memory map is active. So how does &lt;code&gt;SYS&lt;/code&gt; get to it?&lt;/p&gt;
&lt;p&gt;The answer: &lt;code&gt;SYS&lt;/code&gt; changes the map. In the new map, only $E000 to $FFFF are mapped to $3.E000 to $3.FFFF. This is the KERNAL, without the BASIC interpreter or the screen editor.&lt;/p&gt;
&lt;p&gt;In both maps, the unmapped region $C000 to $DFFF connects to I/O registers and whatnot, using features of the memory system that we won&amp;rsquo;t discuss here. See the &amp;ldquo;Memory&amp;rdquo; chapter for details.&lt;/p&gt;
&lt;h3 id=&#34;so-what&#34;&gt;So what?&lt;/h3&gt;
&lt;p&gt;Understanding how the KERNAL uses the memory map is important when writing software that depends on the KERNAL.&lt;/p&gt;
&lt;p&gt;If your machine code program is a game or demo that doesn&amp;rsquo;t need the KERNAL for anything, it can map out the KERNAL, take over the interrupt handlers, and run the whole show. The tradeoff is, if you want to do something like read a file from disk, you&amp;rsquo;ll have to provide your own driver routines that interface directly with hardware registers.&lt;/p&gt;
&lt;p&gt;If your program calls KERNAL subroutines, or if it installs vectors but does not return to BASIC, the SYS map will work just fine. The KERNAL routines live in $E000 to $FFFF, and this is present in both the BASIC map and the SYS map. The KERNAL&amp;rsquo;s internal memory is in the $0000-$15FF region, in bank 0.&lt;/p&gt;
&lt;p&gt;If your program installs vector routines then returns to BASIC, those routines must live in a region that&amp;rsquo;s accessible from the BASIC map, not just the SYS map. This means your vector routines must live within $1600 to $1EFF.&lt;/p&gt;
&lt;p&gt;The vector routines themselves can do something fancy like disable interrupts, change the map, do something with code elsewhere in memory, then restore the map and re-enable interrupts before continuing on. See that &amp;ldquo;Memory&amp;rdquo; chapter again if you want to try to figure that out.&lt;/p&gt;
&lt;h2 id=&#34;project-a-desktop-clock&#34;&gt;Project: a desktop clock&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s 10 o&amp;rsquo;clock at night, the kids and spouse have gone to bed, and you finally have a bit of time to play with your MEGA65. You flip through the User&amp;rsquo;s Guide, scroll through some old Digests, and decide to try a little BASIC program. You type a few lines, run the program, get a satisfying result, then write some more code. Everything is going great. Then you look up and it&amp;rsquo;s 3 o&amp;rsquo;clock in the morning! And you have an important work meeting in five hours! If only you had a little clock display in the corner of the MEGA65&amp;rsquo;s screen, you wouldn&amp;rsquo;t be in this mess.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s try extending the KERNAL with an IRQ routine that prints the current time of day in the corner of the screen. This program has two parts: an installer that sets up the IRQ vector to point to a clock printing routine, and the clock routine itself.&lt;/p&gt;
&lt;p&gt;To keep the memory management simple, we will assemble everything starting at address $1600, leaving out the BASIC preamble of a traditional program assembled to $2001. This complicates the user instructions a bit: the user must load the program with the &lt;code&gt;BLOAD&lt;/code&gt; command, and start it with &lt;code&gt;SYS $1600&lt;/code&gt;. But this turns out to be somewhat convenient. If the user resets the KERNAL vectors with &lt;kbd&gt;Run/Stop&lt;/kbd&gt; + &lt;kbd&gt;Restore&lt;/kbd&gt;, they can re-install the clock by running &lt;code&gt;SYS $1600&lt;/code&gt; again.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the full listing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;!cpu m65
!to &amp;#34;clock.prg&amp;#34;, cbm
!symbollist &amp;#34;clock.lst&amp;#34;

* = $1600

vector = $ff8d
scrnptr = $d060
attrmem = $d800
rtc = $fd7110    ; RTC registers at $0ffd7110
rtc_mb = $0f

    ; Read vector table into memory
    sec
    ldx #&amp;lt;vectable
    ldy #&amp;gt;vectable
    jsr vector

    ; Copy the iirq vector to custom_irq&amp;#39;s
    ; jmp instruction
    lda vectable
    sta custom_irq_return+1
    lda vectable+1
    sta custom_irq_return+2

    ; Write custom_irq address to iirq
    lda #&amp;lt;custom_irq
    sta vectable
    lda #&amp;gt;custom_irq
    sta vectable+1

    ; Install updated vector table
    clc
    ldx #&amp;lt;vectable
    ldy #&amp;gt;vectable
    jsr vector

    ; Return to BASIC
    rts

custom_irq:
    lda #rtc_mb
    sta $ff
    lda #^rtc
    sta $fe
    lda #&amp;gt;rtc
    sta $fd
    lda #&amp;lt;rtc
    sta $fc

    ldx #0     ; X: output buffer position
    ldz #2     ; Z: 2=hours, 1=minutes,
               ;    0=seconds
-   lda [$fc],z
    cpz #2     ; Hours value needs truncation
    bne +
    and #$7f
+   tay
    ; Convert Binary Coded Decimal (BCD)
    ; to two screen codes
    lsr
    lsr
    lsr
    lsr
    clc
    adc #48
    sta clock_buf,x
    inx
    tya
    and #$0f
    clc
    adc #48
    sta clock_buf,x
    inx
    inx         ; Skip over colon
    dez
    bpl -

    ; Copy clock_buf to the screen
    lda #72     ; column of clock display
    ldx #0
    ldy #0
    ldz #0
    adcq scrnptr  ; screen memory address,
                  ;   plus column offset
    stq $fc       ; $fc-$ff = where the clock
                  ;   will go

    ldz #7
    ldx #7
-   lda clock_buf,x
    sta [$fc],z
    dez
    dex
    bpl -

    ; Reverse white
    ldx #7
    lda #33
-   sta attrmem+72,x
    dex
    bpl -

custom_irq_return:
    jmp $0000
custom_irq_end:

clock_buf:
    !byte 48,48,58,48,48,58,48,48  ; 00:00:00

vectable:
    !fill $30&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Things to notice:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;* = $1600&lt;/code&gt; : The installer assembles to address $1600, with the IRQ routine immediately following. The assembler creates the file &lt;code&gt;clock.prg&lt;/code&gt; with this starting address. The user can load it with &lt;code&gt;BLOAD &amp;quot;CLOCK&amp;quot;&lt;/code&gt;. Note that &lt;code&gt;DLOAD &amp;quot;CLOCK&amp;quot;&lt;/code&gt; will not load it to the correct address and should not be used.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sta custom_irq_return+1&lt;/code&gt; : The &lt;code&gt;jmp $0000&lt;/code&gt; instruction at the end of the custom IRQ routine assembles to three bytes, one for the &lt;code&gt;jmp&lt;/code&gt; instruction and two for the address. The installer copies the original KERNAL IRQ vector to the address portion of this instruction.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$0ffd7110&lt;/code&gt; : The Real-Time Clock can be read from hardware registers starting at $0FFD7110. There are six byte registers: seconds, minutes, hours, day-date, month, year (from the year 2000). Each value is a two-digit Binary Coded Decimal (BCD), where each 4-bit nibble represents one decimal digit. This might seem like a crazy way to store a number, but it&amp;rsquo;s quite useful when the end goal is to display it as a decimal number. To read the left digit alone, shift right four times: &lt;code&gt;lsr&lt;/code&gt;&amp;hellip;. To read the right digit alone, mask out the upper four bits: &lt;code&gt;and #$0f&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;and #$7f&lt;/code&gt; : The hours value needs its top bit masked out for some reason.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;adcq scrnptr&lt;/code&gt; : The address of screen memory where the clock should be drawn is calculated by adding 72 to the starting address of screen memory, read from the VIC SCRNPTR register ($D060-$D063). This is a 28-byte pointer, and using the Q virtual register to calculate column 72 allows this to support any text screen configuration, including 80x50 mode. Of course, on a 40x25 screen, an offset of 72 would put it on the second row. This could be improved by detecting the screen width. See the SCRORG KERNAL routine for one way to do this.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sta attrmem+72,x&lt;/code&gt; : To make the clock stand out, it is drawn with character attributes for reverse mode and a white color. The VIC makes the first 2KB of attribute memory visible at $D800, which is sufficient to reach the top half of the screen. See the &amp;ldquo;Memory&amp;rdquo; chapter for an explanation of attribute memory. (Naturally, the &amp;ldquo;72&amp;rdquo; in this statement would also have to change to support the clock on the first row in 40-column mode.)&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Here&amp;rsquo;s a pre-assembled version of the clock program if you want to play with it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;clock.d81&#34;&gt;clock.d81&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A reminder of the instructions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;To load the clock: &lt;code&gt;BLOAD &amp;quot;CLOCK&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;To start the clock: &lt;code&gt;SYS $1600&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Run/Stop&lt;/kbd&gt; + &lt;kbd&gt;Restore&lt;/kbd&gt; stops the clock. &lt;code&gt;SYS $1600&lt;/code&gt; again to bring it back.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;Did you enjoy this Digest? Consider supporting the Digest with money! Visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn/&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Oh, and be sure to &lt;a href=&#34;mailto:contact@dansanderson.com&#34;&gt;send me a photo&lt;/a&gt; of your MEGA65 set-up! I might feature it in a future issue.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/kernal-of-truth/M65Digest_2024Jun.mp3" length="30605500" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1530</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/kernal-of-truth/trenz2024_2.jpg"/>
      
    </item>
    
    <item>
      <title>Racing the Beam</title>
      <link>https://dansanderson.com/mega65/racing-the-beam/</link>
      <pubDate>Fri, 31 May 2024 18:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/racing-the-beam/</guid>
      <description>&lt;p&gt;Racing the Beam. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for May 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Racing the Beam. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for May 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/racing-the-beam/M65Digest_2024May.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/M65Digest_2024May.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Racing the Beam.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;At least once before in this Digest I&amp;rsquo;ve said something about how there&amp;rsquo;s a way to write a program to perform precisely timed actions, but the actual technique would have to wait until a future issue. In this issue, we&amp;rsquo;ll start looking into this, with a focus on synchronizing a program with a particularly useful hardware feature: the &lt;em&gt;raster beam&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;To do this effectively, we&amp;rsquo;ll introduce an important programming paradigm supported directly by a feature of the CPU, called &lt;em&gt;interrupts&lt;/em&gt;. To get that to work, we&amp;rsquo;ll also take a brief look at how to uninstall the KERNAL operating system by changing the system&amp;rsquo;s memory map.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;any-news&#34;&gt;Any news?&lt;/h2&gt;
&lt;p&gt;Trenz Electronic is busily assembling new MEGA65s, still on track for delivering the next batch in the next few weeks. The Discord and Forum64 board have been quieter than usual, with everyone starting new projects or resting up from previous ones. I can&amp;rsquo;t wait for the rush of new people joining and asking questions!&lt;/p&gt;
&lt;p&gt;If you have a project in progress that you&amp;rsquo;d like to see featured in the Digest, &lt;a href=&#34;mailto:contact@dansanderson.com&#34;&gt;let me know&lt;/a&gt;! You can also announce your project in the &lt;code&gt;#announcements&lt;/code&gt; channel on the Discord, and upload your work in progress to &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt; for others to try. Beginners welcome! Some of the coolest stuff we&amp;rsquo;ve seen for the MEGA65 has been written in BASIC by people like you just trying things out.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;the-time-keepers&#34;&gt;The time keepers&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/16MHZ_Crystal.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/racing-the-beam/16MHZ_Crystal.jpg 714w, https://dansanderson.com/mega65/racing-the-beam/16MHZ_Crystal_hu_ad64ec352729ebaa.jpg 600w, https://dansanderson.com/mega65/racing-the-beam/16MHZ_Crystal_hu_6be68b0b6fbbf62f.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/racing-the-beam/16MHZ_Crystal.jpg&#34;
        alt=&#34;16 MHz crystal oscillator. Photo by oomlout - https://www.flickr.com/photos/snazzyguy/4150705616/, CC BY-SA 2.0, https://commons.wikimedia.org/w/index.php?curid=23310595&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
16 MHz crystal oscillator.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Every computer contains &lt;a href=&#34;https://en.wikipedia.org/wiki/Crystal_oscillator&#34;&gt;a component&lt;/a&gt; that generates a &lt;em&gt;clock signal,&lt;/em&gt; a fast and precisely timed electronic pulse that drives the digital devices in the computer. Like turning the crank of a music box, these pulses advance the internal mechanisms of each device through their various stages to perform computations, and to generate signals of their own. The clock signal also synchronizes the devices with each other, so they can communicate with one another over their electronic connections.&lt;/p&gt;
&lt;p&gt;MEGA65 programs can take advantage of three specific devices driven by the system clock to execute code with precise timing: the CPU, the VIC video chip, and the CIA chip.&lt;/p&gt;
&lt;h3 id=&#34;the-cpu&#34;&gt;The CPU&lt;/h3&gt;
&lt;p&gt;The CPU uses the clock signal to perform the machine code instructions of a program. Each instruction requires a certain number of &lt;em&gt;cycles&lt;/em&gt; to perform, where each cycle takes a fixed amount of time based on the clock. For example, the &lt;code&gt;lda #$ff&lt;/code&gt; instruction, which loads the byte value &lt;code&gt;$ff&lt;/code&gt; from the program code into the accumulator register, takes two CPU cycles to complete. The cycle cost of an instruction depends on the instruction and addressing mode, but it&amp;rsquo;s typically between 1 and 6 cycles, and as many as 14 cycles for fancier operations like the 45GS02 Q-register instructions.&lt;/p&gt;
&lt;p&gt;In its default MEGA65 mode, the MEGA65 CPU performs instructions at 40.5 million cycles per second, or 40.5 megahertz (MHz). The MEGA65 can also &lt;em&gt;underclock&lt;/em&gt; its cycle rate to emulate a Commodore 64 (1 MHz), Commodore 128 (2 MHz), or Commodore 65 (3.5 MHz).&lt;/p&gt;
&lt;p&gt;In theory, you can analyze the duration of a section of machine code by looking up the cycle costs of each instruction and adding them together. Commodore 64 programmers sometimes do this to optimize small sections of code, especially for advanced video effects that require precise coordination between the 1 MHz CPU and the VIC video chip. This is less necessary with the MEGA65&amp;rsquo;s 40.5 MHz CPU, which outpaces most of the signal frequencies that a program might care about.&lt;/p&gt;
&lt;p&gt;A program can pause for a period of time by executing instructions and ignoring the results, simply to burn through cycles. This could be a series of instructions in memory, a loop with a counter, or a loop that exits when a hardware register changes. This technique is known as &lt;em&gt;busy-waiting&lt;/em&gt; because the CPU can&amp;rsquo;t stop executing instructions: it has to twiddle its thumbs to keep busy—and also to figure out when to stop waiting and continue the program.&lt;/p&gt;
&lt;p&gt;Try these examples of busy-waiting in BASIC:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5 REM -- PAUSE BRIEFLY BY DOING NOTHING IN A LOOP
10 BORDER 0
20 FOR A=1 TO 20000
30 NEXT A
40 BORDER 1

5 REM -- WAIT FOR JOYSTICK FIRE BUTTON, PORT 1
10 BORDER 0
20 IF (JOY(1) AND 128)=0 THEN 20
30 BORDER 1&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;the-vic&#34;&gt;The VIC&lt;/h3&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/vic6569.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/racing-the-beam/vic6569.jpg 800w, https://dansanderson.com/mega65/racing-the-beam/vic6569_hu_388ad61c585b6e26.jpg 600w, https://dansanderson.com/mega65/racing-the-beam/vic6569_hu_7c22a434f62fa20f.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/racing-the-beam/vic6569.jpg&#34;
        alt=&#34;The VIC 6569 chip. (Image from c64-wiki.com)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The VIC 6569 chip. (Image from c64-wiki.com)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The VIC video chip uses the system clock to generate a video signal with the precise timing expected by the display hardware. Such protocols are derived from old &lt;a href=&#34;https://en.wikipedia.org/wiki/Cathode-ray_tube&#34;&gt;cathode-ray tube (CRT)&lt;/a&gt; displays that draw the entire screen with a beam of electrons. This &lt;em&gt;raster beam&lt;/em&gt; sweeps across the screen in a fixed pattern of horizontal rows, or &lt;em&gt;raster lines&lt;/em&gt;, from left to right, top to bottom. The video signal controls the intensity of the beam, and the beam leaves pixels in its wake that form the complete image. Once it reaches the bottom, the beam returns to the top of the screen, and the process repeats, many times per second.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/raster.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/racing-the-beam/raster.png&#34;
            width=&#34;324&#34;
            height=&#34;231&#34;
            alt=&#34;Path of the raster beam: left to right, top to bottom.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Path of the raster beam: left to right, top to bottom.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 connects to modern &lt;a href=&#34;https://en.wikipedia.org/wiki/Video_Graphics_Array&#34;&gt;VGA analog&lt;/a&gt; or &lt;a href=&#34;https://en.wikipedia.org/wiki/Digital_Visual_Interface&#34;&gt;HDMI digital&lt;/a&gt; displays. Internally, it attempts to recreate the display parameters of one of two vintage analog video modes, either &lt;a href=&#34;https://dansanderson.com/mega65/welcome/concepts.html#pal-and-ntsc&#34;&gt;PAL or NTSC&lt;/a&gt;, so that vintage software that depends on these parameters will run properly. The PAL video mode draws 312 raster lines 50 times per second, also known as a &lt;em&gt;refresh rate&lt;/em&gt; of 50 Hz. NTSC draws 262 lines 60 times per second, or a refresh rate of 60 Hz. A full image consists of two interlaced sets of lines, so the actual image size and &lt;em&gt;frame rate&lt;/em&gt; is twice as many lines and half the frequency: PAL video is 625 lines tall with a frame rate of 25 Hz.&lt;/p&gt;
&lt;p&gt;Synchronizing a program&amp;rsquo;s behavior with the raster beam is a powerful way to perform advanced visual effects. By changing VIC control parameters at specific times during the drawing of the screen, a program can break away from some of the VIC&amp;rsquo;s numerical limitations. This is the basis for one of the most coveted of Commodore graphical techniques, called &lt;em&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Sprite_multiplexing&#34;&gt;sprite multiplexing&lt;/a&gt;,&lt;/em&gt; where the VIC&amp;rsquo;s eight hardware sprites are reused in different parts of a single screen.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/easterbunnydemo3.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/racing-the-beam/easterbunnydemo3.png 674w, https://dansanderson.com/mega65/racing-the-beam/easterbunnydemo3_hu_4628f52f439e2630.png 600w, https://dansanderson.com/mega65/racing-the-beam/easterbunnydemo3_hu_d1cbb40ad205408d.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/racing-the-beam/easterbunnydemo3.png&#34;
        alt=&#34;easterbunnydemo3 by Nobato, from Intro Disk #3, demonstrating sprite multiplexing from BASIC&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
easterbunnydemo3 by Nobato, from Intro Disk #3, demonstrating sprite multiplexing from BASIC.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;the-cias&#34;&gt;The CIAs&lt;/h3&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/cia6526.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/racing-the-beam/cia6526.jpg 525w, https://dansanderson.com/mega65/racing-the-beam/cia6526_hu_484e8cf7c217449e.jpg 600w, https://dansanderson.com/mega65/racing-the-beam/cia6526_hu_c2d19ed061da424d.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/racing-the-beam/cia6526.jpg&#34;
        alt=&#34;The CIA 6526 chip. (Image from c64-wiki.com)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The CIA 6526 chip. (Image from c64-wiki.com)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Complex Interface Adapter (CIA) chip is a multi-purpose chip that manages device and serial communications, and also has a high-precision countdown timer feature. Each CIA chip contains two timers, and the MEGA65 (like the Commodore 64) has two CIA chips, each wired up a bit differently. The CIA counts pulses at a rate of 1 MHz, and your program can set a timer interval up to 65,535 of these pulses, for a delay of up to approximately 0.065 seconds. For example, to set a timer for 1/60th of a second, your program would set the timer value to 16,666.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll save a complete discussion of the CIA chip for another time. For now, suffice it to say that you can use both busy-waiting and interrupt-based techniques with the CIA high-precision timers.&lt;/p&gt;
&lt;h3 id=&#34;other-clocks&#34;&gt;Other clocks&lt;/h3&gt;
&lt;p&gt;There are two other kinds of clock that are worth knowing about, but are less useful for high-precision timing. Each CIA chip contains a time-of-day (TOD) clock that counts tenths of seconds, seconds, minutes, and hours, up to a 24-hour period. In the Commodore 64, this clock powers the &lt;code&gt;TI&lt;/code&gt; and &lt;code&gt;TI$&lt;/code&gt; BASIC variables, and is reset to midnight when the computer is switched off. The MEGA65 contains a separate battery-backed Real-Time Clock (RTC) chip that can remember the time of day and calendar date even when power is disconnected. BASIC 65 uses the RTC chip for the &lt;code&gt;TI$&lt;/code&gt; and &lt;code&gt;DT$&lt;/code&gt; variables, and it uses the CIA TOD clock for the &lt;code&gt;TI&lt;/code&gt; variable.&lt;/p&gt;
&lt;p&gt;Just to complete the picture, here&amp;rsquo;s a simple BASIC program that busy-waits on the &lt;code&gt;TI&lt;/code&gt; special variable for three seconds. Notice that the &lt;code&gt;TI&lt;/code&gt; variable&amp;rsquo;s value changes over time, even though the BASIC program itself isn&amp;rsquo;t changing it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5 REM -- WAIT 3 SECONDS
10 BORDER 0
20 T=TI
30 IF (TI-T)&amp;lt;3 THEN 30
40 BORDER 1&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;finding-the-beam&#34;&gt;Finding the beam&lt;/h2&gt;
&lt;p&gt;The VIC video chip generates a signal for the raster beam to draw onto the display, expecting the raster beam to follow a fixed pattern on a regular interval. The VIC keeps track of where the raster beam is located, and a program can access this information by reading a hardware register.&lt;/p&gt;
&lt;p&gt;One way to synchronize a program&amp;rsquo;s behavior with the VIC&amp;rsquo;s raster beam is to busy-wait on its location. You can do this from BASIC 65, with the &lt;code&gt;VSYNC&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 BORDER 0
20 VSYNC 100
30 BORDER 1
40 VSYNC 200
50 GOTO 10&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;VSYNC&lt;/code&gt; pauses the BASIC program and busy-waits for the raster beam to reach a given vertical position (or &lt;em&gt;raster line&lt;/em&gt;). The vertical position number can be between 0 and 311 in PAL video mode, or 6 and 261 in NTSC mode, where smaller numbers are further up the screen. Try adjusting the numbers on lines 20 and 40 in this example program. (Beware that there&amp;rsquo;s currently &lt;a href=&#34;https://github.com/MEGA65/mega65-core/issues/362&#34;&gt;a bug&lt;/a&gt; that causes &lt;code&gt;VSYNC&lt;/code&gt; to hang with a value less than 6 in NTSC mode.)&lt;/p&gt;
&lt;p&gt;Here is an equivalent program in assembly language. Because the raster beam vertical position can be larger than 255, it takes up more than one byte of space across two register addresses. Bit 7 of register $D011 is high (1) if the raster beam is beyond line 255.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vicii_rcl = $d012
vicii_rch = $d011  ; bit 7
border = $d020

loop:
    lda #0  ; black
    sta border

    lda #100
-   cmp vicii_rcl
    bne -
    bit vicii_rch
    bmi -  ; rch is high, not our stop

    lda #1  ; white
    sta border

    lda #200
-   cmp vicii_rcl
    bne -
    bit vicii_rch
    bmi -  ; rch is high, not our stop

    jmp loop&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;$D011/$D012 are the VIC-II raster position registers. Indeed, this example will work on a Commodore 64 as well as the MEGA65. The MEGA65&amp;rsquo;s VIC-IV is also capable of doubling the vertical resolution of the screen, a mode known as &amp;ldquo;V400,&amp;rdquo; which uses twice as many raster lines. You can see this mode in action by activating the 80x50 text mode: press &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;5&lt;/kbd&gt;. (Press &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;8&lt;/kbd&gt; to return to 80x25 text mode.) In V400 mode, the $D011/$D012 VIC-II registers and the &lt;code&gt;VSYNC&lt;/code&gt; command continue to use the raster position as if it were in the non-doubled mode, so the bottommost VIC-II raster position in PAL video mode is still &amp;ldquo;312,&amp;rdquo; even if V400 is active. If you want the actual mode-specific VIC-IV raster position, an 11-bit value, see the FNRASTERLSB register at $D052 (lower 8 bits) and FNRASTERMSB at $D053.0-2 (upper 3 bits).&lt;/p&gt;
&lt;p&gt;Note that while the raster vertical position corresponds to pixel Y-coordinates, the beam starts well above the top edge of the usual background area inside the colored border—because the raster beam also draws the border! The outermost raster positions are outside of the visible area.&lt;/p&gt;
&lt;h2 id=&#34;visualizing-time&#34;&gt;Visualizing time&lt;/h2&gt;
&lt;p&gt;The ability to synchronize our program with the raster beam gives us a clever way to visualize the duration of a section of program code—using the border color! Try this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 N=30
20 DIM FB(N):FB(0)=0:FB(1)=1

60 FOR I=2 TO N
70 FB(I)=FB(I-2)+FB(I-1)
80 NEXT I&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This program allocates an array of 30 numbers, then fills it with the &lt;a href=&#34;https://en.wikipedia.org/wiki/Fibonacci_sequence&#34;&gt;Fibonacci sequence&lt;/a&gt;. To see this in action, run the program, then type: &lt;code&gt;PRINT FB(5)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We can get a sense of how fast this code runs using a combination of &lt;code&gt;VSYNC&lt;/code&gt; and &lt;code&gt;BORDER&lt;/code&gt;, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 N=30
20 DIM FB(N):FB(0)=0:FB(1)=1

30 BORDER 0
40 VSYNC 100
50 BORDER 1

60 FOR I=2 TO N
70 FB(I)=FB(I-2)+FB(I-1)
80 NEXT I

90 GOTO 30&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Fibonacci code is the same, but now it runs repeatedly in a loop. For each repetition, the program changes the border color to black, synchronizes to raster line 100, changes the border to white, then performs the Fibonacci fill. When control loops back to line 30, the border is changed back to black. In other words, the border is only white for the time it takes to fill the array. The height of the white bars in the border represent how far the raster beam travels during the fill operation. The &lt;code&gt;VSYNC&lt;/code&gt; command makes sure this happens when the raster beam is at the same spot on the screen every time, to hold the white bars steady.&lt;/p&gt;
&lt;p&gt;Try changing &lt;code&gt;N&lt;/code&gt; in line 10 to another number, such as &lt;code&gt;N=5&lt;/code&gt; or &lt;code&gt;N=40&lt;/code&gt;. This changes the size of the array, and therefore changes the amount of time it takes to fill it with Fibonacci numbers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Caution:&lt;/strong&gt; This next step causes the screen to flicker. Change line 10 to &lt;code&gt;N=80&lt;/code&gt;, then run the program. Press &lt;kbd&gt;Run/Stop&lt;/kbd&gt; to stop the flickering.&lt;/p&gt;
&lt;p&gt;Why does the screen flicker when &lt;code&gt;N=80&lt;/code&gt;? Here&amp;rsquo;s what&amp;rsquo;s happening:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The raster beam reaches position 100, the border changes to white, then the Fibonacci algorithm runs while the raster beam travels.&lt;/li&gt;
&lt;li&gt;In the time it takes to calculate 80 Fibonacci numbers, the raster beam reaches the bottom of the screen, returns to the top, then goes just beyond position 100.&lt;/li&gt;
&lt;li&gt;The Fibonacci fill completes, and the program changes the border back to black—but by now the raster beam has made it all the way through the screen and has drawn an entirely white border.&lt;/li&gt;
&lt;li&gt;The program waits for the raster beam to reach 100 again, which requires the raster beam to travel through almost a full screen with the border color set to black. With each screenful alternating between black and white, the border flickers.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Visualizing code duration using the border color is especially helpful when writing games and demos. To animate graphics smoothly, a game must update all of the screen data in less than the time it takes to draw a single screen, so the updated data is ready for the next pass of the raster beam. If the border flickers, it means the computation is taking up more than one screen&amp;rsquo;s worth of raster travel, and the programmer has some work to do.&lt;/p&gt;
&lt;h2 id=&#34;wherefore-interrupts&#34;&gt;Wherefore interrupts?&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/interrupt.gif&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/racing-the-beam/interrupt.gif 342w, https://dansanderson.com/mega65/racing-the-beam/interrupt_hu_c2dc4bcecbe141fb.gif 600w, https://dansanderson.com/mega65/racing-the-beam/interrupt_hu_df82b73ce920f08c.gif 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/racing-the-beam/interrupt.gif&#34;
        alt=&#34;Robert Kelly&amp;amp;#39;s famous 2017 BBC News interview, interrupted by his family&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Interrupted.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A typical machine code program is a sequence of instructions performed one at a time by the CPU in the order the instructions are given. Branching instructions can change the flow of control to other instructions in memory, but otherwise the CPU just marches down the list.&lt;/p&gt;
&lt;p&gt;An &lt;em&gt;interrupt&lt;/em&gt; is an event in a computer that needs immediate attention from the software. The event can come from a peripheral, such as a key press or incoming serial communication, or an internal programmable device that isn&amp;rsquo;t the CPU, such as the VIC or CIA chip. (As a special case, an interrupt event can also be triggered directly by the software with the &lt;code&gt;brk&lt;/code&gt; instruction, but we&amp;rsquo;ll ignore this for now.)&lt;/p&gt;
&lt;p&gt;When an interrupt occurs, the CPU completes the current instruction (however many cycles are remaining), stops executing the program, then calls a software routine called an &lt;em&gt;interrupt handler&lt;/em&gt;. A typical interrupt handler does a small amount of work to respond to the event, then resumes the main program where it left off.&lt;/p&gt;
&lt;p&gt;Interrupts allow a program&amp;rsquo;s code to be organized as if it were two programs: a main program that runs as if it is unaware that special events are occurring, and a short program that runs whenever a special event occurs. Without interrupts, a program would have to be written in such a way as to check for the special condition periodically, in between doing everything else it needs to do. This can delay the program&amp;rsquo;s ability to respond to the event, or even cause it to miss the event entirely.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a quick demonstration in BASIC of what could go wrong in this scenario. The program loop does some &amp;ldquo;work&amp;rdquo; that takes time, in this case an empty loop, but imagine it&amp;rsquo;s doing something important. Once the program has a free moment, it checks to see if the fire button of the joystick in port 1 is pressed; if not, it goes and does some more work. It&amp;rsquo;s pretty difficult to get this program&amp;rsquo;s attention with the fire button. Only by holding the button down will it eventually notice and respond.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 BORDER 0
20 REM -- DO SOME &amp;#34;WORK&amp;#34;
30 FOR A=1 TO 50000
40 NEXT A
50 REM -- CHECK FOR FIRE BUTTON IN JOYSTICK PORT 1
60 IF (JOY(1) AND 128)=0 THEN 30
70 BORDER 1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can imagine a hypothetical computer that triggers an interrupt when the fire button is pressed, halting the &amp;ldquo;work&amp;rdquo; to respond immediately. Because interrupts are built into the hardware, only a few kinds of events are wired into the CPU interrupt system. A typical program would use one of the timing sources (VIC or CIA) to trigger an interrupt at fixed intervals many times a second, and the interrupt handler would check for things like joystick input and react accordingly. This is how the KERNAL moves sprites or plays music concurrently with a BASIC program, or blinks the cursor while waiting for keyboard input at the &lt;code&gt;READY.&lt;/code&gt; prompt. The steady drumbeat of interrupts allows the program (or the KERNAL) to respond to user input quickly, and progress animation and music smoothly.&lt;/p&gt;
&lt;p&gt;Custom interrupt handlers are exclusively the domain of machine code programs. While BASIC programs benefit from how the KERNAL uses interrupts, they can&amp;rsquo;t use interrupts directly. In most cases, the best a BASIC game program can do is keep the game loop logic short and fast, so it can respond to joystick input as soon as possible. So maybe don&amp;rsquo;t loop 50,000 times between checks for the fire button.&lt;/p&gt;
&lt;p&gt;BASIC 65&amp;rsquo;s sprite &lt;code&gt;COLLISION&lt;/code&gt; feature behaves like an interrupt handler, but it&amp;rsquo;s actually implemented by the BASIC interpreter, not the CPU&amp;rsquo;s interrupt system: the interpreter just checks for sprite collisions before executing each BASIC statement.&lt;/p&gt;
&lt;h2 id=&#34;irqs-and-nmis&#34;&gt;IRQs and NMIs&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/racing-the-beam/firealarm.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/racing-the-beam/firealarm.png 600w, https://dansanderson.com/mega65/racing-the-beam/firealarm_hu_685c51924a17f2f4.png 600w, https://dansanderson.com/mega65/racing-the-beam/firealarm_hu_c853296daff7b24b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/racing-the-beam/firealarm.png&#34;
        alt=&#34;Hotel do-not-disturb sign; fire alarm&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
IRQs can be disabled; NMIs can&#39;t.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The 6502 family of CPUs supports two kinds of interrupt: an &lt;em&gt;interrupt request&lt;/em&gt; (IRQ), and a &lt;em&gt;non-maskable interrupt&lt;/em&gt; (NMI). Some events trigger IRQs, and others trigger NMIs.&lt;/p&gt;
&lt;p&gt;The difference between IRQs and NMIs is that certain CPU operations can temporarily disable IRQs, and a program can disable and re-enable IRQs as needed, while NMIs cannot be disabled. Disabling IRQs is like putting a &amp;ldquo;Do Not Disturb&amp;rdquo; sign on a hotel room door: it says that the main program is working on something that should not be interrupted, and interrupt requests should be ignored for the time being. NMIs are more like a hotel fire alarm: they must be handled immediately, no matter what. Both kinds of interrupt are necessary for a fully functioning system, but most programs can get away with only dealing with IRQs.&lt;/p&gt;
&lt;p&gt;The following are possible sources of IRQ interrupts in the C64 and MEGA65:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VIC raster beam location&lt;/li&gt;
&lt;li&gt;VIC sprite collision&lt;/li&gt;
&lt;li&gt;Timers on CIA #1&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;brk&lt;/code&gt; instruction&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following are possible sources of NMI interrupts in the C64 and MEGA65:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Timers on CIA #2&lt;/li&gt;
&lt;li&gt;RS-232 serial communication&lt;/li&gt;
&lt;li&gt;Pressing the &lt;kbd&gt;Restore&lt;/kbd&gt; key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Yes, pressing the &lt;kbd&gt;Restore&lt;/kbd&gt; key triggers the NMI handler! This is how &lt;kbd&gt;Run/Stop&lt;/kbd&gt; + &lt;kbd&gt;Restore&lt;/kbd&gt; works: the KERNAL&amp;rsquo;s NMI handler tests whether both keys are pressed, then resets BASIC and declines to continue the interrupted program. This works even if the program has disabled IRQs.&lt;/p&gt;
&lt;p&gt;The CPU supports one interrupt handler for IRQs and one handler for NMIs. It&amp;rsquo;s up to the handler code to figure out the specific cause of the interrupt, and react appropriately.&lt;/p&gt;
&lt;p&gt;The address of each interrupt handler is stored as two bytes, in little-endian order (low byte first), at a fixed 16-bit address: the IRQ handler address is stored at $FFFE-$FFFF, and the NMI handler address is stored at $FFFA-$FFFB. The MEGA65&amp;rsquo;s default memory map installs KERNAL ROM code in this location, and the KERNAL uses its own interrupt handlers, so you can&amp;rsquo;t just &lt;code&gt;POKE&lt;/code&gt; new addresses here. One way that a program can install custom interrupt handlers is to uninstall the KERNAL, by changing the memory map.&lt;/p&gt;
&lt;p&gt;It is possible to leave the KERNAL in place and ask it to call custom code during its own IRQ handler. We&amp;rsquo;re still formalizing and documenting KERNAL integration techniques, so this is best left alone for now when writing MEGA65 programs. This is probably the most popular KERNAL integration technique on the C64, so we&amp;rsquo;ll try to finish this soon. (Hint: use the &amp;ldquo;VECTOR&amp;rdquo; KERNAL routine.)&lt;/p&gt;
&lt;p&gt;For the rest of this Digest, we&amp;rsquo;ll focus on the raster beam IRQ, and assume that the program will uninstall the KERNAL to install its own handler. We&amp;rsquo;ll save other interrupt types for another time.&lt;/p&gt;
&lt;h2 id=&#34;interrupt-handlers&#34;&gt;Interrupt handlers&lt;/h2&gt;
&lt;p&gt;When the CPU encounters an IRQ, it finishes the current instruction, then pushes the 16-bit address of the next instruction onto the stack (two bytes). It also pushes the CPU flags onto the stack, as a single byte. It then disables IRQs, then jumps to the address stored in the IRQ vector.&lt;/p&gt;
&lt;p&gt;The first thing the interrupt handler needs to do is preserve any additional CPU state that might get clobbered by the rest of the handler. The main program expects everything about the CPU to be just as it left it, including the values in other registers. For example, if the handler needs to use the accumulator (and it probably does), it needs to push the previous accumulator value to the stack beforehand, and restore it afterward.&lt;/p&gt;
&lt;p&gt;For most kinds of IRQ interrupt, the device that triggers the interrupt stays in the &amp;ldquo;interrupt&amp;rdquo; state until it is told that the interrupt is handled. The program must interact with the device via a hardware register to &lt;em&gt;acknowledge&lt;/em&gt; the interrupt, so that it doesn&amp;rsquo;t re-trigger once the interrupt handler resumes the program. Remember that an IRQ can have multiple causes, so if your program enables more than one cause, it will need to determine the cause and handle it appropriately.&lt;/p&gt;
&lt;p&gt;When the interrupt handler is complete, it calls the &lt;code&gt;rti&lt;/code&gt; instruction to resume the paused program. This restores the CPU flags and next code address from the stack (thereby re-enabling interrupts), and continues where it left off. This is kind of like how &lt;code&gt;jsr&lt;/code&gt; jumps to a subroutine and &lt;code&gt;rts&lt;/code&gt; returns from it, with minor differences. For example, normal subroutines don&amp;rsquo;t stash and restore the CPU flags.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;irq_handler:
    ; Preserve the Accumulator, X, Y, and Z registers
    ; on the stack.
    pha
    phx
    phy
    phz

    ; Test for and acknowledge the IRQ cause...
    
    ; Do something fun...

    ; Restore the CPU registers, pulling them off the
    ; stack in the reverse order they were pushed.
    plz
    ply
    plx
    pla

    ; Resume the program
    rti&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;enabling-and-disabling-irqs&#34;&gt;Enabling and disabling IRQs&lt;/h2&gt;
&lt;p&gt;The CPU keeps track of whether IRQs should be handled or ignored using the &amp;ldquo;IRQs disabled&amp;rdquo; CPU status flag (&lt;code&gt;I&lt;/code&gt;). To disable IRQs, a program calls the &lt;code&gt;sei&lt;/code&gt; instruction (&amp;ldquo;set IRQ disabled&amp;rdquo;). To re-enable IRQs, a program calls the &lt;code&gt;cli&lt;/code&gt; instruction (&amp;ldquo;clear IRQ disabled&amp;rdquo;). I know, this set/clear definition feels like a double-negative; just think of how interrupts being enabled is the default case (0 or clear), and being disabled is the special case (1 or set).&lt;/p&gt;
&lt;p&gt;The CPU will automatically disable IRQs when calling either the IRQ or NMI interrupt handler, so an IRQ handler can&amp;rsquo;t re-trigger while it is executing, nor can a handler be interrupted by something else. Interrupts get re-enabled automatically when the &lt;code&gt;rti&lt;/code&gt; instruction restores the previous status flags from the stack. It&amp;rsquo;s possible to get fancy with this, and some advanced techniques make unusual exits from the interrupt handler or manipulate the stack.&lt;/p&gt;
&lt;p&gt;Interrupts are also disabled automatically while updating the 45GS02 memory map registers. This is important because memory map adjustments require several instructions, and interrupting these instructions could be disastrous if the incomplete memory map leaves either the interrupt handler code or handler vectors in an inconsistent state.&lt;/p&gt;
&lt;p&gt;This is an important hint for how a program and its interrupt handlers can communicate with each other. If the main program is updating the state of the system, and it&amp;rsquo;d be bad if the interrupt handler sees the state only partially updated, the main program should disable interrupts (&lt;code&gt;sei&lt;/code&gt;), update the state, then re-enable interrupts (&lt;code&gt;cli&lt;/code&gt;). Remember: with interrupts enabled, the handler could be called between any two instructions, including between an &lt;code&gt;lda&lt;/code&gt; and an &lt;code&gt;sta&lt;/code&gt;. Modern-day programmers might compare disabling interrupts to a &amp;ldquo;global lock&amp;rdquo; on memory and CPU state, albeit a simple one.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-hardware-interrupt-handlers&#34;&gt;Setting up hardware interrupt handlers&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s try disabling the KERNAL and setting up our own interrupt handler. This requires a few steps.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re not going to cover memory mapping in detail in this issue. To learn more about it, download the latest version of &lt;a href=&#34;https://files.mega65.org/?id=d668168c-1fef-4560-a530-77e9e237536d&#34;&gt;The MEGA65 Compendium&lt;/a&gt; and check out the &amp;ldquo;Memory&amp;rdquo; chapter. For now, we just need to know a few things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The MEGA65 has an &lt;em&gt;address space&lt;/em&gt; of 28 bits, with addresses numbered from $000.0000 to $FFF.FFFF. Some of these addresses go to memory, some go to hardware registers, and some are unassigned.&lt;/li&gt;
&lt;li&gt;The CPU sees 64KB of the MEGA65&amp;rsquo;s memory at a time, using 16-bit addresses numbered from $0000 to $FFFF.&lt;/li&gt;
&lt;li&gt;The CPU maintains a &lt;em&gt;memory map&lt;/em&gt; that assigns 8KB chunks of the 16-bit address space to the 28-bit address space. A program can adjust this memory map using CPU instructions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The MEGA65 KERNAL ROM code lives in the 28-bit address space from $2.0000 to $3.FFFF. While the KERNAL is running, it switches between a few memory maps to do various things. Most importantly, when interrupts are enabled, the 28-bit addresses $3.E000 to $3.FFFF are mapped to 16-bit addresses $E000 to $FFFF, which includes the IRQ and NMI vectors as well as the handler routines that they point to.&lt;/p&gt;
&lt;p&gt;To take this over for our own purposes, we need to reset the memory map so that $E000 to $FFFF points to RAM at $0.E000 to $0.FFFF. The memory map consists of eight bytes of information. Without going into detail, we can accomplish our task by setting four of these bytes to zero. To do this, set the A, X, Y, and Z registers to zero, then use the &lt;code&gt;map&lt;/code&gt; instruction, followed by the &lt;code&gt;eom&lt;/code&gt; (&amp;ldquo;End Of Map&amp;rdquo;) instruction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    lda #0
    tax
    tay
    taz
    map  ; Disable IRQs and update the MAP register
    
    eom  ; End MAP adjustments, re-enable IRQs&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;map&lt;/code&gt; instruction transfers A, X, Y, and Z to the first four bytes of the MAP register. Simultaneously, the &lt;code&gt;map&lt;/code&gt; instruction also disables IRQs (similar to &lt;code&gt;sei&lt;/code&gt;). After the first &lt;code&gt;map&lt;/code&gt; and before the &lt;code&gt;eom&lt;/code&gt;, the program can call &lt;code&gt;map&lt;/code&gt; a second time to set the second four bytes of the MAP register if needed, or otherwise set up any additional state needed by IRQ handlers in the new memory map. The &lt;code&gt;eom&lt;/code&gt; instruction signifies that the MAP setting is complete, and re-enables IRQs.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;eom&lt;/code&gt; instructions are specific to the 65CE02 CPU on which the 45GS02 is based, so you&amp;rsquo;ll want to use an assembler that supports them, like &lt;a href=&#34;https://sourceforge.net/projects/acme-crossass/&#34;&gt;Acme assembler&lt;/a&gt;. If your assembler of choice only supports CPUs up to the 65C02, you can use the &lt;code&gt;aug&lt;/code&gt; instruction for &lt;code&gt;map&lt;/code&gt;, and &lt;code&gt;nop&lt;/code&gt; for &lt;code&gt;eom&lt;/code&gt;. If your assembler only supports 6502 instructions, get a better assembler.&lt;/p&gt;
&lt;p&gt;The KERNAL keeps the VIC raster interrupt active for its own purposes, so we need to either disable this or set it up the way we want. In general, it&amp;rsquo;s a best practice to disable all sources of interrupt that your program doesn&amp;rsquo;t recognize when installing custom interrupt handlers.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s use the gap between &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;eom&lt;/code&gt; to install our own interrupt handlers, and disable the KERNAL&amp;rsquo;s raster interrupt. Even though we&amp;rsquo;re not discussing NMIs for now, we need an NMI handler because we&amp;rsquo;re replacing all of the KERNAL&amp;rsquo;s handlers. (We&amp;rsquo;ll look at a more thorough way to do this another time.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hw_nmi_vec = $fffa
hw_irq_vec = $fffe
vicii_irqmask = $d01a
ciaa_d = $dc0d
ciab_d = $dd0d

    lda #0
    tax
    tay
    taz
    map  ; (disables interrupts)
    
    ; Set the NMI handler vector
    lda #&amp;lt;nmi_handler
    sta hw_nmi_vec
    lda #&amp;gt;nmi_handler
    sta hw_nmi_vec+1
    
    ; Set IRQ handler vector
    lda #&amp;lt;irq_handler
    sta hw_irq_vec
    lda #&amp;gt;irq_handler
    sta hw_irq_vec+1
    
    ; Disable all VIC IRQs
    lda #0
    sta vicii_irqmask

    ; Disable all CIA IRQs, and acknowledge any pending timers
    lda #$7f
    sta ciaa_d
    sta ciab_d
    lda ciaa_d
    lda ciab_d

    ; Set up the interrupts we care about...
    
    eom  ; (re-enables interrupts)

    ; Main program...
-   bra -  ; (Just an empty busy-loop for now.)

irq_handler:
    pha

    ; Test for and acknowledge the IRQ cause...

    ; Do something fun...

    pla
    rti

nmi_handler:
    rti&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;raster-interrupts&#34;&gt;Raster interrupts&lt;/h2&gt;
&lt;p&gt;The VIC chip can trigger an IRQ when the raster beam is at a requested position. Setting this up requires two simple steps.&lt;/p&gt;
&lt;p&gt;First, the program must tell the VIC what raster position to use. As with the BASIC 65 &lt;code&gt;VSYNC&lt;/code&gt; command, the range of this value depends on the video mode: 0 to 311 for PAL, and 6 to 261 for NTSC. The program sets the desired location with the lower eight bits in register $D012, and the ninth bit as bit 7 of register $D011.&lt;/p&gt;
&lt;p&gt;Astute readers may notice that this is the same register we used to read the raster position for busy-waiting! The VIC is clever enough to re-use this register location in this way: when you read the register, it returns the current raster position. When you write to the register, you set the raster interrupt position.&lt;/p&gt;
&lt;p&gt;The second step is to set a flag that says the program wants the VIC to trigger the raster IRQ. Set bit 0 of register $d01a to 1 to enable the raster IRQ.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vicii_rcl = $d012
vicii_rch = $d011  ; bit 7
vicii_irqmask = $d01a

    ; Enable raster interrupt at position 200
    lda #200
    sta vicii_rcl
    lda vicii_rch  ; clear bit 7 of $d011
    and #$7f
    sta vicii_rch
    lda #$01
    sta vicii_irqmask&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Within the IRQ handler, you can confirm that it was the raster IRQ that triggered the interrupt by testing bit 0 of register $D019. To acknowledge the interrupt and prevent the IRQ handler from re-triggering, write a 1 to this bit. This is another register that has unusual read and write behavior: reading it tests the IRQ trigger status, and writing a 1 to a bit &amp;ldquo;unlatches&amp;rdquo; the trigger.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vicii_irq = $d019

irq_handler:
    pha

    ; Test for raster IRQ
    lda vicii_irq
    bit #$01
    beq +  ; not raster IRQ

    ; Acknowledge raster IRQ
    lda #$01  ; write a 1 to bit 0
    sta vicii_irq

    ; Do something fun...

+   pla
    rti&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I promised to limit this discussion to raster interrupts, but it won&amp;rsquo;t take more than two sentences to discuss the VIC-II&amp;rsquo;s other interrupt capabilities. The VIC can also trigger an IRQ when a sprite collides with the background, or with another sprite. To use these, simply use bits 1 and 2, respectively, of the $d019 and $d01a registers. Oh, and the VIC also uses an IRQ for managing input from a &lt;a href=&#34;https://www.c64-wiki.com/wiki/Light_pen&#34;&gt;light pen&lt;/a&gt;, but I don&amp;rsquo;t have one of those so I can&amp;rsquo;t tell you anything about it.&lt;/p&gt;
&lt;p&gt;As mentioned earlier, the VIC-IV uses twice as many raster lines in V400 mode as otherwise, but maintains the non-doubled raster line count in the $D011/$D012 registers. The raster vertical position IRQ uses the same value range, regardless of the V400 mode. There is not currently a way to set a more precise raster IRQ in V400 mode.&lt;/p&gt;
&lt;h2 id=&#34;racing-the-beam&#34;&gt;Racing the beam&lt;/h2&gt;
&lt;p&gt;In the time that it takes the raster beam to draw a single line, a 1 MHz Commodore 64 can execute about 64 cycles worth of instructions. (Check my math: PAL draws 312 lines 50 times per second; the C64 executes 1 million CPU cycles per second; 1,000,000 / (312 x 50) = 64.1. NTSC draws 262 lines 60 times per second; 1,000,000 / (262 x 60) = 63.6.) Just eyeballing the IRQ handler I wrote above, which doesn&amp;rsquo;t even do anything useful, it looks like I&amp;rsquo;ve already spent 26 cycles. A typical C64 interrupt handler will not complete until the raster beam is on the next line.&lt;/p&gt;
&lt;p&gt;With high-speed C64 graphics programming, if each CPU cycle represents 1/64th of a line, every cycle matters, and getting the code to synchronize with the raster beam position can be challenging. Remember how I said that when the CPU receives the interrupt request from the VIC, it finishes the current instruction before calling the handler? The current instruction could have several cycles remaining, and the raster beam will have advanced across the screen for some distance before the handler is called. Moreover, the interrupt could be happening at any time during any instruction, so the runoff is likely to vary every time. On a C64, a simple raster IRQ handler that changes the background color results in a flickering fringe at the transition point. C64 programmers can use &lt;a href=&#34;https://codebase64.org/doku.php?id=base:interrupts&#34;&gt;complex techniques&lt;/a&gt; to synchronize the CPU with the raster beam, typically by setting a raster interrupt just before the line that is needed, then performing tests and busy-waiting for very specific amounts of time to account for minute differences between C64 models and other conditions.&lt;/p&gt;
&lt;p&gt;The MEGA65 doesn&amp;rsquo;t have that problem. At 40.5 MHz, the MEGA65 executes approximately 2,600 cycles per raster line, or less than a pixel per CPU instruction. In most cases, the small amount of cycle slop just before the interrupt handler is called won&amp;rsquo;t impact a program. A bit of fringing can still appear if you&amp;rsquo;re changing the border color, because the border is so close to the beginning of the raster line. In this case, just be sure to change the border color as early as possible in the handler routine.&lt;/p&gt;
&lt;p&gt;Also note that if the interrupt handler exits before the beam has left the line that caused the IRQ to trigger, the VIC won&amp;rsquo;t re-trigger the IRQ for the same line. The VIC only triggers a vertical raster interrupt at the beginning (left-most position) of the line.&lt;/p&gt;
&lt;h2 id=&#34;raster-chaining&#34;&gt;Raster chaining&lt;/h2&gt;
&lt;p&gt;If you want the raster IRQ to trigger once per frame in the same location, you can just leave the IRQ mask bit set, and leave the raster location registers alone. This is handy for simple game loops that stay in sync with the screen refresh.&lt;/p&gt;
&lt;p&gt;Earlier, we were discussing special effects like multi-color borders and sprite multiplexing that involve changing VIC parameters at multiple raster positions. To do this with interrupts, you set the next raster position within the interrupt handler. After the handler returns, the VIC is ready to trigger it again at the new position. Of course, this means that your handler must test which position triggered the interrupt. It can do so by reading the raster position, as before.&lt;/p&gt;
&lt;p&gt;Another option is for the interrupt handler to also update the IRQ handler vector address to point to a different routine to be called for the next raster interrupt. This avoids having to test the raster position. As long as all of the raster handlers correctly advance the raster interrupt position and handler address, you can set up distinct handlers for each raster position.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example of using the first technique to draw the white border bar from 100 to 200:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vicii_border = $d020

irq_handler:
    pha

    ; Test for raster IRQ
    lda vicii_irq
    bit #$01
    beq +  ; not raster IRQ

    ; Acknowledge raster IRQ
    lda #$01  ; write a 1 to bit 0
    sta vicii_irq

    ; White border bar from 100 to 200
    lda vicii_rcl
    cmp #101
    bcs ++

    ; This is the raster interrupt for line 100.
    ; Set the raster interrupt position to 200.
    lda #200
    sta vicii_rcl
    lda #1  ; white
    sta vicii_border
    bra +

    ; This is the raster interrupt for line 200.
    ; Set the raster interrupt position to 100.
++  lda #100
    sta vicii_rcl
    lda #0  ; black
    sta vicii_border

+   pla
    rti&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;the-vic-iv-raster-x-position&#34;&gt;The VIC-IV raster X position&lt;/h2&gt;
&lt;p&gt;The traditional VIC-II raster position register and corresponding IRQ trigger are based on the vertical position of the beam, how far up or down the beam is. If you&amp;rsquo;re careful to consider the video mode, you can think of this as a raster Y coordinate, in correspondence with the VIC screen coordinates.&lt;/p&gt;
&lt;p&gt;The MEGA65&amp;rsquo;s VIC-IV has an extra trick up its sleeve: it also reports and can trigger the IRQ on the raster horizontal position, as a raster X coordinate. This works similarly to the VIC-II vertical position: you can read the X position from a register, write an X position to this register to set the IRQ trigger, and enable and acknowledge the IRQ by setting bits in other registers.&lt;/p&gt;
&lt;p&gt;To protect backwards compatibility, this IRQ is behind a master switch for all MEGA65-specific IRQ triggers that is off by default. To unlock new MEGA65 IRQs (currently just this one), set $D07A bit 6. The X position is a 13-bit value, readable at $D050 (lower eight bits) and $D051.0-5 (upper five bits). You write the IRQ trigger position to the same register. To enable the raster X IRQ, set bit 4 of $D01A. To acknowledge the raster X IRQ in the request handler, write a 1 to bit 4 of $D019.&lt;/p&gt;
&lt;p&gt;This IRQ will trigger whenever the raster beam reaches the requested horizontal position, once for every raster line when this is enabled. To target a specific raster X-Y coordinate, leave the horizontal IRQ disabled, trigger a vertical IRQ for the Y coordinate, then in that handler, enable the horizontal IRQ for the X coordinate and return. The next interrupt will be at the requested position on the line. Remember that the beam travels while the handler is executing, so keep it tight.&lt;/p&gt;
&lt;h2 id=&#34;playing-sid-music&#34;&gt;Playing SID music&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s end with a musical experiment!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;SID files&lt;/em&gt; are the Commodore community&amp;rsquo;s method of creating and preserving music designed to be played by a Commodore 64 through its SID sound chip. Perhaps surprisingly, a typical SID file isn&amp;rsquo;t just data about the musical notes to be played, like a piano roll for a player piano. Instead, it contains 6502 machine code—the player mechanism itself! (I guess the SID is the piano? You get it.)&lt;/p&gt;
&lt;p&gt;The playback code consists of two subroutines. One subroutine initializes the SID chip, and is expected to be called once before starting the song. The other subroutine plays the actual music, and is expected to be called many times per second, with precise timing. This makes it easy for a game or demo to play the SID file simply by loading it into memory, calling the initialization routine, then calling the playback subroutine from an interrupt handler. The music plays concurrently with whatever else the program does.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.commodore.software/reference-material/articles-and-guides/commodore-64-articles/sid-file-format-info.pdf&#34;&gt;The complete SID file specification&lt;/a&gt; has matured over multiple generations to cover many interesting cases. For our simple experiment, we can note just a few things: the file header tells us where in memory to load the file, and also provides the addresses of the initialization routine and the playback routine in memory when loaded appropriately. SID files expect a C64 memory map, so getting arbitrary SIDs to play on the MEGA65 can be tricky. (When you play a SID via &lt;a href=&#34;https://dansanderson.com/mega65/welcome/transferring-files.html#m65connect&#34;&gt;M65Connect&lt;/a&gt;—did you know you can play SIDs via M65Connect?—it uploads a tiny player routine that runs in GO64 mode, which gets around this issue.)&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an easy one to try that works with the MEGA65 memory map:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download &lt;a href=&#34;Frogger.sid&#34;&gt;Frogger.sid&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Download &lt;a href=&#34;FROGGERSID.d81&#34;&gt;FROGGERSID.d81&lt;/a&gt; (contains &lt;code&gt;frogger.sid&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If we open &lt;code&gt;Frogger.sid&lt;/code&gt; in a hex editor and compare it to the SID file format spec, we can see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s a PSID file (not an RSID), version 2.&lt;/li&gt;
&lt;li&gt;The data region starts at offset $7C in this file.&lt;/li&gt;
&lt;li&gt;The load address is in the first two bytes of the data region, and not the header. This address is $5000.&lt;/li&gt;
&lt;li&gt;The initialization routine starts at $5000.&lt;/li&gt;
&lt;li&gt;The play routine starts at $59F0.&lt;/li&gt;
&lt;li&gt;The play routine expects to be called 60 times per second.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It seems like we should be able to load this file starting at address $5000 - $7C = $4F84, then call the subroutines at $5000 and $59F0 appropriately. Let&amp;rsquo;s forget about interrupts for a second and try this in BASIC!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 BLOAD &amp;#34;FROGGER.SID&amp;#34;,P($4F84)
20 SYS $5000
30 BORDER 0
40 VSYNC 100
50 BORDER 1
60 SYS $59F0
70 GOTO 30&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This program loads the SID file such that the data region starts at $5000, calls the initialization routine, then runs the main loop in lines 30-70. The loop uses &lt;code&gt;VSYNC&lt;/code&gt; in two ways: it makes sure that we&amp;rsquo;re calling the play routine as often as the screen updates, and it uses the border timing trick to see how long the playback routine takes to execute. If you want to use this tune in a BASIC game, the white bar tells you how much runtime is available for game logic and graphics.&lt;/p&gt;
&lt;p&gt;Maybe this tune sounds familiar! And if you&amp;rsquo;re in PAL mode, maybe it sounds a bit too slow. If your display supports it, open the Freezer (hold &lt;kbd&gt;Restore&lt;/kbd&gt; for one second then release), press &lt;kbd&gt;V&lt;/kbd&gt; to switch video modes, then press &lt;kbd&gt;F3&lt;/kbd&gt;, then re-run the program to hear the difference. The song plays as originally intended in the NTSC video mode, which updates the screen 60 times per second, and slower in the PAL video mode, at 50 times per second.&lt;/p&gt;
&lt;p&gt;Music playing at the wrong speed is very familiar to Commodore enthusiasts sharing game software between the USA and Europe, where the two different video standards were used. Many C64 games use the raster interrupt for every aspect of their game loop including music playback, because it&amp;rsquo;s much more convenient to use a single interrupt for all timing purposes than to try to accommodate different intervals for graphics and music. One fix for this would be to use both a raster IRQ (50 Hz or 60 Hz, depending on video mode) and a CIA timer IRQ (set to 60 Hz), and write the interrupt handler to detect which device triggered the IRQ and perform either graphics or sound updates accordingly.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like to try playing this SID file from assembly language, I recommend using the feature of your assembler to include &lt;code&gt;frogger.sid&lt;/code&gt; as binary data into your program, then have the program start by copying the data into the correct memory location. Everything else should look similar to the interrupt handling code from earlier. In a later Digest, we&amp;rsquo;ll revisit the subject of interrupts, and look at how to use the CIA chip to play music correctly in either video mode.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;By this time next month, new MEGA65s may be on their way to their new homes! Huge thanks to everyone who has been reading this Digest in anticipation of future ownership. The new &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/21331992/Documentation+-+Landing+Page&#34;&gt;User&amp;rsquo;s Guide&lt;/a&gt; contains everything you need to get started, and don&amp;rsquo;t miss &lt;a href=&#34;https://dansanderson.com/mega65/welcome/intro.html&#34;&gt;my MEGA65 Welcome Guide&lt;/a&gt; with photos and additional tips. &lt;a href=&#34;https://discord.gg/5DNvESf&#34;&gt;Join the Discord&lt;/a&gt; and let us know it arrived safely, and don&amp;rsquo;t forget to &lt;a href=&#34;https://files.mega65.org?ar=1a47ec2c-1b56-4bd9-8d89-5b12ab8b72ae&#34;&gt;register for ownership status&lt;/a&gt; in both the Discord and on Filehost.&lt;/p&gt;
&lt;p&gt;Everything I do for the MEGA65 project, including this Digest, is made possible by supporters like you! If you&amp;rsquo;d like to support the Digest, visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Happy computing!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/racing-the-beam/M65Digest_2024May.mp3" length="54251540" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>2712</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/racing-the-beam/16MHZ_Crystal.jpg"/>
      
    </item>
    
    <item>
      <title>Oh right, April!</title>
      <link>https://dansanderson.com/mega65/oh-right-april/</link>
      <pubDate>Wed, 01 May 2024 14:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/oh-right-april/</guid>
      <description>&lt;p&gt;Oh right, April! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for, uh, April 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Oh right, April! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for, uh, April 2024.&lt;/p&gt;
&lt;p&gt;Heyhey, all! I hope everyone is doing well.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been dealing with a family thing (not tragic, just time consuming) and haven&amp;rsquo;t been able to finish the feature article I planned for the April issue of the MEGA65 Digest. So instead, I&amp;rsquo;m going to push that article to the next issue, and just drop you a quick note. I&amp;rsquo;m also going to skip the audio issue for this month. (The audio issue for March was enough for two. 😅)&lt;/p&gt;
&lt;p&gt;There has been a quiet burble of activity in the MEGA65 community as we all await the next delivery batch, including some promising incremental improvements to the audio system, and bug fixes for advanced graphics features. Only a couple of projects have proper announcements, but they&amp;rsquo;re fun and I don&amp;rsquo;t want to delay them!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;pascal65&#34;&gt;Pascal65&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/oh-right-april/pascal65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/oh-right-april/pascal65.png 701w, https://dansanderson.com/mega65/oh-right-april/pascal65_hu_55a91c90912a9c71.png 600w, https://dansanderson.com/mega65/oh-right-april/pascal65_hu_6306dcdbcc60a6e2.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/oh-right-april/pascal65.png&#34;
        alt=&#34;Pascal65, by TwoBitRetro&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Pascal65, by TwoBitRetro&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 speaks a new language! TwoBitRetro has just launched the first public beta of &lt;a href=&#34;https://pascal65.org/&#34;&gt;Pascal65&lt;/a&gt;, a compiler and IDE of the Pascal programming language. The MEGA65 is just the first target. Ken says he intends to support other Commodore 8-bits in the future, as well as the Commander X16. The project is &lt;a href=&#34;https://github.com/kenschenke/Pascal65&#34;&gt;open source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kenschenke/Pascal65/releases&#34;&gt;Download the beta&lt;/a&gt;, check out &lt;a href=&#34;https://pascal65.org/blog/pascal65-first-beta-release&#34;&gt;the beta release notes&lt;/a&gt; and the &lt;a href=&#34;https://pascal65.org/blog/pascal65-0-25-beta&#34;&gt;0.25 update notes&lt;/a&gt;, read &lt;a href=&#34;https://docs.pascal65.org/en/latest/&#34;&gt;the documentation&lt;/a&gt;, and &lt;a href=&#34;https://pascal65.org/blog&#34;&gt;follow the dev blog for updates&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;program hello;

var name: string;

begin
  write(&amp;#39;What is your name? &amp;#39;);
  readln(name);
  writeln(&amp;#39;Hi, &amp;#39;, name, &amp;#39; nice to meet you!&amp;#39;);
end.&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;mega65h-for-llvm-mos&#34;&gt;mega65.h for llvm-mos&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/oh-right-april/plasma.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/oh-right-april/plasma.png 659w, https://dansanderson.com/mega65/oh-right-april/plasma_hu_c0c2492f61c87a37.png 600w, https://dansanderson.com/mega65/oh-right-april/plasma_hu_6eea8b776c7794c9.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/oh-right-april/plasma.png&#34;
        alt=&#34;The MEGA65 plasma demo from the llvm-mos SDK&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The MEGA65 plasma demo from the llvm-mos SDK.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/llvm-mos/llvm-mos-sdk/tree/main&#34;&gt;llvm-mos SDK&lt;/a&gt;, the LLVM backend for 6502-family microcomputers capable of compiling languages like C and C++, now includes &lt;a href=&#34;https://github.com/llvm-mos/llvm-mos-sdk/tree/main/mos-platform/mega65&#34;&gt;header files for using MEGA65 features&lt;/a&gt;. This provides a common way to use the VIC-IV, SID, CIA, hardware math, and the Hypervisor from C and C++ programs. Check out &lt;a href=&#34;https://github.com/llvm-mos/llvm-mos-sdk/blob/main/examples/mega65/plasma.cc&#34;&gt;this example visual demo in C++&lt;/a&gt;. These headers are also usable with the CC65 and Calypsi compilers.&lt;/p&gt;
&lt;p&gt;Many thanks to wombat for his continued development and advocacy work bringing MEGA65 support to the llvm-mos project!&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;tell-me-what-you-think&#34;&gt;Tell me what you think!&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;mailto:contact@dansanderson.com&#34;&gt;I want to hear from you!&lt;/a&gt; If you&amp;rsquo;re waiting for your MEGA65 to ship, what are you most looking forward to learning more about? If you&amp;rsquo;re already enjoying your MEGA65, what topics could the Digest cover that would make your experience more rewarding? If you&amp;rsquo;re still considering a purchase, what interests you about retro computing, and how are you hoping the MEGA65 or this Digest will scratch that itch?&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&#34;mailto:contact@dansanderson.com&#34;&gt;send me e-mail&lt;/a&gt;, or &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;leave a comment on my Ko-fi page&lt;/a&gt;. I&amp;rsquo;m considering doing the &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023-results/&#34;&gt;Community Survey&lt;/a&gt; again this year, too, so keep an eye out for that.&lt;/p&gt;
&lt;p&gt;Thanks all! Back soon!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>The Justified Ancients of Mu Mu</title>
      <link>https://dansanderson.com/mega65/justified-ancients/</link>
      <pubDate>Thu, 14 Mar 2024 21:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/justified-ancients/</guid>
      <description>&lt;p&gt;The Justified Ancients of Mu Mu. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for March 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;The Justified Ancients of Mu Mu. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for March 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/justified-ancients/M65Digest_2024Mar.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/M65Digest_2024Mar.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
The Justified Ancients of Mu Mu.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/klf.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/klf.png 866w, https://dansanderson.com/mega65/justified-ancients/klf_hu_324382529b58b98.png 600w, https://dansanderson.com/mega65/justified-ancients/klf_hu_ba3330318d423e02.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/klf.png&#34;
        alt=&#34;A still from The KLF, 3AM Eternal (Live at the S.S.L.) (1991)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The KLF, 3AM Eternal (Live at the S.S.L.) (1991)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;[Did you know: All issues of the Digest have an audio version! Search for “&lt;a href=&#34;https://podcasts.apple.com/us/podcast/dans-mega65-digest-podcast/id1656654132&#34;&gt;Dan’s MEGA65 Digest&lt;/a&gt;” in your favorite podcast app, or check out the audio player at the top of each issue. — Dan]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There are two methods for making sound and music with the MEGA65, as it is currently implemented. The first method is the four SID chips, programmable devices that generate waveforms with requested parameters using analog electronic components. We took a dive into the SID chips back in—&lt;em&gt;&lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/&#34;&gt;November 2022&lt;/a&gt;??&lt;/em&gt; How long have I been doing this?? &amp;hellip;&lt;/p&gt;
&lt;p&gt;The MEGA65 can produce sound another way. &lt;a href=&#34;https://en.wikipedia.org/wiki/Pulse-code_modulation&#34;&gt;Pulse-Code Modulation&lt;/a&gt; (PCM) describes a waveform as a sequence of values over time, literally the shape of the desired waveform as a series of high and low numbers, as if drawn on a graph. The computer feeds these numbers into a device called a Digital-Analog Converter (DAC) that produces the waveform in that shape, as if rapidly changing the position of a speaker membrane according to each value. The MEGA65 has four DACs, and these waveforms are mixed with the rest of the audio system to produce the stereo audio output of the computer.&lt;/p&gt;
&lt;p&gt;With PCM, a computer can reproduce real-world sounds captured by a microphone, such as human speech or musical instruments. Today, we take this extremely for granted: modern computers generate pretty much all sound using PCM waveforms. We used to call this &amp;ldquo;digitized sound,&amp;rdquo; in contrast with &amp;ldquo;synthesized sound.&amp;rdquo; Now we just call it &amp;ldquo;sound.&amp;rdquo; While PCM gives a computer program much more control over the generated sound, the trade-off is memory: relative to the memory sizes of 1980&amp;rsquo;s computers, PCM sound data takes a huge amount of space, depending on the length and quality of the sounds.&lt;/p&gt;
&lt;p&gt;In this issue, we&amp;rsquo;ll look at how to control the MEGA65&amp;rsquo;s DACs to play digitized sound, as well as techniques for wrangling sound data for use in your programs. As usual, we&amp;rsquo;ll spend a bit too much time nerding out on theory and file formats.&lt;/p&gt;
&lt;p&gt;Are you ready? Here we go.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/bombemall.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/bombemall.png 705w, https://dansanderson.com/mega65/justified-ancients/bombemall_hu_a8502e31f2225690.png 600w, https://dansanderson.com/mega65/justified-ancients/bombemall_hu_4278a152ea56888f.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/bombemall.png&#34;
        alt=&#34;Bomb&amp;amp;#39;em All, by btoschi&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Bomb&amp;rsquo;em All, by btoschi&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=99eb7f2b-ee95-421d-806f-32361a954448&#34;&gt;Bomb&amp;rsquo;em All&lt;/a&gt; by btoschi, an explosive action game for two to four players. Drop bombs, pick up items, and break through walls while trying to trap your opponents in the blast zone. The game supports the &lt;a href=&#34;https://www.bit-zeal.com/product/4PlayerMEGA65/6&#34;&gt;Four Fun joystick adapter&lt;/a&gt; for four joysticks, or can be played with a mix of joystick and keyboard controls.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/bsg.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/bsg.png 622w, https://dansanderson.com/mega65/justified-ancients/bsg_hu_2c86d37c4b07cb52.png 600w, https://dansanderson.com/mega65/justified-ancients/bsg_hu_97bae2af8f4f430f.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/bsg.png&#34;
        alt=&#34;BASIC Star Galactica, by jim_64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;BASIC Star Galactica, by jim_64&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=8c0cdef8-ac11-47e0-b422-a209e1a6727b&#34;&gt;BASIC Star Galactica&lt;/a&gt; by jim_64, a space battle adventure. Destroy the Cylons and protect the fleet—and the future of humanity. Don&amp;rsquo;t miss the &lt;a href=&#34;https://github.com/jim-64/BASIC-Star-G&#34;&gt;downloadable, printable disk label and manual&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/varicella.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/varicella.png 707w, https://dansanderson.com/mega65/justified-ancients/varicella_hu_54ade1e5b829d724.png 600w, https://dansanderson.com/mega65/justified-ancients/varicella_hu_3cfdb984fc7cfd1b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/varicella.png&#34;
        alt=&#34;The MEGA65 Z-code Text Adventure Collection Pack #4, edited by fredrikr&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The MEGA65 Z-code Text Adventure Collection Pack #4, edited by fredrikr&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;fredrikr has prepared &lt;a href=&#34;https://files.mega65.org?id=3c8e8567-0b03-49e3-81c6-e6b8b0360e64&#34;&gt;the fourth in his series of text adventure game bundles&lt;/a&gt; for the MEGA65, featuring modern classics from the interactive fiction community. This pack includes a variety of games released from 1995 to 2023, all playable on the MEGA65 thanks to the Ozmoo Z-machine player. (See &lt;a href=&#34;https://dansanderson.com/mega65/mega65-adventures/&#34;&gt;the Digest from October 2022&lt;/a&gt; for more on Ozmoo and MEGA65 adventure gaming.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/gng-cabinet.gif&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/gng-cabinet.gif 573w, https://dansanderson.com/mega65/justified-ancients/gng-cabinet_hu_84b878032b59651.gif 600w, https://dansanderson.com/mega65/justified-ancients/gng-cabinet_hu_dd0037a2cb587a04.gif 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/gng-cabinet.gif&#34;
        alt=&#34;Ghosts&amp;amp;#39;n Goblins, arcade core by muse&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Ghosts&amp;rsquo;n Goblins, arcade core by muse&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another arcade core from muse! In &lt;a href=&#34;https://files.mega65.org/html/main.php&#34;&gt;Ghosts&amp;rsquo;n Goblins&lt;/a&gt; (1985), you are brave knight Sir Arthur, on a quest to save the Princess Prin-Prin. Don your armor—and take care not to lose it—while fighting waves of zombies, giants, demons, and other monsters. This classic from Capcom is considered one of &lt;a href=&#34;https://en.wikipedia.org/wiki/List_of_video_games_considered_the_best&#34;&gt;the best video games of all time&lt;/a&gt;—and one of the most difficult. As with the other arcade cores, you will need to find the game ROM online, and &lt;a href=&#34;https://github.com/sho3string/GnGMEGA65&#34;&gt;follow the instructions&lt;/a&gt; to install it.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/stranded.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/stranded.jpg 961w, https://dansanderson.com/mega65/justified-ancients/stranded_hu_61914dc0a55a3f02.jpg 600w, https://dansanderson.com/mega65/justified-ancients/stranded_hu_a8669cde38bdfcd0.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/stranded.jpg&#34;
        alt=&#34;Stranded, by Magnus Heidenborn&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Stranded, by Magnus Heidenborn&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In &lt;a href=&#34;https://files.mega65.org?id=stranded&#34;&gt;Stranded&lt;/a&gt;, a graphical adventure game by Magnus Heidenborn, your boat has crashed and washed ashore a deserted island. Magnus wrote Stranded for the Commodore 64, specifically the modern &lt;a href=&#34;https://retrogames.biz/products/thec64/&#34;&gt;TheC64&lt;/a&gt; clone. Gurce ported it to the MEGA65, and added original music. I especially appreciate the novel keyboard-based linear travel and exploration mechanic, which works around common issues with point-and-click adventure games. Check it out!&lt;/p&gt;
&lt;h2 id=&#34;expansion-board-progress&#34;&gt;Expansion board progress&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/P1030853.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/P1030853.jpeg 1280w, https://dansanderson.com/mega65/justified-ancients/P1030853_hu_3585968a39bfd28b.jpeg 600w, https://dansanderson.com/mega65/justified-ancients/P1030853_hu_bd7f4e070e8f1054.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/P1030853.jpeg&#34;
        alt=&#34;The latest expansion board prototype&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The latest expansion board prototype, from Paul&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Paul is &lt;a href=&#34;https://c65gs.blogspot.com/2024/02/expansion-board-revd-and-new-connector.html&#34;&gt;making progress on the MEGA65 expansion board project&lt;/a&gt;. As we &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/&#34;&gt;reviewed in a previous issue&lt;/a&gt;, this project intends to produce an internal hardware expansion that adds component video output, a Commodore user port, a tape port, and a port for the never-released 1565 external floppy drive that was originally intended for the Commodore 65. The goal is for these expansion boards to be made entirely out of printed circuit boards (PCBs) and common components with open source designs, so anyone can order and assemble one from any PCB fabricator.&lt;/p&gt;
&lt;p&gt;The latest prototype includes a way to connect an &lt;a href=&#34;https://www.espressif.com/en/products/socs/esp32&#34;&gt;ESP32 wireless Internet module&lt;/a&gt; (!), and routes a path for the &lt;a href=&#34;https://dansanderson.com/mega65/welcome/using-jtag.html&#34;&gt;optional JTAG adapter&lt;/a&gt; to a firmly mounted microUSB port accessible through the back of the computer. It also completes the 1565 disk drive port. Hopefully someday we&amp;rsquo;ll be able to make a &lt;a href=&#34;https://www.m-e-g-a.org/commodore-1565/&#34;&gt;modern recreation 1565 drive&lt;/a&gt; with a plastic case that matches the MEGA65.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;klf-is-gonna-rock-you&#34;&gt;KLF is gonna rock you&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/klf_phone.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/klf_phone.png 864w, https://dansanderson.com/mega65/justified-ancients/klf_phone_hu_a9edd76fced7497f.png 600w, https://dansanderson.com/mega65/justified-ancients/klf_phone_hu_5e8e6f07dae78cdb.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/klf_phone.png&#34;
        alt=&#34;Ricardo da Force using a mobile phone, from 3AM Eternal (Live at the S.S.L.) (1991)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Ricardo da Force using a mobile phone
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Here is a visual representation of the waveform of the first few notes of &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/3_a.m._Eternal&#34;&gt;3 am Eternal&lt;/a&gt;&amp;rdquo; by &lt;a href=&#34;https://en.wikipedia.org/wiki/The_KLF&#34;&gt;The KLF&lt;/a&gt;, performed by soul singer &lt;a href=&#34;https://en.wikipedia.org/wiki/P._P._Arnold&#34;&gt;P. P. Arnold&lt;/a&gt;:&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/waveform_klf.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/waveform_klf.png 304w, https://dansanderson.com/mega65/justified-ancients/waveform_klf_hu_a978d5cc37d7359b.png 600w, https://dansanderson.com/mega65/justified-ancients/waveform_klf_hu_f0ff20b515d21d23.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/waveform_klf.png&#34;
        alt=&#34;Waveform diagram of P. P. Arnold&amp;amp;#39;s intro to The KLF&amp;amp;#39;s 3 a.m. Eternal&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Waveform diagram of P. P. Arnold&#39;s intro to The KLF&#39;s &#34;3 a.m. Eternal&#34;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Storing and replicating this waveform exactly as it was performed would require a device and a storage medium that could capture the infinitesimal changes of air pressure in the listener&amp;rsquo;s ear over time. Digital storage media is neither infinite nor infinitesimal, so we have to make some tradeoffs when &lt;em&gt;digitizing&lt;/em&gt; audio. How can we represent this waveform as a collection of numbers, then use those numbers to reproduce an approximation of the waveform on a loudspeaker?&lt;/p&gt;
&lt;h3 id=&#34;sample-rate&#34;&gt;Sample rate&lt;/h3&gt;
&lt;p&gt;Pulse-code modulation describes the height of a waveform measured periodically, or &lt;em&gt;sampled&lt;/em&gt;, over time. We can&amp;rsquo;t measure every infinitesimal point in time, so we have to choose a &lt;em&gt;sample rate&lt;/em&gt; that says how often we take a sample. For audio, a typical sample rate is on the order of &lt;em&gt;kilohertz&lt;/em&gt;, or thousands of times per second. A smooth curve in the original waveform is approximated by a stair-step pattern in the digitized waveform.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/samprate.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/justified-ancients/samprate.png&#34;
            width=&#34;600&#34;
            height=&#34;500&#34;
            alt=&#34;An illustration of how sample rate affects the accuracy of the digitized waveform&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Decreasing the sample rate reduces the accuracy of the digital waveform.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The sample rate for digital audio is a lot like the screen resolution of a digital image. The actual image of an object as seen by the eye could have infinitesimal detail, but to capture it and represent it on a screen, it must be digitized into pixels. The smaller and closer together the pixels, the more detail can be captured and represented. You can think of sample rate as the &amp;ldquo;horizontal resolution&amp;rdquo; of the waveform.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/klf_phone_res.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/klf_phone_res.png 1080w, https://dansanderson.com/mega65/justified-ancients/klf_phone_res_hu_35d30c02f04d8b9f.png 600w, https://dansanderson.com/mega65/justified-ancients/klf_phone_res_hu_8a055a80a1e11e18.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/klf_phone_res.png&#34;
        alt=&#34;An analogy with image resolution: lower resolution is less accurate&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An analogy with image resolution: decreasing resolution reduces the accuracy of the image.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;bit-depth&#34;&gt;Bit depth&lt;/h3&gt;
&lt;p&gt;We can&amp;rsquo;t measure the height of each waveform sample infinitesimally either, so this too needs a digital compromise. For example, we could store each sample as 8 bits (one byte) of data. This would give us 256 possible values for the sample. If the measured sample is between two adjacent values, it gets rounded—or &lt;em&gt;quantized&lt;/em&gt;—to the closest value. The number of storage bits per sample is the &lt;em&gt;bit depth&lt;/em&gt; of the sample (or &lt;em&gt;sample depth&lt;/em&gt;). You can think of bit depth as the &amp;ldquo;vertical resolution&amp;rdquo; of the waveform.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/bitdepth.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/justified-ancients/bitdepth.png&#34;
            width=&#34;600&#34;
            height=&#34;500&#34;
            alt=&#34;An illustration of how bit depth affects the accuracy of the digitized waveform&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Decreasing the bit depth reduces the accuracy of the digital waveform.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Sample depth can also be understood by analogy with digital images. Each pixel of an image is stored with a digital value that represents its color. The number of possible colors it can use is limited by the bit depth of the color value. Naturally, the more colors the computer can use for a pixel, the more accurately it can represent the original image.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/klf_phone_depth.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/klf_phone_depth.png 1080w, https://dansanderson.com/mega65/justified-ancients/klf_phone_depth_hu_a41b2dd0c46d5212.png 600w, https://dansanderson.com/mega65/justified-ancients/klf_phone_depth_hu_18a0aa21a148df95.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/klf_phone_depth.png&#34;
        alt=&#34;An analogy with image bit depth: lower depth is less accurate&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An analogy with image bit depth: decreasing depth reduces the accuracy of the image.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;signed-vs-unsigned-samples&#34;&gt;Signed vs. unsigned samples&lt;/h3&gt;
&lt;p&gt;Conceptually, an audio waveform is a variance in the regular air pressure of a silent room, wiggling positive and negative in a pattern until stabilizing back to zero. You can see the middle line on these waveform diagrams where this level lies. Based on this, waveform samples could be represented as a &lt;em&gt;signed&lt;/em&gt; number, with some negative numbers and some positive numbers around a baseline of zero. Or, it could be represented as an &lt;em&gt;unsigned&lt;/em&gt; number, where the baseline is the middle value of a range of positive numbers.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/signed.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/signed.png 600w, https://dansanderson.com/mega65/justified-ancients/signed_hu_6b85724100636e1c.png 600w, https://dansanderson.com/mega65/justified-ancients/signed_hu_dcf246d9fd1813de.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/signed.png&#34;
        alt=&#34;A diagram of signed vs. unsigned sample values; the effective waveform is the same&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Signed vs. unsigned sample values; the effective waveform is the same.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A signed 16-bit sample has a range of -32,768 to +32,767. It is usually stored as a &lt;a href=&#34;https://en.wikipedia.org/wiki/Two%27s_complement&#34;&gt;two&amp;rsquo;s complement&lt;/a&gt; value, $8000 (-32,768) up to $FFFF (-1), then $0000 (0) up to $7FFF (32,767). An unsigned 8-bit sample has a range of 0 to 255, where 128 is the baseline of the waveform. It is stored simply as its byte value, $00 (0) to $FF (255). If you&amp;rsquo;re messing with sample data, you need to know both its bit depth and whether it is signed or unsigned to interpret it correctly.&lt;/p&gt;
&lt;h2 id=&#34;size-vs-audio-quality&#34;&gt;Size vs. audio quality&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/Tower_Records_Sunset.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/Tower_Records_Sunset.jpg 1624w, https://dansanderson.com/mega65/justified-ancients/Tower_Records_Sunset_hu_19982cfea75b10c9.jpg 600w, https://dansanderson.com/mega65/justified-ancients/Tower_Records_Sunset_hu_75e6acf3134dad58.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/Tower_Records_Sunset.jpg&#34;
        alt=&#34;Tower Records, on Sunset Blvd. in West Hollywood, California, USA. Photograph by Mike Dillon, May 10, 2006, seven months before the store closed permanently.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Tower Records, on Sunset Blvd. in West Hollywood, California, USA. Photograph by Mike Dillon, May 10, 2006, seven months before the store closed permanently.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Both sample rate and bit depth explain how the amount of data relates to the quality of the reproduction of the original sound. The faster we sample, the more samples we collect, and the more accurate the data is to the original sound. The higher the bit depth of the sample, the more memory is required for each sample, and the more accurate the sample is to the waveform.&lt;/p&gt;
&lt;p&gt;Before there were large hard drives, fast Internet transmission speeds, and data compression algorithms tuned for audio, digital music could only be practically distributed on optical fixed-storage &lt;a href=&#34;https://en.wikipedia.org/wiki/Compact_disc&#34;&gt;compact discs&lt;/a&gt; (or &amp;ldquo;CDs,&amp;rdquo; as we called them). We purchased these discs at retail establishments with names such as &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/Tower_Records&#34;&gt;Tower Records&lt;/a&gt;,&amp;rdquo; and ordered them from printed catalogs to be delivered to our home via postal service from &lt;a href=&#34;https://en.wikipedia.org/wiki/Columbia_House&#34;&gt;Columbia House&lt;/a&gt; at an introductory cost of 10 discs for 1 penny. A typical audio CD stored 74 minutes of uncompressed stereo sound data, using a sample rate of 44.1 kHz and a depth of 16 bits.&lt;/p&gt;
&lt;p&gt;We can calculate the amount of sample data on an audio CD with a simple multiplication: 74 minutes x 60 seconds per minute x 44,100 samples per second x 2 bytes per sample x one sample for each stereo channel (2) = 783,216,000 bytes, or almost 747 MiB. Old-timers may remember that a CD-ROM, which uses the same type of disc for storing computer files, has a capacity of 650 MiB. CD-ROMs use the rest of the space for error correction and addressing, so computers can find files and make sure they read them correctly. When an audio CD player reads a sample incorrectly, it just pretends nothing happened and keeps going, so it can use more space for samples.&lt;/p&gt;
&lt;p&gt;For perspective, at CD quality, the MEGA65&amp;rsquo;s 8 megabytes of Attic RAM can contain 45 seconds of audio. As we&amp;rsquo;ll soon see, we&amp;rsquo;re actually limited to 64 kilobytes at a time, which would last us 0.35 seconds at 44.1 kHz 16-bit. We&amp;rsquo;ll need to make some tradeoffs in quality and duration to make practical use of digitized sound.&lt;/p&gt;
&lt;p&gt;The following are the durations of 64 kilobytes of sample data at various sample rates and bit depths:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;4000 Hz, 8-bit: 16.384 seconds&lt;/li&gt;
&lt;li&gt;4000 Hz, 16-bit: 8.192 seconds&lt;/li&gt;
&lt;li&gt;8000 Hz, 8-bit: 8.192 seconds&lt;/li&gt;
&lt;li&gt;8000 Hz, 16-bit: 4.096 seconds&lt;/li&gt;
&lt;li&gt;11025 Hz, 8-bit: 5.944 seconds&lt;/li&gt;
&lt;li&gt;11025 Hz, 16-bit: 2.972 seconds&lt;/li&gt;
&lt;li&gt;16000 Hz, 8-bit: 4.096 seconds&lt;/li&gt;
&lt;li&gt;16000 Hz, 16-bit: 2.048 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;mega65-audio-dmagic&#34;&gt;MEGA65 Audio DMAgic&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/dmagic.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/dmagic.png 500w, https://dansanderson.com/mega65/justified-ancients/dmagic_hu_861562f5f56b117.png 600w, https://dansanderson.com/mega65/justified-ancients/dmagic_hu_d24e0fab5ce837d7.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/dmagic.png&#34;
        alt=&#34;The original C65 DMAgic chip, from a REV 2A board&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The original C65 DMAgic chip, from a REV 2A board
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Imagine we had a way to control the speaker membrane directly from a MEGA65 program using a hardware register. What would the program have to do to play back a short digitized sound? The program would write each PCM sample to the register, and it would have to do it at a consistent rate that matches the sample rate. If the sound was digitized at 8 kHz, this program would have to write sample data to the register 8,000 times per second, at even intervals. This is entirely possible with a 40 MHz CPU, but getting the timing right would be a significant programming challenge, especially if the program does other things besides play the sound.&lt;/p&gt;
&lt;p&gt;Thankfully, the MEGA65 can help us with this. Reading a series of values from one memory location and writing them to another is the bread and butter of the Direct Memory Access (DMA) chip, a purpose-built chip in the Commodore 65 that the development team called &amp;ldquo;DMAgic.&amp;rdquo; DMA is typically used to copy one region of memory to another location very quickly, or fill a region with a value. Normally it does this as quickly as possible. The MEGA65 has enhanced DMAgic with a mechanism for playing audio samples to the DAC at a programmable sample rate, controlled with hardware registers. Your program can even do other things while the sample is playing: playback happens concurrently with program execution.&lt;/p&gt;
&lt;p&gt;Because sample timing is managed for us by audio DMA, we don&amp;rsquo;t need to worry about our program being fast or accurately timed. You can even use audio DMA from BASIC!&lt;/p&gt;
&lt;h3 id=&#34;audio-dma-specs-and-techniques&#34;&gt;Audio DMA specs and techniques&lt;/h3&gt;
&lt;p&gt;For audio DMA to work its &amp;ldquo;DMAgic,&amp;rdquo; a few things must be true:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The CPU must be running at 40 MHz. (This is the default.)&lt;/li&gt;
&lt;li&gt;Sample data must be in main memory, not Attic RAM.&lt;/li&gt;
&lt;li&gt;Samples must use a bit depth of 16, 8, or 4. Values can be signed or unsigned.&lt;/li&gt;
&lt;li&gt;The playback region cannot exceed 64 KB.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At first glance, this seems a bit limiting, but it&amp;rsquo;s actually quite powerful with a few tricks. For example, while sample data must be in the first 384 KB of main memory during playback, your program can store its samples in the 8 MB of Attic RAM, then use a DMA copy operation to install it in main memory to be played.&lt;/p&gt;
&lt;p&gt;4-bit samples are stored in an interesting way: the DMA must advance through memory by at least one byte per sample, so 4-bit samples use either the top four bits or the bottom four bits of each byte, and you tell audio DMA which bits to use when you play the sound. This means you can have two 4-bit sounds stored in the same bytes, one in the top bits and another in the bottom bits.&lt;/p&gt;
&lt;p&gt;When you play a sound, you can tell audio DMA to stop at the end, or loop back to the beginning automatically and continue playing. Looping is great for short repeating waveforms, or long repeating patterns like drum beats or atmospheric sounds.&lt;/p&gt;
&lt;p&gt;With a bit of cleverness, you can play sample data larger than 64 KB by taking advantage of the looping feature. Your program can copy new sample data into the memory region as the sound is being played, so when the playhead loops back to the beginning, it starts playing the new data.&lt;/p&gt;
&lt;p&gt;Your program specifies the sample rate to use the play the samples. If you want the samples to sound like the original recording, you play the samples at the rate they were digitized. You can also play the samples at a slower or faster rate to change the pitch and speed of the sample, like spinning a record player at a faster or slower speed. —Oh, uh, records were another way to distribute music before CDs, as analog waveforms etched into grooves on vinyl discs. Sounds were reproduced mechanically by vibrating a needle called a &lt;em&gt;stylus&lt;/em&gt;, by running it across the etched groove at a steady speed. Because retro is cool, &lt;a href=&#34;https://nowspinning.co.uk/vinyl-and-cd-sales-a-deep-dive-into-the-current-trends/&#34;&gt;vinyl album sales have seen a rapid resurgence&lt;/a&gt; recently that is expected to grow in 2024, while sales of CDs have dropped in favor of online music streaming.&lt;/p&gt;
&lt;h2 id=&#34;a-synthetic-example&#34;&gt;A synthetic example&lt;/h2&gt;
&lt;p&gt;Before we figure out how we get recorded sound data into the MEGA65, let&amp;rsquo;s try out the audio DMA system with some made-up numbers. We&amp;rsquo;ll use BASIC here, but the procedure is the same in assembly language: we&amp;rsquo;re just writing to memory and registers. (Try porting this example to assembly language!)&lt;/p&gt;
&lt;h3 id=&#34;the-waveform&#34;&gt;The waveform&lt;/h3&gt;
&lt;p&gt;To start, let&amp;rsquo;s draw a simple &amp;ldquo;sawtooth&amp;rdquo; waveform into some memory. This will just be the numbers 0 to 255 across 256 bytes of memory, which we will play looped.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 FOR X=0 TO 255 : POKE $50000+X,X : NEXT X&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/sawtooth_diag.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/justified-ancients/sawtooth_diag.png&#34;
            width=&#34;432&#34;
            height=&#34;131&#34;
            alt=&#34;Diagram of the synthetic sawtooth waveform generated by this code, looped&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The waveform generated by this code, looped.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;channel-registers&#34;&gt;Channel registers&lt;/h3&gt;
&lt;p&gt;Each of the four audio DMA channels has 16 bytes of registers. Channel 0&amp;rsquo;s registers are at addresses $D720 to $D72F, channel 1&amp;rsquo;s are at $D730 to $D73F, channel 2&amp;rsquo;s are at $D740 to $D74F, and channel 3&amp;rsquo;s are at $D750 to $D75F. I&amp;rsquo;ll refer to each register by its offset $0 through $F. Just know that the registers have the same layout for all four channels.&lt;/p&gt;
&lt;p&gt;Switch off channel 0 while we&amp;rsquo;re setting it up, by writing a 0 to register $0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;20 POKE $D720,0&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;enabling-the-audio-dma-system&#34;&gt;Enabling the audio DMA system&lt;/h3&gt;
&lt;p&gt;The audio DMA system must be enabled before it can be used. This is a global setting, address $D711 bit 7:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;30 SETBIT $D711,7&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;sample-addresses&#34;&gt;Sample addresses&lt;/h3&gt;
&lt;p&gt;The starting address of the sample is a 24-bit value, across registers $1 to $3. We also want to set the channel 0 playhead, a 24-bit value across registers $A to $C. (Remember, these are all Little Endian.) The starting address is used for looping: when the playhead reaches the end, it&amp;rsquo;ll jump back to the start address.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;40 POKE $D721,$00:POKE $D722,$00:POKE $D723,$05 : REM SAMPLE STARTS AT $5.0000
50 POKE $D72A,$00:POKE $D72B,$00:POKE $D72C,$05 : REM SET PLAYHEAD TO BEGINNING&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The end of the sample is stored as a 16-bit value equal to the lower 16 bits of the last address, in registers $7 to $8. In our case, the end address is $5.00FF, so the register value is $00FF.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;60 POKE $D727,$FF:POKE $D728,$00&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;channel-volume&#34;&gt;Channel volume&lt;/h3&gt;
&lt;p&gt;Each audio DMA channel gets two volume settings, with the ability to pan the channel&amp;rsquo;s output to the Left DAC or the Right DAC in different proportions.&lt;/p&gt;
&lt;p&gt;Channels 0 and 1 are considered &amp;ldquo;left&amp;rdquo; channels, and channels 2 and 3 are considered &amp;ldquo;right&amp;rdquo; channels. The $9 register in each channel&amp;rsquo;s register bank sets the volume of the signal that it outputs to its device, either the Left DAC or the Right DAC. The register value is between 0 and 255, with 255 being the loudest.&lt;/p&gt;
&lt;p&gt;Another set of volume registers allow for each channel to also output to the opposing DAC. Registers $D71C and $D71D set the output of channels 0 and 1, respectively, to the Right DAC. Registers $D71E and $D71F set the output of channels 2 and 3, respectively, to the Left DAC.&lt;/p&gt;
&lt;p&gt;This can get a little confusing because the user can subsequently pan the Left DAC or the Right DAC using the Audio &amp;amp; Volume tool in the Freezer, and can even flip the stereo field entirely. If you want to experiment with this, I recommend opening the Freezer tool and setting the &amp;ldquo;Left Digi&amp;rdquo; volume up in the left output channel and all the way down in the right output channel, and the &amp;ldquo;Right Digi&amp;rdquo; volume down in the left and up in the right, so you can hear clearly through stereo speakers which DAC is being used.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s just set channel 0 to output evenly to both DACs for now. This sawtooth wave is a bit obnoxious, so I&amp;rsquo;m using a low volume level:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;70 POKE $D71C,$22 : POKE $D729,$22&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Headphone warning:&lt;/strong&gt; If you are listening to your MEGA65 with headphones connected directly to the 3.5mm jack, I recommend reducing the master volume in the Audio &amp;amp; Volume tool while you are testing digital audio samples. Incorrect sample data or erroneous register values could cause unexpectedly loud sounds. I prefer to use a set of speakers with an independent volume knob set to a low setting. (Headphones tend not to have their own volume control.)&lt;/p&gt;
&lt;h3 id=&#34;sample-rate-1&#34;&gt;Sample rate&lt;/h3&gt;
&lt;p&gt;The sample rate (frequency) is stored as a 24-bit value in registers $4 to $6. This one is a bit weird, but it&amp;rsquo;ll make sense, I promise.&lt;/p&gt;
&lt;p&gt;The value is the 24-bit proportional value of the frequency relative to the CPU speed. For example, if the sample rate is 16 kHz, then the register value is 16 kHz divided by 40 MHz (a ratio), multiplied by 2 to the 24th power minus 1 (the largest 24-bit value). Watch those units when doing the math! The CPU is much faster than the sample rate, so you should get a very small ratio.&lt;/p&gt;
&lt;p&gt;Here are the register values for some useful sample rates, pre-calculated for your convenience:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;4 kHz : 1,662 ($00067E)&lt;/li&gt;
&lt;li&gt;8 kHz : 3,324 ($000CFC)&lt;/li&gt;
&lt;li&gt;16 kHz : 6,648 ($0019F8)&lt;/li&gt;
&lt;li&gt;32 kHz : 13,296 ($0033F0)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For our experiment, we actually want to do something special with the frequency. We have a very short sawtooth waveform, capable of playing a musical note. The middle &amp;ldquo;A&amp;rdquo; key on a piano would play this pattern 440 times per second (440 Hz). We have 256 samples, so to achieve a middle A pitch, we need a sample rate of 440 x 256 = 112640 Hz = 112.64 kHz. Proportional to the 40 MHz CPU speed, the 24-bit value is: 47,244 decimal, or $00B88C (that&amp;rsquo;s &amp;ldquo;zero zero Baker eight eight Charlie&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Someone check my math.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;80 POKE $D724,$8C:POKE $D725,$B8:POKE $D726,$00 : REM SAMPLE RATE 112.64 KHZ&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;sample-sign-bit-depth-looping-and-playback&#34;&gt;Sample sign, bit depth, looping, and playback&lt;/h3&gt;
&lt;p&gt;Finally, we can trigger the sample, with a few last settings in register $0. This register uses the following bits as flags:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bit 7: Play it.&lt;/li&gt;
&lt;li&gt;Bit 6: Loop it. We want this to loop our very short sawtooth wave.&lt;/li&gt;
&lt;li&gt;Bit 5: Set this to 0 if the sample value is signed. We&amp;rsquo;re using unsigned values in this example, so we set this to 1.&lt;/li&gt;
&lt;li&gt;Bits 1-0: The bit depth: 11=16 bits, 10=8 bits (our choice), 01=upper 4 bits, 00=lower 4 bits.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;90 POKE $D720, $80 + $40 + $20 + $02
100 GETKEY A$ : REM WAIT FOR A KEYPRESS
110 POKE $D720,0 : REM SWITCH IT OFF! SWITCH IT OFF!&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;try-it-out&#34;&gt;Try it out!&lt;/h3&gt;
&lt;p&gt;Run this to hear the tone. It&amp;rsquo;s a bit obnoxious, so press a key to switch it off. If you accidentally press Run/Stop with the sound still playing, use &lt;code&gt;POKE $D720,0&lt;/code&gt; to disable the sound.&lt;/p&gt;
&lt;p&gt;You can experiment with different waveforms by writing different values to $5.0000-$5.00FF. Try these:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 FOR X=0 TO 255 : POKE $50000+X,255*(SGN(X-128)+1) : NEXT X

10 FOR X=0 TO 255 : POKE $50000+X,X-(X-128)*(X&amp;gt;128) : NEXT X

10 FOR X=0 TO 255 : POKE $50000+X,127*SIN(X/255*3.1415)+128 : NEXT X&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;converting-audio-files-to-raw-pcm-data&#34;&gt;Converting audio files to raw PCM data&lt;/h2&gt;
&lt;p&gt;This little experiment to play triangle, sawtooth, and sine waveforms is fun, but not particularly impressive considering that the SID chips can already generate these waveforms on their own. To unleash the true power of audio DMA, we need PCM sample data for more interesting sounds. The MEGA65 does not have a built-in audio digitizer (at least not yet), so we must turn to our trusty modern computers.&lt;/p&gt;
&lt;p&gt;There are many ways to record, produce, or otherwise acquire sound files with a modern computer and an Internet connection. Your computer&amp;rsquo;s operating system probably includes a free sound recording or editing program, and so does your mobile phone. Sound editing software like &lt;a href=&#34;https://www.audacityteam.org/&#34;&gt;Audacity&lt;/a&gt; is free, and you can also download free sound files from &lt;a href=&#34;https://freesound.org/&#34;&gt;FreeSound.org&lt;/a&gt;. Whatever software you&amp;rsquo;re using, be sure to edit your sound file to trim it to just the length you want your MEGA65 program to play.&lt;/p&gt;
&lt;h3 id=&#34;audacity&#34;&gt;Audacity&lt;/h3&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/audacity_export.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/audacity_export.png 691w, https://dansanderson.com/mega65/justified-ancients/audacity_export_hu_5f59a7efe232c31b.png 600w, https://dansanderson.com/mega65/justified-ancients/audacity_export_hu_3fe5c07470009a3e.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/audacity_export.png&#34;
        alt=&#34;Screenshot of the Audacity application&amp;amp;#39;s audio export dialog, set for raw PCM data&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Audacity&#39;s audio export dialog, set to export monophonic PCM data, 8 kHZ 8-bit unsigned.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Our goal is to convert the sound file to raw PCM sample data at an appropriate sample rate, and at a bit depth supported by the MEGA65 audio DMA. Audacity can do all of this in a single export step:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;File menu, Export Audio.&lt;/li&gt;
&lt;li&gt;Format: &amp;ldquo;Other uncompressed files&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Channels: Mono&lt;/li&gt;
&lt;li&gt;Sample Rate: 8000 Hz or higher, or select &amp;ldquo;Other&amp;rdquo; and enter any rate in Hertz&lt;/li&gt;
&lt;li&gt;Header: &amp;ldquo;RAW (header-less)&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Encoding: &amp;ldquo;Signed 16-bit PCM&amp;rdquo; or &amp;ldquo;Unsigned 8-bit PCM&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Click Export.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Remember that sample rate and bit depth affect data size and sound quality, so choose wisely.&lt;/p&gt;
&lt;p&gt;Other modern sound production software may not have all of the same export options. Some of the more expensive software packages on my computer can&amp;rsquo;t believe I would ever want to export at a sample rate lower than 44.1 kHz. If your software doesn&amp;rsquo;t export raw PCM sample data, or doesn&amp;rsquo;t offer the desired sample rate or bit depth, export a &lt;code&gt;.wav&lt;/code&gt; file with high quality settings, then use Audacity for the final conversion to raw PCM data with the desired parameters.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important to use the highest quality settings for every processing step until the last one. Because each digital audio file is an approximation of the original waveform, the conversion tool has to use some math to assume the gaps between the samples when converting from one sample rate to another. The more data that goes into that process, the better.&lt;/p&gt;
&lt;p&gt;While preparing this Digest, I had occasional issues with Audacity trying to boost the volume of my samples, causing &lt;a href=&#34;https://en.wikipedia.org/wiki/Clipping_(audio)&#34;&gt;clipping&lt;/a&gt; of the signal in some cases that added loud pops to the final sound effect. Notably, this clipping only happened on real hardware and not in Xemu, so be sure to test your samples.&lt;/p&gt;
&lt;h3 id=&#34;ffmpeg&#34;&gt;ffmpeg&lt;/h3&gt;
&lt;p&gt;Audacity is fine, but I like command line tools so I can automate build workflows. The tool for this is &lt;a href=&#34;https://ffmpeg.org/&#34;&gt;ffmpeg&lt;/a&gt;, an essential free media conversion tool for video and audio. It&amp;rsquo;s similar to how we used &lt;a href=&#34;https://imagemagick.org/index.php&#34;&gt;ImageMagick&lt;/a&gt; to convert still images back in &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/&#34;&gt;a previous Digest&lt;/a&gt;. ffmpeg is available for all platforms. On a Mac using &lt;a href=&#34;https://brew.sh/&#34;&gt;Homebrew&lt;/a&gt;, install this with: &lt;code&gt;brew install ffmpeg&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;ffmpeg accepts most audio files as input, including &lt;code&gt;.wav&lt;/code&gt; files. Specify the input file with the &lt;code&gt;-i&lt;/code&gt; parameter. It&amp;rsquo;ll detect everything it needs to know about the input data from the file itself.&lt;/p&gt;
&lt;p&gt;For the output file, we want something special, so we need to tell it what we want. The &lt;code&gt;-f&lt;/code&gt; option selects the bit rate, selected from &lt;a href=&#34;https://trac.ffmpeg.org/wiki/audio%20types&#34;&gt;this list&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;s16le&lt;/code&gt; : signed 16-bit Little Endian&lt;/li&gt;
&lt;li&gt;&lt;code&gt;u16le&lt;/code&gt; : unsigned 16-bit Little Endian&lt;/li&gt;
&lt;li&gt;&lt;code&gt;u8&lt;/code&gt; : unsigned 8-bit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To convert the file to a different sample rate, use the &lt;code&gt;-ar&lt;/code&gt; option, and provide the value in Hertz. To convert a stereo sound to monophonic, specify &lt;code&gt;-ac 1&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ffmpeg -i klf.wav -f u8 -ar 8000 -ac 1 klf.raw&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You now have a raw PCM data file. Assuming it&amp;rsquo;s small enough, you can now copy this to a D81 disk image, and transfer the disk image to your MEGA65. See &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/&#34;&gt;a previous Digest&lt;/a&gt; for more information on how to manage files and disk images.&lt;/p&gt;
&lt;h2 id=&#34;playing-the-digitized-sound&#34;&gt;Playing the digitized sound&lt;/h2&gt;
&lt;p&gt;The BASIC program above can be modified to play an arbitrary sample file. Replace line 10 with a &lt;code&gt;BLOAD&lt;/code&gt; command that loads your sample file to address $50000:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 BLOAD &amp;#34;KLF.RAW&amp;#34;,P($0050000)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You will need to adjust the sample length (line 60) and the sample rate (line 80) as appropriate for your data. You might want to remove the loop flag (&lt;code&gt;$40&lt;/code&gt;) from the playback command (line 90). Only include the &amp;ldquo;unsigned&amp;rdquo; flag (&lt;code&gt;$20&lt;/code&gt; on line 90) if the sample data is unsigned.&lt;/p&gt;
&lt;p&gt;Can you hear the sound, but it&amp;rsquo;s noisy or crackling? Double-check the &amp;ldquo;unsigned&amp;rdquo; bit. Using the unsigned bit when the sample data is signed (and vice versa) will cause transitions from negative to positive values to pop, in a bad way.&lt;/p&gt;
&lt;h2 id=&#34;what-about-4-bit-sample-data&#34;&gt;What about 4-bit sample data?&lt;/h2&gt;
&lt;p&gt;None of the audio processing programs I tried offer export of 4-bit samples. How can we make 4-bit samples, to take advantage of this feature of audio DMA?&lt;/p&gt;
&lt;p&gt;Compared to something as complex as re-sampling at different sample rates, converting from an unsigned 8-bit sample to an unsigned 4-bit sample is simple. We just lop off the lower four bits, equivalent to dividing by 16. Here&amp;rsquo;s a simple Python program that does this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INPUT_FILE = &amp;#39;klf_8b.raw&amp;#39;
OUTPUT_FILE = &amp;#39;klf_4b.raw&amp;#39;

data_input = open(INPUT_FILE, &amp;#39;rb&amp;#39;).read()

with open(OUTPUT_FILE, &amp;#39;wb&amp;#39;) as outfile:
  for i in range(len(data_input)):
    samp = int(data_input) // 16
    outfile.write(samp)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This takes the file &lt;code&gt;klf_8b.raw&lt;/code&gt; containing unsigned 8-bit samples and produces the file &lt;code&gt;klf_4b.raw&lt;/code&gt; containing unsigned 4-bit samples, with each sample in the lower four bits. We can modify our playback program to use this by setting the appropriate flags in the $0 register:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;90 POKE $D720, $80 + $20 : REM PLAY IT ONCE, UNSIGNED, 4-BIT LOW&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Audio DMA requires that each sample be at separate memory locations, so merely converting a sample from 8-bit to 4-bit doesn&amp;rsquo;t actually save any space. The space savings comes from storing two 4-bit samples on top of each other, and telling audio DMA to play either the bottom four bits or the top four bits. We can modify this Python script to store two samples together in this way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INPUT_FILE_ONE = &amp;#39;klf_8b.raw&amp;#39;
INPUT_FILE_TWO = &amp;#39;rockyou_8b.raw&amp;#39;
OUTPUT_FILE = &amp;#39;klf_4b.raw&amp;#39;

data_one = open(INPUT_FILE_ONE, &amp;#39;rb&amp;#39;).read()
data_two = open(INPUT_FILE_TWO, &amp;#39;rb&amp;#39;).read()

# Pad the shorter sample with zeroes, so they are the same length
if len(data_one) &amp;lt; len(data_two):
  data_one += b&amp;#39;\x00&amp;#39; * (len(data_two) - len(data_one))
elif len(data_two) &amp;lt; len(data_one):
  data_two += b&amp;#39;\x00&amp;#39; * (len(data_one) - len(data_two))

with open(OUTPUT_FILE, &amp;#39;wb&amp;#39;) as outfile:
  for i in range(len(data_one)):
    samp_one = int(data_one[i]) // 16
    samp_two = int(data_two[i]) // 16
    result = samp_two * 16 + samp_one
    outfile.write(bytes([result]))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This takes the two 8-bit sample files &lt;code&gt;klf_8b.raw&lt;/code&gt; and &lt;code&gt;rockyou_8b.raw&lt;/code&gt;, converts them both to 4-bit, then writes them to a single file &lt;code&gt;klf_4b.raw&lt;/code&gt; with &lt;code&gt;klf&lt;/code&gt; in the lower bits and &lt;code&gt;rockyou&lt;/code&gt; in the upper bits.&lt;/p&gt;
&lt;p&gt;To tell the playback program which sample to play, set bits 1 and 0 of $D720 accordingly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;90 POKE $D720, $80 + $20 : REM PLAY IT ONCE, UNSIGNED, 4-BIT LOW

90 POKE $D720, $80 + $20 + $01 : REM PLAY IT ONCE, UNSIGNED, 4-BIT HIGH&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;I have a vivid memory of hearing The KLF&amp;rsquo;s &amp;ldquo;3 a.m. Eternal&amp;rdquo; played on my childhood Amiga 500. Like the MEGA65, the Amiga can play short digitized sounds over four audio DACs. Most Amiga owners didn&amp;rsquo;t have enough memory to store several minutes of digitized sound, so another kind of music was born. A &lt;a href=&#34;https://en.wikipedia.org/wiki/MOD_(file_format)&#34;&gt;MOD file&lt;/a&gt; encodes music as short digitized sounds played in a pattern of frequencies and timings, saving memory by re-using samples throughout the song. The KLF&amp;rsquo;s music was largely sample-based and repetitive to begin with, and they even produced some of it on home computers like the Apple II and Atari ST. MOD files can come close to reproducing the original songs within the memory limitations of a vintage computer.&lt;/p&gt;
&lt;p&gt;Your MEGA65 includes a MOD player on the Intro Disk, called &amp;ldquo;&lt;a href=&#34;https://files.mega65.org?id=73b398a2-d7fa-43fd-9dd5-7879cc824e46&#34;&gt;Manche&lt;/a&gt;,&amp;rdquo; that uses audio DMA to play sound samples. I found one person&amp;rsquo;s attempt at a MOD of &amp;ldquo;3 a.m. Eternal&amp;rdquo; and was able to play it in Manche on my MEGA65. I can&amp;rsquo;t say this particular MOD is my favorite remix, but it&amp;rsquo;s been fun to revive this memory.&lt;/p&gt;
&lt;p&gt;Here are a few MOD arrangements of KLF songs for you to enjoy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download: &lt;a href=&#34;3ametern.mod&#34;&gt;3ametern.mod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Download: &lt;a href=&#34;whattime.mod&#34;&gt;whattime.mod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Download: &lt;a href=&#34;doctorin.mod&#34;&gt;doctorin.mod&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Put these in the root of your SD card, then start Intro Disk #1. Open the Music menu, select Manche, and press &lt;kbd&gt;Return&lt;/kbd&gt; to run the program. Within Manche, press F1, type one of the filenames, then press &lt;kbd&gt;Return&lt;/kbd&gt; to load the file. Press &lt;kbd&gt;Space&lt;/kbd&gt; to start playback.&lt;/p&gt;
&lt;p&gt;I also made this demonstration disk with the waveform generator program from this issue, as well as a program demonstrating the same sound at different sample rates and bit depths.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download: &lt;a href=&#34;KLF.D81&#34;&gt;KLF.D81&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/justified-ancients/klf_clarinet.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/justified-ancients/klf_clarinet.png 867w, https://dansanderson.com/mega65/justified-ancients/klf_clarinet_hu_81aafaa0cf0b3ffe.png 600w, https://dansanderson.com/mega65/justified-ancients/klf_clarinet_hu_b12fb2b86b9be616.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/justified-ancients/klf_clarinet.png&#34;
        alt=&#34;Duy Khiem on the clarinet, from 3AM Eternal (Live at the S.S.L.) (1991)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Clarinet solo!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This Digest is made possible with support from justified ancients, like you! To contribute, visit &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;See you next month!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/justified-ancients/M65Digest_2024Mar.mp3" length="49438218" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>2472</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/justified-ancients/klf.png"/>
      
    </item>
    
    <item>
      <title>Release Day!</title>
      <link>https://dansanderson.com/mega65/release-day/</link>
      <pubDate>Sun, 25 Feb 2024 00:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/release-day/</guid>
      <description>&lt;p&gt;MEGA65 platform release v0.96 is now available! This release is a culmination of 14 months of improvements to the FPGA core, the MEGA65 ROM, and system software. You can also now download the final version of the new User&amp;rsquo;s Guide PDF and Intro Disk software package. Everyone who owns a MEGA65 is encouraged to upgrade.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;MEGA65 platform release v0.96 is now available! This release is a culmination of 14 months of improvements to the FPGA core, the MEGA65 ROM, and system software. You can also now download the final version of the new User&amp;rsquo;s Guide PDF and Intro Disk software package. Everyone who owns a MEGA65 is encouraged to upgrade.&lt;/p&gt;
&lt;h3 id=&#34;for-the-mega65-delivered-in-2022&#34;&gt;For the MEGA65 delivered in 2022&amp;hellip;&lt;/h3&gt;
&lt;p&gt;If you own a MEGA65 delivered in 2022, &lt;a href=&#34;https://files.mega65.org/&#34;&gt;sign in to Filehost&lt;/a&gt; with the account you used to redeem your owner code, then &lt;a href=&#34;https://files.mega65.org?id=a0276005-e71c-4b2d-8d17-2aa92e492c50&#34;&gt;download MEGA65 release v0.96&lt;/a&gt; for &amp;ldquo;R3&amp;rdquo; boards. If you don&amp;rsquo;t yet have a Filehost account, register for one, then select &amp;ldquo;Redeem Code&amp;rdquo; from the user menu and enter the nine character code printed on the piece of paper that was included with your MEGA65. This gives you access to the release packages &amp;ldquo;with ROM,&amp;rdquo; and a few other things.&lt;/p&gt;
&lt;p&gt;Download &lt;a href=&#34;https://builder.mega65.org/job/mega65-user-guide/job/master/lastSuccessfulBuild/artifact/mega65-userguide.pdf&#34;&gt;The MEGA65 User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt; PDF, and follow the instructions in the chapter, &amp;ldquo;Upgrading the MEGA65.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;You will want to update the factory core in slot 0 to this release. Please see the &amp;ldquo;NOTE&amp;rdquo; in the User&amp;rsquo;s Guide about upgrading an R3A MEGA65 for the first time: there&amp;rsquo;s a little trick required to start the flasher from the v0.96 core in slot 1 to flash the v0.96 core to slot 0. Don&amp;rsquo;t worry, it&amp;rsquo;s easy, just don&amp;rsquo;t miss the note. For a more detailed version of these instructions with photos, see &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/83689488/Visual+Guide+to+Flashing+Slot+0+without+JTAG&#34;&gt;Visual Guide to Flashing Slot 0 without JTAG&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Lastly, download M65Connect v2.3 &lt;a href=&#34;https://files.mega65.org?id=d612d745-360e-4e86-8e15-14af525b6220&#34;&gt;for Windows (Intel)&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=1b849d0a-2ceb-44aa-beb4-a2cdfa51eb19&#34;&gt;for Windows (ARM)&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=5919a8b8-c23c-4616-9a52-37e077076638&#34;&gt;for macOS (Universal)&lt;/a&gt;, or &lt;a href=&#34;https://files.mega65.org?id=c1dbc7fe-89ad-4f1d-9e72-ad3f55cf02a1&#34;&gt;for Linux (Intel)&lt;/a&gt;. This powerful desktop application includes new features and enhancements for transferring files between your PC and your MEGA65, with support for a new feature in the v0.96 release: file transfer over Ethernet. See the User&amp;rsquo;s Guide for more information, as well as &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/48365569/M65Connect&#34;&gt;the new M65Connect section of the Wiki&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;for-xemu-users&#34;&gt;For Xemu users&amp;hellip;&lt;/h3&gt;
&lt;p&gt;If you don&amp;rsquo;t yet own a MEGA65 and use &lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;the Xemu MEGA65 emulator&lt;/a&gt;, you can upgrade the MEGA65 ROM to the release v0.96 version, ROM 920395. &lt;a href=&#34;https://files.mega65.org?id=fd2c40b9-f337-41f7-8a81-0254b1e09fb5&#34;&gt;Download the ROM 920395 diff files&lt;/a&gt;, then follow the instructions in the &lt;a href=&#34;https://files.mega65.org?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;ROM FAQ&lt;/a&gt; to construct the &lt;code&gt;mega65.rom&lt;/code&gt; file. The M65Connect app includes a built-in ROM patching tool for this purpose. See also the &lt;a href=&#34;https://github.com/lgblgblgb/xemu/wiki/MEGA65-quickstart&#34;&gt;Xemu MEGA65 Quickstart&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The release v0.96 ROM requires a recent version of Xemu, dated December 2023 or later. If you haven&amp;rsquo;t updated Xemu in a while, get the latest &amp;ldquo;stable&amp;rdquo; version.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://builder.mega65.org/job/mega65-user-guide/job/master/lastSuccessfulBuild/artifact/mega65-userguide.pdf&#34;&gt;The MEGA65 User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt; PDF has been fully updated with information about recently added features to BASIC 65.&lt;/p&gt;
&lt;h3 id=&#34;for-devkit-owners&#34;&gt;For DevKit owners&amp;hellip;&lt;/h3&gt;
&lt;p&gt;Release v0.96 is available for the MEGA65 DevKit. Download and install the &lt;code&gt;mega65r3&lt;/code&gt; release package, as above.&lt;/p&gt;
&lt;p&gt;An important note for this case: the v0.96 core flasher does &lt;em&gt;not&lt;/em&gt; yet work on the DevKit. You can use the v0.95 core to flash the v0.96 core (such as in slot 1), but be sure to keep the v0.95 core around (such as in slot 0) for flashing other cores.&lt;/p&gt;
&lt;p&gt;This shortcoming will be resolved in the next few months with a follow-up release.&lt;/p&gt;
&lt;h3 id=&#34;for-nexys-dev-boards&#34;&gt;For Nexys dev boards&amp;hellip;&lt;/h3&gt;
&lt;p&gt;The v0.96 release is not yet available for FPGA development boards, such as the Nexys. This will be addressed in a follow-up release. Please continue to use v0.95 for now.&lt;/p&gt;
&lt;h3 id=&#34;for-those-who-are-about-to-rock&#34;&gt;For those who are about to rock&amp;hellip;&lt;/h3&gt;
&lt;p&gt;The MEGA65s that will be delivered in June 2024 will have this release installed at the factory. We plan to do another release before then, so you&amp;rsquo;ll want to check for newer versions and upgrade shortly after receiving your computer.&lt;/p&gt;
&lt;h2 id=&#34;reminders-of-other-things-you-can-get&#34;&gt;Reminders of other things you can get&lt;/h2&gt;
&lt;p&gt;As I mentioned in the previous newsletter, you can now &lt;a href=&#34;https://www.lulu.com/shop/dan-sanderson-and-edilbert-kirk-and-paul-gardner-stephen/mega65-users-guide/paperback/product-dyrzzzy.html?page=1&amp;amp;pageSize=4&#34;&gt;purchase the MEGA65 User&amp;rsquo;s Guide, 2nd edition, in print form&lt;/a&gt;. Orders so far have been arriving on doorsteps all over the world, and it turned out great! Don&amp;rsquo;t miss &lt;a href=&#34;https://files.mega65.org/?ar=1c17f84a-2f10-4ad0-9168-6201331ece4b&#34;&gt;the UG2 FAQ&lt;/a&gt; that answers a few anticipated questions.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;The 45GS02 Quick Reference mousepad and poster&lt;/a&gt; are still available. I added &lt;a href=&#34;https://files.mega65.org?ar=46e7054c-9740-4e85-9df3-05b4a0f34122&#34;&gt;this article to Filehost&lt;/a&gt; with a few action photos.&lt;/p&gt;
&lt;p&gt;More MEGA65s will ship in June of this year, and they will include &lt;a href=&#34;https://files.mega65.org?id=all-intros-public&#34;&gt;a massive new Intro Disk software bundle&lt;/a&gt; (&lt;a href=&#34;https://files.mega65.org?id=all-intros&#34;&gt;registered owner version&lt;/a&gt;). Download this for your own computer and copy all of the files to your SD card. This is a superset of the software that was included in 2022, including updated versions of previous titles.&lt;/p&gt;
&lt;h2 id=&#34;whats-new&#34;&gt;What&amp;rsquo;s new?&lt;/h2&gt;
&lt;p&gt;Notable changes in the MEGA65 firmware from release v0.95 to v0.96 (see &lt;a href=&#34;https://github.com/MEGA65/mega65-core/blob/release-0.96/release-build/Changelog.md&#34;&gt;the core changelog&lt;/a&gt; for a complete list):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ethernet file transfer support; use the new M65Connect app (or command line tools), and see the User&amp;rsquo;s Guide, 2nd edition, for instructions&lt;/li&gt;
&lt;li&gt;New core selection and flashing menu, capable of flashing slot 0 without a JTAG adapter
&lt;ul&gt;
&lt;li&gt;Can configure core slots to be selected automatically when different types of cartridges are connected, so a C64 cart can auto-boot into the C64 core instead of the MEGA65 core&lt;/li&gt;
&lt;li&gt;Core file selector supports long filenames&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;New hardware typing event queue, enables faster and more accurate typing&lt;/li&gt;
&lt;li&gt;Improvements to the chipset, Freezer, SD card utility, and Configuration utility
&lt;ul&gt;
&lt;li&gt;Fixed mouse handling in port 2&lt;/li&gt;
&lt;li&gt;Configuration utility now prompts to power cycle on exit, to avoid confusion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Support for the upcoming R6 main board (and intermediate test versions R4 and R5)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notable changes in the MEGA65 ROM from release v0.95 to v0.96 (see &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/blob/main/CHANGELOG.md&#34;&gt;the ROM changelog&lt;/a&gt; for a complete list):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Screen editor and KERNAL use the new hardware typing event queue, for faster and more accurate typing&lt;/li&gt;
&lt;li&gt;80 x 50 text mode: press ESC then 5 (press ESC then 8 or 4 to select 80x25 and 40x25)&lt;/li&gt;
&lt;li&gt;Default sprite images, including a mouse pointer in sprite slot 0&lt;/li&gt;
&lt;li&gt;GO64 mode now displays a custom banner instead of the C64 banner, so it&amp;rsquo;s easier to distinguish between GO64 mode and the C64 core&lt;/li&gt;
&lt;li&gt;Support for booting MEGA65 cartridges, based on the &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/36962324/MEGA65+Style+Cartridge+Work+in+Progress&#34;&gt;MEGA65 cartridge protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Run/Stop-Restore now restores the character set&lt;/li&gt;
&lt;li&gt;Improvements to the Monitor, Renumber, BASIC commands, DOS&lt;/li&gt;
&lt;li&gt;For this release only: the ROM will detect whether it is being run with an older core or Xemu version, and halt with a message. Be sure to use the v0.96 core or a recent version of Xemu with this ROM.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;whats-next&#34;&gt;What&amp;rsquo;s next?&lt;/h2&gt;
&lt;p&gt;A big blow-out party! Or maybe just some rest and relaxation. It&amp;rsquo;s been a long haul, with some heroic efforts from the development and testing team in the last few weeks. Everyone has chipped in to make this release and the next delivery batch of MEGA65s the best as they can be.&lt;/p&gt;
&lt;p&gt;The core team will proceed with working on a follow-up release, currently expected to be called v0.97 and released in a few months. This will include some clean-up tasks that were deferred from v0.96 to hit the batch #3 delivery schedule, including full support for DevKits and Nexys boards.&lt;/p&gt;
&lt;p&gt;As for ROM development, there&amp;rsquo;s exciting news! We&amp;rsquo;ve been focusing primarily on bug fixes over the last year, mostly to ensure we&amp;rsquo;re making the best use of the very limited space we have for new ROM code. The next ROM beta test will include the results of a project I&amp;rsquo;ve been working on to make more code space available for new features. I have taken this opportunity to implement a bunch of features requested by the MEGA65 community over the last two years, and these will also be included in the next beta. Remember that beta releases may have bugs, so thanks in advance for your patience, and your bug reports! Stay tuned to &lt;a href=&#34;https://mega65.org/chat&#34;&gt;the Discord&lt;/a&gt; for an announcement, very soon.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;And one last obligatory plug: My contributions to the MEGA65 project, including this newsletter, are made possible with support from retro computing enthusiasts like you! Please consider a monthly donation. Visit &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks all! Back again in March with another full issue.&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>Sprite Attack!</title>
      <link>https://dansanderson.com/mega65/sprite-attack/</link>
      <pubDate>Thu, 15 Feb 2024 23:00:00 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/sprite-attack/</guid>
      <description>&lt;p&gt;Sprite Attack. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for February 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Sprite Attack. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for February 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/sprite-attack/M65Digest_2024Feb.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/M65Digest_2024Feb.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Sprite Attack.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/s1.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/s1.png 509w, https://dansanderson.com/mega65/sprite-attack/s1_hu_b0a418f8ee1a6639.png 600w, https://dansanderson.com/mega65/sprite-attack/s1_hu_1f9e1fbbba2fc39b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/s1.png&#34;
        alt=&#34;A space ship sprite in the MEGA65 SpritEd sprite editor.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A space ship sprite in the MEGA65 SpritEd sprite editor.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Spaceships. Aliens. Marios. Goombas. Bullets. Fireballs. Mouse pointers, text cursors. Any of these could be a &lt;a href=&#34;https://en.wikipedia.org/wiki/Sprite_(computer_graphics)&#34;&gt;&lt;em&gt;sprite&lt;/em&gt;&lt;/a&gt;, a feature of a computer graphics system dedicated to things that move. The sprite capabilities of the Commodore 64&amp;rsquo;s VIC-II chip super-charged video games and user interfaces beyond a single screenful of character text or a bitmap image. The MEGA65 includes support for VIC-II hardware sprites, and has sprite-related BASIC commands that make them easy to use in your programs.&lt;/p&gt;
&lt;p&gt;In this Digest, we&amp;rsquo;ll review the VIC-II sprite system&amp;rsquo;s capabilities, try out the sprite features added to Commodore BASIC for the C128, C65, and MEGA65, and step through a development workflow for using sprites in BASIC games. And we&amp;rsquo;ll try putting these pieces together to make a simple arcade game.&lt;/p&gt;
&lt;p&gt;But first&amp;hellip;&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;the-users-guide-2nd-edition-now-available&#34;&gt;The User&amp;rsquo;s Guide, 2nd edition, now available&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/ug2.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/ug2.jpeg 640w, https://dansanderson.com/mega65/sprite-attack/ug2_hu_6e9d73461aaf5aa7.jpeg 600w, https://dansanderson.com/mega65/sprite-attack/ug2_hu_c4e5b81c0e72d41d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/ug2.jpeg&#34;
        alt=&#34;The MEGA65 User&amp;amp;#39;s Guide, 2nd edition&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The MEGA65 User&amp;rsquo;s Guide, 2nd edition.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You can now &lt;a href=&#34;https://www.lulu.com/shop/dan-sanderson-and-edilbert-kirk-and-paul-gardner-stephen/mega65-users-guide/paperback/product-dyrzzzy.html?page=1&amp;amp;pageSize=4&#34;&gt;buy a spiral-bound printed copy of the MEGA65 User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;This new edition has been updated substantially from the 1st edition printing from two years ago. It covers the upcoming v0.96 release, with instructions for new features like Ethernet file transfer, and revised information on important topics like upgrading the firmware and using disks. The BASIC reference has been updated with corrections, polish, and material on new features. And there are handy new appendices on screen codes and system colors.&lt;/p&gt;
&lt;p&gt;Whether you have the 1st edition and want to upgrade, or don&amp;rsquo;t yet have a MEGA65 and just want a useful book to go with Xemu, getting the 2nd edition in print is a great way to enhance your MEGA65 experience.&lt;/p&gt;
&lt;p&gt;I &lt;a href=&#34;https://files.mega65.org?ar=1c17f84a-2f10-4ad0-9168-6201331ece4b&#34;&gt;wrote a FAQ with more information&lt;/a&gt;, including what&amp;rsquo;s happening with the manuals bundled with new MEGA65s. Let me know if you have any questions.&lt;/p&gt;
&lt;h2 id=&#34;release-testing-update&#34;&gt;Release testing update&lt;/h2&gt;
&lt;p&gt;The v0.96 release package has been in public testing for a month, and we&amp;rsquo;ve been chasing down issues and polishing it up for factory installation on all of the new MEGA65s. This process should be complete a week or so after you read this. Many thanks to everyone who has contributed to the testing effort!&lt;/p&gt;
&lt;p&gt;What happens next: the v0.96 release package will be made official and sent to Trenz for the factory installation on new machines. It will be declared the new stable release for R3A and R6 mainboards, and made available on Filehost. Everyone with the &amp;ldquo;retail&amp;rdquo; MEGA65 will be encouraged to upgrade.&lt;/p&gt;
&lt;p&gt;DevKit and Nexys board owners will need to wait, just a bit. In order to meet the assembly schedule, we have had to defer preparing new cores for these boards until after this release. The plan is to immediately start work on these deferred tasks, and issue a v0.97 update within a couple of months that includes support for these boards. You&amp;rsquo;re always welcome to help test along the way, just be aware of known issues with slot 0 flashing on the older boards.&lt;/p&gt;
&lt;p&gt;Upgrade party at lydon&amp;rsquo;s place! 🎉&lt;/p&gt;
&lt;h2 id=&#34;new-intro-disks&#34;&gt;New Intro Disks!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/demo_title.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/demo_title.png 720w, https://dansanderson.com/mega65/sprite-attack/demo_title_hu_ec8375508bc9775b.png 600w, https://dansanderson.com/mega65/sprite-attack/demo_title_hu_643741ba6b987742.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/demo_title.png&#34;
        alt=&#34;The new Intro Disk main menu&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The new Intro Disk main menu&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Gurce has put a ton of work into preparing the new software bundle for the SD card that will ship with the new MEGAs. Current owners are familiar with the &amp;ldquo;Intro Disk&amp;rdquo; menu that starts when you first switch on the computer, as well as other bonus goodies that come on the pre-installed memory card. The new bundle includes all of that and &lt;em&gt;much&lt;/em&gt; more, a total of 191 (one hundred and ninety one!) menu entries. And that&amp;rsquo;s not even counting the disk menus themselves, with useful information and musical accompaniment. This compilation starts all new MEGA65 owners off with plenty to do on their first day. Huge thanks to Gurce for his meticulous work on this project, and of course to everyone who has written software for the MEGA65.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&#34;https://files.mega65.org?id=all-intros-public&#34;&gt;download the new software bundle on Filehost&lt;/a&gt;. (There&amp;rsquo;s &lt;a href=&#34;https://files.mega65.org?id=all-intros&#34;&gt;a separate download for registered owners&lt;/a&gt; with a more complete version of GEOS.) If you don&amp;rsquo;t yet have a MEGA65, you can try it out in &lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;Xemu&lt;/a&gt;—or save it as a surprise for when your MEGA65 arrives!&lt;/p&gt;
&lt;h2 id=&#34;new-on-filehost&#34;&gt;New on Filehost&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/rocket.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/rocket.png 701w, https://dansanderson.com/mega65/sprite-attack/rocket_hu_fa9db1c3464d8713.png 600w, https://dansanderson.com/mega65/sprite-attack/rocket_hu_c5422776f928e028.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/rocket.png&#34;
        alt=&#34;Rocket Delivery Service, by fredrikr&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Rocket Delivery Service, by fredrikr&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Don&amp;rsquo;t miss these new titles on Filehost:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=f051e4eb-c4f6-4831-968c-90e95ff39c53&#34;&gt;Rocket Delivery Service, by fredrikr&lt;/a&gt;, a new game for one or two players. Navigate your rocket man to pick up and deliver packages, for cash! Each player can use a joystick, or player one can use the keyboard while player two uses a joystick. Written entirely in BASIC!&lt;/p&gt;
&lt;p&gt;MJoergen and sy2002 are updating their vintage platform cores for use on the new R6 mainboard. &lt;a href=&#34;https://files.mega65.org?id=bdaeb7e0-9fc8-4185-99de-104d01229f27&#34;&gt;The ZX Spectrum core v1.2&lt;/a&gt; is now available, and there is &lt;a href=&#34;https://discord.com/channels/719326990221574164/801767398675316756/1200389851783114784&#34;&gt;a beta test version of the C64 core v5.1&lt;/a&gt; (link goes to Discord) to be released soon. The C64 core update also includes a few fixes for all mainboards, and support for using the MEGA65&amp;rsquo;s Real-Time Clock with the Commodore 64 version of GEOS.&lt;/p&gt;
&lt;p&gt;muse has yet another arcade core, and he keeps picking my favorites! &lt;a href=&#34;https://files.mega65.org?id=e2ee129d-149c-4b59-9ced-d21185878091&#34;&gt;Elevator Action&lt;/a&gt; (1983), a spy thriller set in a multi-level top secret facility. Infiltrate the building from the roof, avoid the armed goons, collect the secret files, and escape through the parking garage. As with the other arcade cores, you must locate the arcade ROMs yourself, so be sure to &lt;a href=&#34;https://github.com/sho3string/ElevatorActionMEGA65&#34;&gt;follow the installation instructions&lt;/a&gt;. Hold the button to jump.&lt;/p&gt;
&lt;p&gt;Amiga fans: geehaf has published &lt;a href=&#34;https://files.mega65.org?id=00fab7dc-0dd1-4a43-b3e9-a904ee09e110&#34;&gt;an ADF disk image utility&lt;/a&gt; that can use the MEGA65&amp;rsquo;s physical floppy drive to make Amiga disks from ADF files, and vice versa. This is a beta release of the tool, so take care to back up important data.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;exploring-sprites&#34;&gt;Exploring sprites&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/balloon.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/balloon.png 285w, https://dansanderson.com/mega65/sprite-attack/balloon_hu_7243ab4c69cfde7f.png 600w, https://dansanderson.com/mega65/sprite-attack/balloon_hu_f543e09e3fb9c238.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/balloon.png&#34;
        alt=&#34;The balloon example sprite, from the Commodore 64 Users Guide&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The balloon example sprite, from the Commodore 64 Users Guide.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The hardware sprites of the VIC-II chip should be familiar to anyone who has written a program for the Commodore 64. The Commodore 64 Users Guide that came with the machine included &lt;a href=&#34;https://www.commodore.ca/manuals/c64_users_guide/c64-users_guide-06-sprite_graphics.pdf&#34;&gt;a chapter on sprite graphics&lt;/a&gt; with a type-in demo. C64 programmers may also remember drawing out pictures on graph paper, hand-coding them into decimal numbers, typing them into &lt;code&gt;DATA&lt;/code&gt; statements, and messing about with dozens of arcane &lt;code&gt;POKE&lt;/code&gt; statements. In later computers and later versions of BASIC, Commodore added a BASIC sprite subsystem with access to most of the VIC-II&amp;rsquo;s sprite features, driven by a new set of commands. No &lt;code&gt;POKE&lt;/code&gt;-ing necessary.&lt;/p&gt;
&lt;p&gt;From here on, when I say &amp;ldquo;sprites,&amp;rdquo; I&amp;rsquo;m referring to the built-in sprite features of the VIC-II chip that have carried forward from the Commodore 64 to the MEGA65. Experienced game programmers would want me to point out that the general term &amp;ldquo;sprite&amp;rdquo; could apply to any kind of moveable graphics object, and there are, in fact, other ways to accomplish sprite-like effects on the MEGA65. We&amp;rsquo;ll have to cover those in later issues of the Digest.&lt;/p&gt;
&lt;p&gt;The best way to get to know Commodore sprites is to try out the commands! The new v0.96 release version of the MEGA65 ROM includes pre-defined sprite images for a mouse pointer and a simple line pattern, so you can get started without drawing any graphics. If you&amp;rsquo;re using the previous release, you can still switch on the sprites, you&amp;rsquo;ll just see a blob of pixels that represents uninitialized memory contents.&lt;/p&gt;
&lt;h3 id=&#34;getting-a-sprite-onto-the-screen&#34;&gt;Getting a sprite onto the screen&lt;/h3&gt;
&lt;p&gt;The VIC chip can keep track of up to eight sprites at a time, numbered 0 through 7. Each sprite has a set of modes and flags, including a flag to enable or disable the sprite. You manage these flags with the &lt;code&gt;SPRITE&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;To turn on sprite 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRITE 0,1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nothing appears to happen because the sprite starts located off the screen. Let&amp;rsquo;s move it roughly to the middle of the screen so we can see it (X=160, Y=120):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MOVSPR 0,160,120&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While many of BASIC 65&amp;rsquo;s sprite commands originate with BASIC 7 and the Commodore 128, there are subtle differences. For example, on the C128, sprites are numbered 1 through 8. I won&amp;rsquo;t describe every difference here, just be aware that they&amp;rsquo;re not exactly the same on both computers.&lt;/p&gt;
&lt;h3 id=&#34;pixels-and-colors&#34;&gt;Pixels and colors&lt;/h3&gt;
&lt;p&gt;In the default sprite mode (sometimes called &amp;ldquo;high resolution&amp;rdquo; mode), each sprite is 24 pixels wide and 21 pixels high, using a single sprite-assignable color for each &amp;ldquo;on&amp;rdquo; pixel (bit 1) and treating each &amp;ldquo;off&amp;rdquo; pixel (bit 0) as transparent. This is encoded as three bytes per row (8 bits per byte x 3 bytes = 24 pixels), for a total of 63 bytes (21 rows x 3 bytes per row) per sprite image.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/sprite_mono.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/sprite_mono.png 549w, https://dansanderson.com/mega65/sprite-attack/sprite_mono_hu_d4506e37fb579ef0.png 600w, https://dansanderson.com/mega65/sprite-attack/sprite_mono_hu_3b2ed1b539862a3c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/sprite_mono.png&#34;
        alt=&#34;A sprite, 24 x 21 monochrome, and its encoded image data&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A VIC-II sprite, 24 x 21, monochrome. Each of the eight sprites can use its own color for the pixels.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You can set the color of a sprite with the &lt;code&gt;SPRITE&lt;/code&gt; command. You can omit any argument you don&amp;rsquo;t want to change by specifying just a comma. The color value refers to the palette entry, in this case the default system palette. To turn sprite 0 red (palette entry 2):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRITE 0,,2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the MEGA65, you can change the system palette using the &lt;code&gt;PALETTE COLOR&lt;/code&gt; command. Each palette entry can be any of 4096 possible colors, with a red, green, and blue component each between 0 and 15. This changes the palette entry for &lt;em&gt;all&lt;/em&gt; uses of the color on the screen, not just sprites. To replace the red color at entry 2 with a bright green:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PALETTE COLOR 2,12,15,4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To restore the default palette:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PALETTE RESTORE&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;multicolor-mode&#34;&gt;Multicolor mode&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re willing to use a lower sprite resolution of 12 double-wide pixels per row instead of 24 single-wide pixels, you can set a sprite to multi-color mode, for two more additional colors. The two new colors must be shared by all sprites that are in multi-color mode. In this mode, sprite pixels are encoded as bit pairs: 00 for transparent, 10 for the sprite color, and 01 and 11 for the two shared colors.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/sprite_multicol.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/sprite_multicol.png 551w, https://dansanderson.com/mega65/sprite-attack/sprite_multicol_hu_9ef585219d41ac4.png 600w, https://dansanderson.com/mega65/sprite-attack/sprite_multicol_hu_8e55acd8e02db6fc.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/sprite_multicol.png&#34;
        alt=&#34;A sprite, 12 x 21 multicolor, and its encoded image data&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A VIC-II sprite, 12 x 21, multicolor. The colors of the hat and scarf must be shared across all eight sprites.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Let&amp;rsquo;s try setting sprite 0 to multi-color mode, using a value of 1 for the seventh argument to &lt;code&gt;SPRITE&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRITE 0,,,,,,1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&amp;rsquo;re using a ROM beta version, the default mouse pointer image of sprite 0 might not look that impressive in multi-color mode. Try enabling sprite 1 and moving it to the middle of the screen, then put it in multicolor mode. The default image of sprite 1 is designed to illustrate multicolor mode, with a repeating pattern of 00, 01, 10, and 11 bit pairs. (If you&amp;rsquo;re using release v0.95&amp;rsquo;s ROM 920377 or earlier, you&amp;rsquo;re in luck: the garbage data that&amp;rsquo;s usually there typically has an interesting combination of bit pairs.)&lt;/p&gt;
&lt;p&gt;To set the two shared colors for the multicolor sprites, use the &lt;code&gt;SPRCOLOR&lt;/code&gt; command, with the two palette entry numbers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRCOLOR 4,5&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;double-width-double-height&#34;&gt;Double width, double height&lt;/h3&gt;
&lt;p&gt;Each sprite can be displayed normal size, double width, double height, or both double width and double height. The double modes don&amp;rsquo;t give you more pixels: instead, they stretch the existing sprite design in the requested dimension.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/sprite_stretch.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/sprite_stretch.png 545w, https://dansanderson.com/mega65/sprite-attack/sprite_stretch_hu_528c6466af5878c0.png 600w, https://dansanderson.com/mega65/sprite-attack/sprite_stretch_hu_ed46f2ccc9003414.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/sprite_stretch.png&#34;
        alt=&#34;A 24 x 21 monochrome sprite displayed normally, double-wide, double-height, and double-wide double-height&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A sprite displayed normally, double-wide, double-height, and double-wide double-height.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;These modes can be selected per sprite, and are the fifth and sixth arguments to the &lt;code&gt;SPRITE&lt;/code&gt; command, respectively. Try the combinations of 0 and 1 for these arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRITE 0,,,,1,1&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;sprite-priority&#34;&gt;Sprite priority&lt;/h3&gt;
&lt;p&gt;Each sprite can be set to appear above the character or bitmap layer, or below it. When above, you can see the character or bitmap through the sprite&amp;rsquo;s transparent pixels.&lt;/p&gt;
&lt;p&gt;Use the cursor keys to move the text cursor to where the sprite is on the screen, then type some characters underneath it. On a blank line, set the fourth argument to &lt;code&gt;SPRITE&lt;/code&gt; to 0 or 1, and see what happens:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRITE 0,,,1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When sprites overlap each other, lower numbered sprites are always in front of higher numbered sprites. This order cannot be changed. Use &lt;code&gt;SPRITE&lt;/code&gt; to make sure two sprites are active, then use &lt;code&gt;MOVSPR&lt;/code&gt; to locate them so that their images overlap.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRITE 1,1
MOVSPR 1,160,120&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Overlapping sprites is a common way to draw a high resolution graphics object using more than one color: just use more than one sprite to represent the object, and allow pixels of lower sprites to shine through the transparent pixels of upper sprites.&lt;/p&gt;
&lt;h3 id=&#34;location-location-location&#34;&gt;Location, location, location&lt;/h3&gt;
&lt;p&gt;A sprite can be located at any pixel location on the screen. A sprite&amp;rsquo;s location is specified as coordinates on the screen, where the sprite&amp;rsquo;s top-left corner is placed at that location. Coordinates extend to locations under the screen border, and a sprite that overlaps the border will be obscured. This allows a sprite to glide off the screen smoothly until it disappears. (Note that double-width sprites won&amp;rsquo;t fit completely under the left border.)&lt;/p&gt;
&lt;p&gt;To place a sprite exactly in the top-left corner of the screen just inside the border, set its coordinates to X=24 Y=50. If a sprite is in its normal display mode (with its double-width double-height features turned off), you can place the sprite&amp;rsquo;s bottom-right corner exactly at the bottom-right corner of the screen with coordinates X=321 Y=229.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/spriteloc.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/spriteloc.png 676w, https://dansanderson.com/mega65/sprite-attack/spriteloc_hu_c7c70052652828ee.png 600w, https://dansanderson.com/mega65/sprite-attack/spriteloc_hu_35272a12008fa985.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/spriteloc.png&#34;
        alt=&#34;The VIC-II sprite coordinate system&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The VIC-II sprite coordinate system
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The VIC-II sprite coordinate system is independent of the resolution of the underlying screen mode. The MEGA65&amp;rsquo;s default 80-column text screen is actually 640 pixels wide. VIC-II sprite coordinates refer to the same locations regardless of the MEGA65 screen resolution. If you switch to the 40-column text mode, the sprites will remain where they are.&lt;/p&gt;
&lt;p&gt;Sprite coordinates are the same for both NTSC and PAL video modes. Even though these modes use different dimensions for the full screen, the dimensions inside the border are the same.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve already seen how the &lt;code&gt;MOVSPR&lt;/code&gt; command can set a sprite to specific coordinates. This command has several other useful features. To move a sprite to a relative distance from its current location, use a &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;-&lt;/code&gt; and an offset for the coordinate value (X, then Y):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MOVSPR 0,+20,-10&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;MOVSPR&lt;/code&gt; command can animate the movement of a sprite at a given speed. This animation happens &lt;em&gt;asynchronously&lt;/em&gt; to BASIC program execution, similar to the &lt;code&gt;PLAY&lt;/code&gt; command for music: the animation occurs in the background while the rest of your code continues to run. To move a sprite from one coordinate pair to another, use the &lt;code&gt;TO&lt;/code&gt; keyword, and provide a speed as a number of pixels per frame. Remember that PAL mode refreshes 50 frames per second, while NTSC mode refreshes 60 frames per second, so the movement speed differs based on video mode.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MOVSPR 0,100,100 TO 250,200,5&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the sprite needs to hit the end coordinate almost exactly for the sprite to stop. If the speed is not a multiple of the differences between the starting and ending coordinates, the sprite might overshoot its destination and wrap around the screen until it finally lands where it was told. If there&amp;rsquo;s a chance of this, you may need to resort to a loop that tests &lt;code&gt;RSPPOS()&lt;/code&gt; and stops the sprite with another &lt;code&gt;MOVSPR&lt;/code&gt; command when it is close enough.&lt;/p&gt;
&lt;p&gt;A sprite can be set to move continuously, with no fixed end coordinate. To do this, provide an angle as a number of degrees, with 0 degrees being &amp;ldquo;up&amp;rdquo; and proceeding clockwise, so 90 is right, 180 is down, and so forth. Follow this with a &lt;code&gt;#&lt;/code&gt; symbol and the speed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MOVSPR 0,135#1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The sprite will continue to move at this angle and speed until you set its speed to 0 with another &lt;code&gt;MOVSPR&lt;/code&gt; command, or until you switch it off with the &lt;code&gt;SPRITE&lt;/code&gt; command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MOVSPR 0,0#0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a moving sprite leaves the screen, it will continue to move until its position wraps around to the other side of the screen. If you want to test the position of the moving sprite, such as to stop its motion after it is off screen, use the &lt;code&gt;RSPPOS()&lt;/code&gt; function. This takes the sprite number, and an argument identifying the parameter to return: 0 for the X position, 1 for the Y position, 2 for the speed.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a short program that starts the sprite moving to the right, then stops it either when a key is pressed or the sprite leaves the screen:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SPRITE 0,1
20 MOVSPR 0,100,100
30 MOVSPR 0,90#1
40 GET A$
50 X=RSPPOS(0,0)
60 IF A$=&amp;#34;&amp;#34; AND X &amp;lt; 345 THEN 40
70 MOVSPR 0,0#0&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;collision-detection&#34;&gt;Collision detection&lt;/h3&gt;
&lt;p&gt;The VIC chip can report when two sprites have non-transparent pixels on top of each other, or on top of the character or bitmap layer. Your program can use this to detect &lt;em&gt;collisions&lt;/em&gt; between sprites, or between a sprite and the background, such as to know when a player&amp;rsquo;s bullet hits an alien ship, or when the player&amp;rsquo;s ship crashes into a mountain.&lt;/p&gt;
&lt;p&gt;BASIC 7 on the Commdoore 128 introduced an interesting mechanism for handling sprite collisions. To tell BASIC that you care about sprite collisions, you use the &lt;code&gt;COLLISION&lt;/code&gt; command to indicate the type of collision (1 = sprite on sprite, 2 = sprite on background), followed by a line number of your BASIC program. At some later point, when the VIC detects the requested collision type, BASIC will stop whatever it is doing and jump to the given line number as if it were a &lt;code&gt;GOSUB&lt;/code&gt; subroutine. Your code at this line number should do whatever it needs to do to react to the collision, then use the &lt;code&gt;RETURN&lt;/code&gt; command to resume where the program left off.&lt;/p&gt;
&lt;p&gt;Your handler subroutine is called for any collision of the requested type. Your code will need to use other tests to determine which collision took place. The &lt;code&gt;BUMP()&lt;/code&gt; function reports which sprites were involved in a collision since the last call to &lt;code&gt;BUMP()&lt;/code&gt;. You can also use the &lt;code&gt;RSPPOS()&lt;/code&gt; function to test individual sprite locations to further determine where the collision took place. See the User&amp;rsquo;s Guide for information on these functions.&lt;/p&gt;
&lt;p&gt;Try to guess what this program does, then type it in and run it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 SCNCLR
110 X=0
120 SPRITE 0,1
130 MOVSPR 0,100,100
140 MOVSPR 0,90#1
150 CURSOR 70,6
160 PRINT &amp;#34;XXX&amp;#34;
170 COLLISION 2,220
180 GET A$
190 IF A$=&amp;#34;&amp;#34; AND X=0 THEN 180
200 MOVSPR 0,0#0
210 END
220 PRINT &amp;#34;BLAMMO!&amp;#34;
230 X=1
240 RETURN&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The VIC&amp;rsquo;s built-in collision detection is not always the most reliable way to detect game events. Depending on the shapes of your sprites and other factors, you may prefer a different method to detect collisions, such as by testing sprite positions relative to a &lt;a href=&#34;https://www.pcgamer.com/how-hitboxes-work/&#34;&gt;hitbox&lt;/a&gt;. To do this, instead of a &lt;code&gt;COLLISION&lt;/code&gt; handler, you&amp;rsquo;d make repeated tests of &lt;code&gt;RSPPOS()&lt;/code&gt; in your game&amp;rsquo;s main loop.&lt;/p&gt;
&lt;p&gt;Another caveat: There is &lt;a href=&#34;https://github.com/MEGA65/mega65-core/issues/659&#34;&gt;a known issue&lt;/a&gt; with the VIC-IV core where sprite collisions are not detected with bitmap graphics (the BASIC 65 &lt;code&gt;SCREEN&lt;/code&gt; system). Collisions are limited to sprite-to-sprite and sprite-to-text for now. Of course, there&amp;rsquo;s quite a bit you can do graphically in text mode using PETSCII graphics, and custom character sets with the &lt;code&gt;CHARDEF&lt;/code&gt; command.&lt;/p&gt;
&lt;h3 id=&#34;other-sprite-features&#34;&gt;Other sprite features?&lt;/h3&gt;
&lt;p&gt;If you grew up with a Commodore 64, these sprite features probably feel quite familiar. The C128 sprite commands, and the C65 and MEGA65 additions, are handy, but the sprites themselves mostly look like they did on the VIC-II.&lt;/p&gt;
&lt;p&gt;For the VIC-III video chip in the Commodore 65, Commodore added no new features to sprites. Sprite colors use the VIC-III system palette, and you can adjust the colors of the system palette to any of 4096 possible colors. Otherwise, they&amp;rsquo;re basically the same as they&amp;rsquo;ve always been.&lt;/p&gt;
&lt;p&gt;The MEGA65&amp;rsquo;s VIC-IV adds advanced sprite features, such as a full-color mode with actual-size pixels, four palette banks, a 64-pixel width monochromatic mode, variable pixel height, and high resolution sprites that use the actual pixel width and coordinate system of a 640-wide (80-column) display. BASIC 65 does not yet support any of these features with the BASIC sprite commands. You can adjust VIC-IV registers directly with &lt;code&gt;POKE&lt;/code&gt; statements, but this may interfere with the behavior of the BASIC commands. I&amp;rsquo;m currently working to extend BASIC 65 with official support for VIC-IV sprite features, so stay tuned for updates!&lt;/p&gt;
&lt;h2 id=&#34;managing-sprite-image-data&#34;&gt;Managing sprite image data&lt;/h2&gt;
&lt;p&gt;Playing with the built-in sprites is fun and all, but for our own programs, we obviously want to draw our own sprite images.&lt;/p&gt;
&lt;h3 id=&#34;using-the-sprite-editor&#34;&gt;Using the Sprite Editor&lt;/h3&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/sprited.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/sprited.png 862w, https://dansanderson.com/mega65/sprite-attack/sprited_hu_826a80607aeab34.png 600w, https://dansanderson.com/mega65/sprite-attack/sprited_hu_c2892c5b95146040.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/sprited.png&#34;
        alt=&#34;SpritEd, the MEGA65 sprite editor&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
SpritEd, the MEGA65 sprite editor
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Did you know that the Commodore 128 has &lt;a href=&#34;https://www.c64-wiki.com/wiki/SPRDEF&#34;&gt;a built-in sprite editor&lt;/a&gt;? The C128&amp;rsquo;s &lt;code&gt;SPRDEF&lt;/code&gt; command opens a sprite editor that directly manipulates the BASIC sprite image data in memory. For whatever reason, Commodore removed &lt;code&gt;SPRDEF&lt;/code&gt; for BASIC 10. The good news is, the MEGA65 has its own sprite editor, &amp;ldquo;SpritEd,&amp;rdquo; built into the Freezer.&lt;/p&gt;
&lt;p&gt;Hold &lt;kbd&gt;Restore&lt;/kbd&gt; for one second then release to open the Freezer, then press &lt;kbd&gt;S&lt;/kbd&gt; to start the sprite editor. This utility edits sprite image data at the BASIC sprite locations in memory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A word of warning.&lt;/strong&gt; SpritEd is currently unfinished software. Up to platform release v0.95, SpritEd crashes the machine if you press the &lt;kbd&gt;Up Arrow&lt;/kbd&gt; key. I discovered this while writing this article, and I committed a fix to prevent this that will be in release v0.96. I recommend upgrading to release v0.96 before doing any serious work in SpritEd.&lt;/p&gt;
&lt;p&gt;SpritEd is missing a bunch of its intended features, such as the ability to load and save images to disk. Even without these features, it is about as useful as the C128&amp;rsquo;s &lt;code&gt;SPRDEF&lt;/code&gt; tool, and can edit sprite image data in memory. We&amp;rsquo;ll see how to get sprite image data from memory into your program in the next section.&lt;/p&gt;
&lt;p&gt;Press the &lt;kbd&gt;Help&lt;/kbd&gt; key for a list of keyboard controls. Briefly, these are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To select a drawing tool: &lt;kbd&gt;P&lt;/kbd&gt; for single pixels, &lt;kbd&gt;L&lt;/kbd&gt; for a line, &lt;kbd&gt;X&lt;/kbd&gt; for a box, &lt;kbd&gt;Shift-X&lt;/kbd&gt; for a filled box.&lt;/li&gt;
&lt;li&gt;Press &lt;kbd&gt;Space&lt;/kbd&gt; to draw with the selected tool. &lt;kbd&gt;Del&lt;/kbd&gt; uses the tool with the background component, such as to erase a pixel.&lt;/li&gt;
&lt;li&gt;To erase the entire sprite: &lt;kbd&gt;Ctrl+N&lt;/kbd&gt;.&lt;/li&gt;
&lt;li&gt;To select a &amp;ldquo;component&amp;rdquo; (color) to draw with: &lt;kbd&gt;+&lt;/kbd&gt; and &lt;kbd&gt;-&lt;/kbd&gt; rotate through the choices. In monochrome mode, this is just the background (transparent) and foreground. In VIC-II double-width multi-color mode, there are two additional components for the shared sprite colors.&lt;/li&gt;
&lt;li&gt;To change the color of the currently selected component: &lt;kbd&gt;0&lt;/kbd&gt; through &lt;kbd&gt;9&lt;/kbd&gt;, &lt;kbd&gt;A&lt;/kbd&gt; through &lt;kbd&gt;F&lt;/kbd&gt; assigns one of the sixteen palette entries to the component.&lt;/li&gt;
&lt;li&gt;To select other sprites: comma (&lt;kbd&gt;,&lt;/kbd&gt;) and period (&lt;kbd&gt;.&lt;/kbd&gt;) rotate through the eight sprites.&lt;/li&gt;
&lt;li&gt;To change the sprite mode: &lt;kbd&gt;*&lt;/kbd&gt; rotates through monochrome, VIC-II multicolor, and VIC-IV multicolor modes. Remember that BASIC does not yet support VIC-IV multicolor mode directly, so this last mode won&amp;rsquo;t be useful until we finish the new features.&lt;/li&gt;
&lt;li&gt;To see what your sprite looks like when expanded horizontally or vertically: use &lt;kbd&gt;H&lt;/kbd&gt; and &lt;kbd&gt;V&lt;/kbd&gt; to toggle these modes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SpritEd supports drawing with a mouse connected to port 1. I discovered &lt;a href=&#34;https://github.com/MEGA65/mega65-freezemenu/issues/75&#34;&gt;a small bug&lt;/a&gt; where the mouse can&amp;rsquo;t draw in the rightmost column, which should be easy to fix in a future version.&lt;/p&gt;
&lt;p&gt;To exit SpritEd, press &lt;kbd&gt;F11&lt;/kbd&gt; to make sure the current sprite is saved to memory, then press &lt;kbd&gt;F3&lt;/kbd&gt; to exit back to the Freezer menu. Each sprite image is saved to memory automatically when you flip between the sprites, so &lt;kbd&gt;F11&lt;/kbd&gt; is only necessary on the current sprite, if it was modified. (That feels like something else we can improve pretty easily. Just know that&amp;rsquo;s how it works for now.)&lt;/p&gt;
&lt;h3 id=&#34;storing-sprite-image-data-on-disk&#34;&gt;Storing sprite image data on disk&lt;/h3&gt;
&lt;p&gt;The gorgeous sprite graphics we created in SpritEd are now in memory, but they&amp;rsquo;ll disappear forever if we don&amp;rsquo;t get them out of memory and onto disk. BASIC 65 makes this easy: &lt;code&gt;SPRITE SAVE &amp;quot;filename&amp;quot;&lt;/code&gt; saves all eight sprite images to a file on disk. &lt;code&gt;SPRITE LOAD &amp;quot;filename&amp;quot;&lt;/code&gt; loads them back in.&lt;/p&gt;
&lt;p&gt;This provides a &lt;code&gt;POKE&lt;/code&gt;-free workflow for managing sprites for BASIC programs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create sprite images in the SpritEd utility. Press &lt;kbd&gt;F11&lt;/kbd&gt;, then &lt;kbd&gt;F3&lt;/kbd&gt; to exit back to the Freezer menu, then &lt;kbd&gt;F3&lt;/kbd&gt; again to resume BASIC.&lt;/li&gt;
&lt;li&gt;Execute the &lt;code&gt;SPRITE SAVE &amp;quot;filename&amp;quot;&lt;/code&gt; command to save all eight sprite images to a file.&lt;/li&gt;
&lt;li&gt;Then in the program, use the &lt;code&gt;SPRITE LOAD &amp;quot;filename&amp;quot;&lt;/code&gt; command to load these images.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;animating-sprite-images&#34;&gt;Animating sprite images&lt;/h3&gt;
&lt;p&gt;For a game like Space Invaders, a ship can be a single sprite image whose only animation is to move around the screen, such as with the &lt;code&gt;MOVSPR&lt;/code&gt; command. For a game like Pac Man, the player sprite should open and close its mouth, which means updating the sprite&amp;rsquo;s image data. We can&amp;rsquo;t exactly load a new Pac Man from disk each time he opens and closes his mouth, so we need another way to update sprite data within the program.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;SPRSAV&lt;/code&gt; command copies sprite data between sprite slots and BASIC string variables. It takes two arguments: the source and the destination. One or both of these can be a number between 0 and 7 to refer to the sprite image. If the other is a named string variable, the variable is used as either the source or destination.&lt;/p&gt;
&lt;p&gt;For example, to copy the image data from sprite 2 to the string variable &lt;code&gt;C$&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRSAV 2,C$&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To copy that image to sprite 5:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SPRSAV C$,5&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Combined with &lt;code&gt;SPRITE LOAD&lt;/code&gt;, you can use &lt;code&gt;SPRSAV&lt;/code&gt; to load all of your sprite patterns into string variables, then store them back into sprite slots during game play as needed.&lt;/p&gt;
&lt;p&gt;You can also use string variables and &lt;code&gt;SPRSAV&lt;/code&gt; along with disk operations as an alternative to &lt;code&gt;SPRITE LOAD&lt;/code&gt;. For example, you can store more than eight patterns in a single file. Each pattern is 64 bytes in length. See any good reference on disk commands for more information.&lt;/p&gt;
&lt;h2 id=&#34;putting-it-together&#34;&gt;Putting it together&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sprite-attack/spriteattack_set.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sprite-attack/spriteattack_set.png 550w, https://dansanderson.com/mega65/sprite-attack/spriteattack_set_hu_3f7b5fc1c3a9e4aa.png 600w, https://dansanderson.com/mega65/sprite-attack/spriteattack_set_hu_4784ecab69059a22.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sprite-attack/spriteattack_set.png&#34;
        alt=&#34;Sprite Attack sprite set&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Sprite Attack sprite set.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;Sprite Attack&lt;/em&gt; is a simple game I wrote to demonstrate how the sprite features can be used together. Get it here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sprite Attack: &lt;a href=&#34;spratk.d81&#34;&gt;spratk.d81&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Try it out with a joystick in port 2. It&amp;rsquo;s written entirely in BASIC, so type &lt;code&gt;LIST&lt;/code&gt; to see the program listing. A few notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I used SpritEd to draw eight multicolor sprites: the player&amp;rsquo;s spaceship, the player missiles, the space alien death ray, four frames of an explosion animation, and the space alien itself. I exited SpritEd and the Freezer, then used the command &lt;code&gt;SPRITE SAVE &amp;quot;SPRATK.DAT&amp;quot;&lt;/code&gt; to save the sprite data to disk. The program starts by loading this file with &lt;code&gt;SPRITE LOAD&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I keep the player&amp;rsquo;s X position in a variable so I can fine-tune the speed that the player moves. Pixel locations are always integers, but sometimes you want a sprite to move in non-integer increments, such as 1.8 pixels per frame. The variable holds the non-integer location, and this value is rounded to the nearest pixel when I pass it to the &lt;code&gt;MOVSPR&lt;/code&gt; command.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The game loop tests for joystick movement, adjusts the variable, and updates the player location with &lt;code&gt;MOVSPR&lt;/code&gt;. Because the player only moves left and right, I use &lt;code&gt;+0&lt;/code&gt; as the Y coordinate argument to &lt;code&gt;MOVSPR&lt;/code&gt; so that I don&amp;rsquo;t have to remember the ship&amp;rsquo;s vertical position after initializing it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I use the &lt;code&gt;VSYNC&lt;/code&gt; command to synchronize gameplay with the frame rate. This makes it easier to tune the movement speeds, and it prevents the sprites from &amp;ldquo;tearing&amp;rdquo; by making sure the location doesn&amp;rsquo;t change while the sprite is being drawn.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Player missiles use the movement animation system. The &lt;code&gt;RSPPOS()&lt;/code&gt; with a second argument of &lt;code&gt;2&lt;/code&gt; returns the current speed of a sprite, so I can test whether the missiles are moving. If the button is pressed and the missiles aren&amp;rsquo;t moving, I set their position to just above the player ship and set them moving in an upward motion, then I activate the missiles sprite. I also test once per loop if the missiles have gone off the top of the screen, and if so, I stop their motion by setting their speed to zero.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The alien also uses movement animation. If the space alien is ever stationary (speed is 0), the program chooses a new random location, and calls &lt;code&gt;MOVSPR&lt;/code&gt; with the current location as the origin and the random location as the destination. This gives the alien an evasive behavior that still gives the player a chance to target it with missiles.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A collision handler detects when the missiles are in contact with the alien. When the alien is hit, the routine moves the explosion sprite to the alien&amp;rsquo;s location, disables the missiles sprite, then moves the alien sprite to another random starting point above the screen. It plays out the explosion animation using &lt;code&gt;SPRSAV&lt;/code&gt; to copy in the explosion patterns we saved into string variables earlier, pausing between each frame. This causes all gameplay to pause while the explosion finishes. A more sophisticated game would handle explosion animations in the main game loop, so other events like player movement can take place during the animation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This game is a little unfair—to the alien. Try extending this program to have the alien shoot back at the player, using its death ray in sprite 2.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;VIC hardware sprites and the BASIC 65 sprite commands are a fun and easy way to code video game graphics. Combine them with PETSCII graphics to draw level maps, backgrounds, and informational displays, and you have all of the elements of a great looking game. Be sure to share your games with other MEGA65 owners by uploading them to &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;There are some advanced sprite techniques I wanted to mention here, but they&amp;rsquo;ll have to wait for another issue. You can help make more issues possible by &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;supporting the Digest on Ko-Fi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As always, happy coding!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/sprite-attack/M65Digest_2024Feb.mp3" length="38805336" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1940</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/sprite-attack/s1.png"/>
      
    </item>
    
    <item>
      <title>The New Hotness</title>
      <link>https://dansanderson.com/mega65/new-hotness/</link>
      <pubDate>Mon, 15 Jan 2024 00:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/new-hotness/</guid>
      <description>&lt;p&gt;The New Hotness. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for January 2024.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;The New Hotness. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for January 2024.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/new-hotness/M65Digest_2024January.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/new-hotness/M65Digest_2024January.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
The New Hotness.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/new-hotness/available.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/new-hotness/available.png 2534w, https://dansanderson.com/mega65/new-hotness/available_hu_c9d940cde0316d3d.png 600w, https://dansanderson.com/mega65/new-hotness/available_hu_984c711397fb768.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/new-hotness/available.png&#34;
        alt=&#34;Trenz Electronic&amp;amp;#39;s estimate for MEGA65 in-stock availability is June 14th, 2024. Preorders ship June 1st.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Trenz Electronic expects the MEGA65 to be in stock by June 12th, 2024. Preorders ship June 1st.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s time! We have a shipping schedule for the next batch of MEGA65 computers, and a candidate for the next platform release. Everyone is invited to help with testing, so let&amp;rsquo;s get to it!&lt;/p&gt;
&lt;h2 id=&#34;shipping-update&#34;&gt;Shipping update!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/new-hotness/mega65_box_01.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/new-hotness/mega65_box_01.jpg 1920w, https://dansanderson.com/mega65/new-hotness/mega65_box_01_hu_7c6131d12b5a0759.jpg 600w, https://dansanderson.com/mega65/new-hotness/mega65_box_01_hu_8c5a7e3793371e78.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/new-hotness/mega65_box_01.jpg&#34;
        alt=&#34;The MEGA65 retail packaging box&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 retail packaging box. Your MEGA65 will ship with an outer box, with this inside it.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Trenz Electronic has announced that the next batch of MEGA65 computers will ship on &lt;strong&gt;June 1st, 2024.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We currently expect that &lt;em&gt;all&lt;/em&gt; preorders up to this point will be included in this batch. If you need to make adjustments to your preorder before then, &lt;a href=&#34;mailto:sales@trenz-electronic.de&#34;&gt;contact sales@trenz-electronic.de&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once we clear the preorders, remaining stock will become &lt;a href=&#34;https://shop.trenz-electronic.de/en/TE0765-06-T001CK-MEGA65-highly-advanced-C64-and-C65-compatible-8-bit-computer?c=564&#34;&gt;available for purchase in the Trenz Electronic store&lt;/a&gt;, while supplies last.&lt;/p&gt;
&lt;p&gt;Please bear with us while we work through any last minute issues that might change these estimates. And thank you so much for your patience! I can&amp;rsquo;t wait for you to receive your MEGA65!&lt;/p&gt;
&lt;h2 id=&#34;v096-release-candidate-now-available-to-test&#34;&gt;v0.96 release candidate now available to test!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/new-hotness/flashing.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/new-hotness/flashing.jpeg 640w, https://dansanderson.com/mega65/new-hotness/flashing_hu_d90f8ae1df89c790.jpeg 600w, https://dansanderson.com/mega65/new-hotness/flashing_hu_2290ef5952ec6640.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/new-hotness/flashing.jpeg&#34;
        alt=&#34;Flashing a new MEGA65 core&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Installing the new release candidate core.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To make the new delivery schedule, we need to hand over the gold masters of the next release of the MEGA65 firmware and system software, as well as the updated &lt;em&gt;User&amp;rsquo;s Guide,&lt;/em&gt; to Trenz Electronic by January 31st. Release v0.96 of the firmware, ROM, and system software will be installed at the factory on all MEGA65s about to ship. Of course, it will also be available as a free upgrade for all existing MEGA65s. This next release has a ton of new features and bug fixes—and we need testers!&lt;/p&gt;
&lt;p&gt;If you have a MEGA65, you can install the release candidate on your machine to help test. If you don&amp;rsquo;t have a MEGA65 yet, you can still help by testing the new version of the ROM with an updated version of the Xemu emulator.&lt;/p&gt;
&lt;h3 id=&#34;testing-the-release-candidate-on-a-mega65&#34;&gt;Testing the release candidate on a MEGA65&lt;/h3&gt;
&lt;p&gt;To begin, be sure to back up your SD card, or use an alternate SD card, before proceeding with testing. I usually just move the SD card to my PC, then copy all of the files from the SD card into a folder on my desktop. This doesn&amp;rsquo;t back up the configuration or Freeze states, but personally I don&amp;rsquo;t keep important freeze states around long term. Alternatively, you could also use a disk imaging utility to back up both the hidden configuration partition and the files partition.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re using a fresh SD card for testing, remember to prepare the card first using the MEGA65&amp;rsquo;s SD Card Utility. Insert the card in your MEGA65, hold the &lt;kbd&gt;Alt&lt;/kbd&gt; key while switching on the computer, then select the utility from the menu and follow the prompts. This erases all data on the card.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how to get the files for the release candidate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://builder.mega65.org/job/mega65-core/job/release-0.96/&#34;&gt;Release v0.96 RC core and system software&lt;/a&gt;. Select the latest build that begins with &lt;code&gt;mega65r3-r-0.96&lt;/code&gt;, such as &lt;code&gt;mega65r3-r-0.96-build-5.7z&lt;/code&gt;. The &amp;ldquo;r3&amp;rdquo; refers to all MEGA65s delivered up to this point. The MEGA65s shipping in June will be known as &amp;ldquo;r6.&amp;rdquo; Yes, we&amp;rsquo;re skipping R5 after all: we found one small non-electrical change needed for the board during R5 testing.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=mega65-rom-beta&#34;&gt;Release v0.96 RC ROM&lt;/a&gt;. Sign in with your Filehost account with your owner code redeemed to access this. Download the most recent version: &lt;code&gt;920391.bin&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;MEGA65 command line tools: &lt;a href=&#34;https://files.mega65.org?id=658322fd-e586-4b4f-a991-89470b269b4a&#34;&gt;Windows&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=7d96641c-b306-49cf-80ff-ea1e5d00c9d1&#34;&gt;Mac&lt;/a&gt;, or &lt;a href=&#34;https://files.mega65.org?id=2b7bd912-1181-447c-a489-223f16b764c1&#34;&gt;Linux&lt;/a&gt;. These will be bundled with, and be the basis for, an upcoming version of the M65Connect app, and are generally useful on their own for the new Ethernet file transfer feature.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://builder.mega65.org/job/mega65-user-guide/job/master/lastSuccessfulBuild/artifact/mega65-userguide.pdf&#34;&gt;The MEGA65 User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt; (PDF).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unpack the &lt;code&gt;mega65r3-r-0.96-build-5.7z&lt;/code&gt; archive. Transfer the &lt;code&gt;.cor&lt;/code&gt; file to the root of your SD card. Open the &lt;code&gt;sdcard-files&lt;/code&gt; folder, and copy its contents (&lt;code&gt;.M65&lt;/code&gt; files) to the root of the SD card as well.&lt;/p&gt;
&lt;p&gt;Rename &lt;code&gt;920391.bin&lt;/code&gt; to &lt;code&gt;mega65.rom&lt;/code&gt;, and transfer it to the root of your SD card.&lt;/p&gt;
&lt;p&gt;Install the SD card in your MEGA65. With the power switched off, hold &lt;kbd&gt;No Scroll&lt;/kbd&gt; then switch on the computer. This opens the core selection menu. Hold the &lt;kbd&gt;Ctrl&lt;/kbd&gt; key and press a number to select an appropriate core slot for the new core, then follow the prompts to select the &lt;code&gt;.cor&lt;/code&gt; file and flash the core. See the &lt;em&gt;User&amp;rsquo;s Guide&lt;/em&gt; for more information about upgrading cores.&lt;/p&gt;
&lt;h3 id=&#34;using-both-the-release-candidate-and-the-previous-stable-release-with-one-mega65&#34;&gt;Using both the release candidate and the previous stable release with one MEGA65&lt;/h3&gt;
&lt;p&gt;I recommend keeping both the release candidate and the previous stable release installed during testing. If you find any issues with the release candidate, it will be important to determine if those issues also exist with the previous stable release, or if they are new issues introduced by a recent change.&lt;/p&gt;
&lt;p&gt;Choose one or the other to be the default for your computer. Flash the core you wish to be the default to core slot 1, and name the default ROM as &lt;code&gt;mega65.rom&lt;/code&gt; on the SD card. For the non-default release, flash the core to slot 2, and name the ROM file as &lt;code&gt;mega652.rom&lt;/code&gt;. To start the non-default release (whichever one you chose), hold &lt;kbd&gt;No Scroll&lt;/kbd&gt; while switching on the computer to open the core selection menu, then press &lt;em&gt;and hold&lt;/em&gt; the number &lt;kbd&gt;2&lt;/kbd&gt; until you see the &lt;code&gt;READY.&lt;/code&gt; prompt (and probably a bunch of 2&amp;rsquo;s). This selects core slot 2 and also selects &lt;code&gt;mega652.rom&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s one tricky bit with a dual installation: you can only have one set of system software on the SD card. I have not had any issues running the new system software with the previous stable core and ROM, so my recommendation is to go ahead and use the release candidate system software as the system files on your SD card.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important to note that the release candidate ROM only works with the release candidate core. If you accidentally select the release candidate ROM (version 920391) and the previous stable release core, typing won&amp;rsquo;t work correctly and you&amp;rsquo;ll see the cursor disappear. If this happens, switch off the computer, hold &lt;kbd&gt;No Scroll&lt;/kbd&gt; while switching it back on, then select a matching core and ROM. You can use the previous ROM (version 920377) with the new core, just not the other way around.&lt;/p&gt;
&lt;p&gt;You can confirm that you&amp;rsquo;re running the release that you intend with the new MEGAINFO utility. Open the Freezer—hold the &lt;kbd&gt;Restore&lt;/kbd&gt; key for a second, then release—then press the &lt;kbd&gt;Help&lt;/kbd&gt; key. This is a feature of the new system software, and it works with either release as long as the new release&amp;rsquo;s system software is on the SD card.&lt;/p&gt;
&lt;h3 id=&#34;testing-the-candidate-rom-in-xemu&#34;&gt;Testing the candidate ROM in Xemu&lt;/h3&gt;
&lt;p&gt;If you do not have a MEGA65, you can still help test the ROM in the Xemu emulator. Get these files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=mega65-rom-beta-diff&#34;&gt;Release v0.96 RC ROM patch&lt;/a&gt;. Follow the instructions in &lt;a href=&#34;https://files.mega65.org/html/main.php?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;the ROM FAQ&lt;/a&gt; to put together the MEGA65 ROM 920391 using the free C64 Forever download from Cloanto.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;Xemu &amp;ldquo;next&amp;rdquo; release&lt;/a&gt;. Look at the bottom of the page for &amp;ldquo;The &amp;lsquo;future next stable&amp;rsquo; still unstable (&amp;ldquo;next&amp;rdquo; branch) builds&amp;rdquo; for your platform. Download and install.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://builder.mega65.org/job/mega65-user-guide/job/master/lastSuccessfulBuild/artifact/mega65-userguide.pdf&#34;&gt;The MEGA65 User&amp;rsquo;s Guide, 2nd edition&lt;/a&gt; PDF.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Run xmega65, and when prompted for a ROM, use the new ROM.&lt;/p&gt;
&lt;p&gt;Just as the release candidate ROM (version 920391) depends on the release candidate core, it also depends on the &amp;ldquo;next&amp;rdquo; version of Xemu. If you try to use the new ROM with the previous stable version of Xemu, you will notice problems with typing.&lt;/p&gt;
&lt;h3 id=&#34;what-to-test&#34;&gt;What to test&lt;/h3&gt;
&lt;p&gt;This release is the culmination of 15 months of improvements and fixes across the board. Changes to the ROM are listed in &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/blob/main/CHANGELOG.md&#34;&gt;the ROM change log&lt;/a&gt;. Changes to the core are numerous and we&amp;rsquo;re still assembling &lt;a href=&#34;https://github.com/MEGA65/mega65-core/blob/release-0.96/release-build/Changelog.md&#34;&gt;the core change log&lt;/a&gt;, but here are a few notable features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ethernet file transfer.&lt;/strong&gt; See the updated User&amp;rsquo;s Guide or &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/29327361/Ethernet+tools+mega65+ftp+and+etherload&#34;&gt;this wiki page&lt;/a&gt; for instructions on how to transfer files between your PC and the MEGA65 using just an Ethernet cable. Notice that this requires flipping a small switch on the mainboard, so you will need to open your MEGA65&amp;rsquo;s case.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hardware accelerated typing.&lt;/strong&gt; You should notice that typing at the &lt;code&gt;READY.&lt;/code&gt; prompt and in most apps is more accurate, especially for fast typists. This should not affect MEGA65 software in any other way.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improvements to mouse handling,&lt;/strong&gt; with smoother motion and support for mouse and paddles in port 2.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Coming soon:&lt;/em&gt; &lt;strong&gt;New core flashing capabilities—and a way to flash slot 0.&lt;/strong&gt; The special core slot 0 controls aspects of the MEGA65 boot process, and it is intentionally more difficult to flash so you always have the factory-installed MEGA65 core available. With this release, there will be a new way to update the core in slot 0 to claim the benefits of improvements made to the boot process. &lt;em&gt;As of this writing, this feature is not yet in the release candidate.&lt;/em&gt; Stay tuned to the Discord for an announcement of when and how to test this.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Coming soon:&lt;/em&gt; &lt;strong&gt;Configurable cartridge booting.&lt;/strong&gt; Flashing this core to slot 0 enables the ability to configure the boot process to use a specific core when a type of Commodore cartridge is connected. This is primarily so you can assign C64 cartridges to the C64 core, instead of the less capable GO64 mode of the MEGA65 core and ROM. This change also introduces a new cartridge signature and boot protocol for MEGA65 cartridges, though you&amp;rsquo;ll need an EasyFlash 1CR cartridge and a test image to test it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to testing new features, we want to know about anything that worked in the last stable release and appears to have stopped working in the new release candidate (called &amp;ldquo;regressions&amp;rdquo; in software engineering parlance). This includes, but is not limited to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your favorite MEGA65 games, apps, and utilities&lt;/li&gt;
&lt;li&gt;BASIC commands and features&lt;/li&gt;
&lt;li&gt;The core menu, core flashing, configuration, &amp;ldquo;on-boarding,&amp;rdquo; and the SD card utility&lt;/li&gt;
&lt;li&gt;The Freezer, and features accessible from the Freezer menu&lt;/li&gt;
&lt;li&gt;Procedures and information described in the User&amp;rsquo;s Guide, 2nd edition&lt;/li&gt;
&lt;li&gt;Anything that worked in GO64 mode with the previous stable release&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;how-to-report-issues&#34;&gt;How to report issues&lt;/h3&gt;
&lt;p&gt;There are two ways to report any bugs you find. We have &lt;a href=&#34;https://discord.com/channels/719326990221574164/1196590643007463459&#34;&gt;an active thread on the Discord&lt;/a&gt; for collecting release candidate bugs. Look for the &lt;code&gt;platform-testing&lt;/code&gt; forum. Alternatively, you can file issues directly to the &lt;a href=&#34;https://github.com/MEGA65/mega65-core/issues&#34;&gt;Github repo for the core&lt;/a&gt;, the &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues&#34;&gt;repo for the ROM&lt;/a&gt;, or &lt;a href=&#34;https://github.com/MEGA65/mega65-user-guide/issues&#34;&gt;the repo for the User&amp;rsquo;s Guide&lt;/a&gt;. If you&amp;rsquo;re not sure where the bug goes, file it in the core repo, and we&amp;rsquo;ll triage.&lt;/p&gt;
&lt;p&gt;If you find something that doesn&amp;rsquo;t look right, try to reproduce it in the previous release. File a bug either way, and make sure to note whether this only happens in the release candidate, or if it happens in both versions.&lt;/p&gt;
&lt;p&gt;Many thanks to everyone who is available to test! We&amp;rsquo;re on a tight schedule, so anything you can do before the end of January would be a huge help.&lt;/p&gt;
&lt;h2 id=&#34;about-that-users-guide&#34;&gt;About that User&amp;rsquo;s Guide&amp;hellip;&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/new-hotness/ug2.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/new-hotness/ug2.jpeg 640w, https://dansanderson.com/mega65/new-hotness/ug2_hu_6e9d73461aaf5aa7.jpeg 600w, https://dansanderson.com/mega65/new-hotness/ug2_hu_c4e5b81c0e72d41d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/new-hotness/ug2.jpeg&#34;
        alt=&#34;A test print of the MEGA65 User&amp;amp;#39;s Guide, 2nd edition&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A test print of the MEGA65 User&#39;s Guide, 2nd edition.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Every MEGA65 includes a printed version of the &lt;em&gt;MEGA65 User&amp;rsquo;s Guide,&lt;/em&gt; a book that includes set-up instructions, common procedures, an introduction to BASIC programming, and a BASIC command reference. We printed a large quantity of the 1st edition, and everyone who has received a MEGA65 so far has this edition. We can&amp;rsquo;t afford not to use the remaining stock, so we will be including copies of the 1st edition with some MEGA65s that will ship in June.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;User&amp;rsquo;s Guide&lt;/em&gt; has been revised with new material on new features like Ethernet file transfer, and a renewed focus on non-developer activities like using virtual disk images and upgrading the firmware. The entire Guide has been polished with corrections, and the BASIC reference has been updated to include the most recently added features. We&amp;rsquo;re calling this the &amp;ldquo;2nd edition,&amp;rdquo; and we will be printing new &lt;em&gt;Guides&lt;/em&gt; to include with MEGA65s after the stock of the 1st edition is depleted.&lt;/p&gt;
&lt;p&gt;Do you want a printed copy of the 2nd edition? I know I do! I&amp;rsquo;m working on setting up the &lt;em&gt;User&amp;rsquo;s Guide, 2nd edition&lt;/em&gt; with a print-on-demand service, so anyone who wants an updated printed &lt;em&gt;Guide&lt;/em&gt; can get one. Whether you have the 1st edition and want to upgrade, or you&amp;rsquo;re just enjoying Xemu and want a book to go with it, you&amp;rsquo;ll be able to order a copy.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll share the link to the purchase page in the next issue of this Digest. We&amp;rsquo;re using the release testing period to catch any last minute bugs in the Guide, and to make sure it matches the new slot 0 flashing procedure when it is finished. In the meantime, you can always download &lt;a href=&#34;https://builder.mega65.org/job/mega65-user-guide/job/master/lastSuccessfulBuild/artifact/mega65-userguide.pdf&#34;&gt;the latest draft PDF of The MEGA65 User&amp;rsquo;s Guide&lt;/a&gt;. (And &lt;a href=&#34;https://github.com/MEGA65/mega65-user-guide/issues&#34;&gt;report bugs&lt;/a&gt;!)&lt;/p&gt;
&lt;h2 id=&#34;the-8-bit-guy-and-me&#34;&gt;The 8-Bit Guy, and me!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/new-hotness/8bitguy.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/new-hotness/8bitguy.jpeg 1920w, https://dansanderson.com/mega65/new-hotness/8bitguy_hu_213ced235229db3d.jpeg 600w, https://dansanderson.com/mega65/new-hotness/8bitguy_hu_9676c38c1bf86d9f.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/new-hotness/8bitguy.jpeg&#34;
        alt=&#34;The 8-Bit Guy David Murray (right) and Dan Sanderson (left)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The 8-Bit Guy David Murray (right) with Dan Sanderson (left).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;YouTuber David Murray, aka &amp;ldquo;The 8-Bit Guy,&amp;rdquo; made &lt;a href=&#34;https://youtu.be/OoHxDe3Gc9E?si=ls1od_Cf32gg0vtD&#34;&gt;a video about the Commodore 65&lt;/a&gt; last December, borrowing Bo Zimmerman&amp;rsquo;s vintage C65 prototype to try it out. At the end of the video, David mentioned the MEGA65, mostly to say that he knew about the project but didn&amp;rsquo;t know anything about it. There were multiple attempts to get a review unit to David that fizzled out for one reason or another. When I saw that, I thought to myself, what can I do to help? I suppose I could&amp;hellip; just go down to Texas and bring my MEGA65 with me. So I did!&lt;/p&gt;
&lt;p&gt;Behold, &lt;a href=&#34;https://youtu.be/8qHdTKjPXww?si=ab-gXo1YpPdG9L3C&#34;&gt;the 8-Bit Guy&amp;rsquo;s video about the MEGA65&lt;/a&gt;, with special guest, me!&lt;/p&gt;
&lt;p&gt;David is a co-founder of &lt;a href=&#34;https://www.commanderx16.com/&#34;&gt;the Commander X16 project&lt;/a&gt;, a retro fantasy hardware project with similar interests to the MEGA65. Based on the 65C02 CPU, the X16 has a Commodore-like architecture and uses a Commodore-derived KERNAL and BASIC, while updating other aspects of the design to use readily available components and interfaces. Check out &lt;a href=&#34;https://x16community.github.io/faq/faq.html&#34;&gt;the X16 FAQ&lt;/a&gt; for details, and &lt;a href=&#34;https://www.commanderx16.com/webemu/x16emu.html&#34;&gt;give the in-browser emulator a try&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Many thanks to David for hosting me and for appreciating the MEGA65. Thanks also to my Ko-fi supporters and to the MEGA65 team who helped make this possible.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Yes, your support of this Digest on Ko-fi is already making new things happen! If you would like to support the Digest and my involvement with the MEGA65 team, please visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Back again next month with more news, and more fun things to do with your favorite computer. Cheers!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/new-hotness/M65Digest_2024January.mp3" length="20365216" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1018</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/new-hotness/mega65_box_01.jpg"/>
      
    </item>
    
    <item>
      <title>robotfindskitten, part 3</title>
      <link>https://dansanderson.com/mega65/robot-finds-kitten-3/</link>
      <pubDate>Thu, 14 Dec 2023 14:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/robot-finds-kitten-3/</guid>
      <description>&lt;p&gt;robotfindskitten, part 3. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for December 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;robotfindskitten, part 3. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for December 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/M65Digest_2023Dec.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/M65Digest_2023Dec.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
robotfindskitten, part 3.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/b1_1.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/b1_1.png 1500w, https://dansanderson.com/mega65/robot-finds-kitten-3/b1_1_hu_26a43a43fb428c00.png 600w, https://dansanderson.com/mega65/robot-finds-kitten-3/b1_1_hu_93e1222633f71036.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/b1_1.png&#34;
        alt=&#34;A multi-colored poster of the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Our robotfindskitten adventure continues! In &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/&#34;&gt;part 1&lt;/a&gt;, we introduced the robotfindskitten experience, and described tools and techniques for building an rfk game in BASIC 65. In &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/&#34;&gt;part 2&lt;/a&gt;, we started building a similar toolkit in assembly language, starting with KERNAL routines, memory access techniques, and screen memory registers. This month, we complete the toolkit, and I present my own attempt at an assembly language version of the game.&lt;/p&gt;
&lt;p&gt;But first, a whole bunch of new stuff!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;r5-main-board-in-testing&#34;&gt;R5 main board in testing!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/r5test.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/r5test.jpg 4000w, https://dansanderson.com/mega65/robot-finds-kitten-3/r5test_hu_48a064ad4084a0e8.jpg 600w, https://dansanderson.com/mega65/robot-finds-kitten-3/r5test_hu_a27c35287b1c7821.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/r5test.jpg&#34;
        alt=&#34;A test unit of the R5 main board.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;A test unit of the R5 main board.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The new R5 main board test units have arrived and &lt;a href=&#34;https://c65gs.blogspot.com/2023/12/r5-board-bring-up.html&#34;&gt;Paul has started the &amp;ldquo;bring-up&amp;rdquo; process&lt;/a&gt;, adapting the FPGA core to the design changes. With some minor corrections to the assembly, this should resemble the main boards that will ship with new MEGA65s going forward, including all pending pre-orders. Many thanks to Paul, Trenz Electronic, and the hardware testing team for the work they are doing.&lt;/p&gt;
&lt;h2 id=&#34;unicone-by-deathy&#34;&gt;Unicone, by deathy&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/unicone.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/unicone.png 705w, https://dansanderson.com/mega65/robot-finds-kitten-3/unicone_hu_24b6f90f6a4521da.png 600w, https://dansanderson.com/mega65/robot-finds-kitten-3/unicone_hu_3efc37c95f1cbc12.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/unicone.png&#34;
        alt=&#34;Title screen for the game Unicone for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Unicode title screen.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;deathy has another new game release! In &lt;a href=&#34;https://files.mega65.org?id=0f619bcf-63f0-43d5-b938-0ae6b87f4917&#34;&gt;Unicone&lt;/a&gt;, you are chasing a unicorn that poops ice cream. Move your ice cream cone left and right to catch falling ice cream scoops dropped by the unicorn. A fun game in the tradition of &lt;a href=&#34;https://en.wikipedia.org/wiki/Kaboom!_(video_game)&#34;&gt;Kaboom!&lt;/a&gt; (or its lesser known ancestor, &lt;a href=&#34;https://en.wikipedia.org/wiki/Avalanche_(video_game)&#34;&gt;Avalanche&lt;/a&gt;), Unicone features high resolution graphics, sampled sounds, a wide variety of control schemes, and a unique ice cream balancing mechanic for extra challenge in later levels. &lt;a href=&#34;https://files.mega65.org?id=0f619bcf-63f0-43d5-b938-0ae6b87f4917&#34;&gt;Download Unicode from Filehost&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Want to see how it works? deathy has generously released &lt;a href=&#34;https://github.com/BAS-demogroup/unicone&#34;&gt;the C source code to Unicone&lt;/a&gt; using an open source license, and the assets using a Creative Commons license. The code builds with the &lt;a href=&#34;https://github.com/hth313/Calypsi-tool-chains/releases/tag/5.1&#34;&gt;Calypsi C cross-compiler&lt;/a&gt;, a modern retro development suite by hth313 that recently added support for the MEGA65&amp;rsquo;s 45GS02 CPU. Check it out!&lt;/p&gt;
&lt;h2 id=&#34;the-ghosts-of-blackwood-manor-by-stefan-vogt&#34;&gt;The Ghosts of Blackwood Manor, by Stefan Vogt&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/the-ghosts-of-blackwood-manor-mega65.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/the-ghosts-of-blackwood-manor-mega65.jpg 1120w, https://dansanderson.com/mega65/robot-finds-kitten-3/the-ghosts-of-blackwood-manor-mega65_hu_5d71893fe1099367.jpg 600w, https://dansanderson.com/mega65/robot-finds-kitten-3/the-ghosts-of-blackwood-manor-mega65_hu_c5bdcf26d078f50.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/the-ghosts-of-blackwood-manor-mega65.jpg&#34;
        alt=&#34;The Ghosts of Blackwood Manor, by Stefan Vogt&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The Ghosts of Blackwood Manor, by Stefan Vogt&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Stefan Vogt, the author of the adventure games &lt;em&gt;Hibernated&lt;/em&gt; and &lt;em&gt;The Curse of Rabenstein&lt;/em&gt;, has a new adventure out for multiple platforms including the MEGA65. &lt;a href=&#34;https://8bitgames.itch.io/ghosts&#34;&gt;The Ghosts of Blackwood Manor&lt;/a&gt; is an interactive horror game with three possible outcomes, and each outcome fills out the story.&lt;/p&gt;
&lt;p&gt;And of course, &lt;em&gt;Ghosts&lt;/em&gt; is getting another gorgeous boxed release from poly.play! &lt;a href=&#34;https://www.polyplay.xyz/The-Ghosts-of-Blackwood-Manor-MEGA65_1&#34;&gt;Pre-order the boxed release&lt;/a&gt;, and &lt;a href=&#34;https://8bitgames.itch.io/ghosts&#34;&gt;get it digitally right now&lt;/a&gt; for a donation of your choice.&lt;/p&gt;
&lt;h2 id=&#34;gurces-basic-65-dev-vlogs&#34;&gt;Gurce&amp;rsquo;s BASIC 65 Dev Vlogs&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot.png 674w, https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot_hu_3cbd60e55d09f1d2.png 600w, https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot_hu_2d3a55d2843a3e96.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot.png&#34;
        alt=&#34;Way of the Imploding Foot, a game in progress by Gurce and the MEGA65 community&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Way of the Imploding Foot, a game in progress by Gurce and the MEGA65 community&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Gurce has been doing a series of &lt;a href=&#34;https://www.youtube.com/@IshiTheLastYihi/streams&#34;&gt;live stream development vlogs&lt;/a&gt; coding a game from scratch in BASIC 65, using the &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/34209812/Eleven+Walkthrough&#34;&gt;Eleven programming environment&lt;/a&gt;. The game, currently titled &amp;ldquo;Way of the Imploding Foot&amp;rdquo; (or just &amp;ldquo;MegaFoot&amp;rdquo; for short), is a side-view fighting game, featuring low resolution block character graphics, animated fighting characters, and parallax scrolling.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot_src.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot_src.png 677w, https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot_src_hu_347e850b6cb6c672.png 600w, https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot_src_hu_6efc338a04e8e01c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/megafoot_src.png&#34;
        alt=&#34;MegaFoot source code, in the Eleven IDE&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MegaFoot source code, in the Eleven IDE&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You can &lt;a href=&#34;https://www.youtube.com/watch?v=pqqf2Ge4yWw&#34;&gt;start with episode 1&lt;/a&gt;, and subscribe to find out about new live streams. Also check out &lt;a href=&#34;https://github.com/MEGA65/MegaFoot&#34;&gt;the Github repository for the game&lt;/a&gt;, or just try &lt;a href=&#34;https://github.com/MEGA65/MegaFoot/raw/main/megafoot.d81&#34;&gt;the latest D81 disk image&lt;/a&gt;. When browsing the repo, be sure to locate the &lt;code&gt;.ELPC&lt;/code&gt; files (such as &lt;a href=&#34;https://github.com/MEGA65/MegaFoot/blob/main/FOOT.ELPC&#34;&gt;FOOT.ELPC&lt;/a&gt;), which contain the code in Eleven syntax viewable as a text file on a PC.&lt;/p&gt;
&lt;p&gt;Gurce is welcoming contributions on this project! If you&amp;rsquo;d like to try implementing a feature in BASIC using Eleven, let Gurce know on the Discord.&lt;/p&gt;
&lt;h2 id=&#34;discord-upgrade&#34;&gt;Discord upgrade!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/discord.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/discord.png&#34;
            width=&#34;237&#34;
            height=&#34;308&#34;
            alt=&#34;One section of the newly remodeled MEGA65 Discord: the Pin-Board&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;One section of the newly remodeled MEGA65 Discord.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://mega65.org/chat&#34;&gt;The MEGA65 Discord&lt;/a&gt; is the MEGA65 community&amp;rsquo;s real-time meeting spot, a great place to ask questions, show off your projects, and meet other MEGA65 enthusiasts. Thanks to MEGA65 Discord moderator KiDra, the Discord now has a fresh new structure and some really cool new features! Here are just a few highlights:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;New section layout.&lt;/strong&gt; Channels and resources are now organized in sections based on how you engage with the project, such as regular use, programming, and platform development. Click or tap a section title to collapse sections you use less often.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Discord forums.&lt;/strong&gt; Sections now include Discord forums in addition to text chat channels. Forums are especially useful for asking technical questions: each question stays visible in a list, and answers and discussions stay organized by topic. Once you have the answer you need, you can close the discussion, and it stays in Discord search history for others to find.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice/video rooms.&lt;/strong&gt; Sometimes it&amp;rsquo;s just easier to talk, you know? Hop into a voice room to start an audio or video chat. Show off your work, collaborate on a project, or just hang out.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Pin-Board.&lt;/strong&gt; All of the most important community resources in one well-organized section! Announcements, official project status, and links to resources.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Events.&lt;/strong&gt; Want to organize a club meeting, schedule an online conference, or throw a party? Let everyone know by posting an event! Everyone will be able to express interest in your event and request an automated reminder when the event draws near.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-service posting roles.&lt;/strong&gt; To help keep the announcements and events channels clean and on-topic, we ask that anyone who wishes to post to them read a brief description of how they are used, in the &lt;code&gt;#role-setup&lt;/code&gt; channel. Acknowledging the description grants permission to post, automatically.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Starred posts.&lt;/strong&gt; Did someone post something you think more people should see? Give it a ⭐️ reaction emoji! If enough people star the post, it will be advertised in the &lt;code&gt;#starred-posts&lt;/code&gt; channel. This works from any public channel.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Project channels.&lt;/strong&gt; These discussion channels for specific MEGA65 projects by the community can be used for collaboration, on-going user support, or just dev logging and &lt;a href=&#34;https://en.wikipedia.org/wiki/Rubber_duck_debugging&#34;&gt;rubber ducking&lt;/a&gt; by the project developers. Want a channel for your project? Propose one in the &lt;code&gt;#signup&lt;/code&gt; channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will continue to evolve and improve the Discord based on the needs of the community. If you have any feedback or questions on the new layout and features, feel free to discuss it in the &lt;code&gt;#mega65&lt;/code&gt; channel, or contact anyone on the admin team. Thanks again to KiDra for setting all of this up!&lt;/p&gt;
&lt;h2 id=&#34;bad-apple-in-basic&#34;&gt;Bad Apple&amp;hellip; in BASIC?!?&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/badappl65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/badappl65.png 705w, https://dansanderson.com/mega65/robot-finds-kitten-3/badappl65_hu_f1ba72c987d8f906.png 600w, https://dansanderson.com/mega65/robot-finds-kitten-3/badappl65_hu_9bffb3a020130a4b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/badappl65.png&#34;
        alt=&#34;Bad Basic65 Apple Demo, by Nobato&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Bad Basic65 Apple Demo, by Nobato.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;As a follow-up to &lt;a href=&#34;https://files.mega65.org?id=2b32fbaf-f78b-47db-b919-564eba9ddab1&#34;&gt;MEGApple&lt;/a&gt;, MirageBD&amp;rsquo;s high fidelity Bad Apple demo for the MEGA65, Nobato has a new version, this time in BASIC65! &lt;a href=&#34;https://files.mega65.org?id=52e166b5-07f8-4a5b-92e5-33ffd4dd2d40&#34;&gt;Bad Basic65 Apple Demo&lt;/a&gt; comes on multiple D81 disk images and can swap disks automatically from the SD card. The music is an original SID arrangement, using BASIC65 &lt;code&gt;PLAY&lt;/code&gt; statements.&lt;/p&gt;
&lt;p&gt;Boot &lt;code&gt;B65APPL1.D81&lt;/code&gt; to start. It takes a few minutes to load and decompress data into upper RAM—this is all in BASIC, remember—but once it begins, it runs smoothly, start to finish.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t miss the Little Bad Basic65 Apple bonus disk, also included in the archive!&lt;/p&gt;
&lt;h2 id=&#34;45gs02-assembly-language-mousepads-and-posters&#34;&gt;45GS02 assembly language mousepads and posters&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/mousepad2.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/mousepad2.jpeg 640w, https://dansanderson.com/mega65/robot-finds-kitten-3/mousepad2_hu_e17749a2ddf9a4b0.jpeg 600w, https://dansanderson.com/mega65/robot-finds-kitten-3/mousepad2_hu_30a8f00698809408.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/mousepad2.jpeg&#34;
        alt=&#34;The MEGA65 45GS02 Quick Reference mousepad, now available!&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;It&amp;rsquo;s a mousepad! It&amp;rsquo;s a quick reference! It&amp;rsquo;s a mousepad &lt;em&gt;and&lt;/em&gt; a quick reference!&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/&#34;&gt;A couple of weeks ago&lt;/a&gt;, I mentioned that I designed a 45GS02 assembly language quick reference, and you can &lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;purchase this design as a mousepad or a poster&lt;/a&gt;. Many thanks to everyone who has ordered a mousepad or poster so far! Proceeds go to supporting this Digest and my other work on the MEGA65 project.&lt;/p&gt;
&lt;p&gt;I especially like how the mousepad turned out. It&amp;rsquo;s fun to look at, I can keep it on my desk as a mousepad, and it&amp;rsquo;s actually useful as a quick reference for MEGA65 assembly language programming. I just used it a couple of days ago to remind myself how the stack-related instructions work.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m using Zazzle to make and distribute these. They ship worldwide, and the shipping rates seem reasonable, only about 10 euros to ship the mousepad to Germany. I&amp;rsquo;ve had one report that there were technical issues trying to pay with PayPal. They also support credit cards. If you have issues, let me know, and I can try to figure it out.&lt;/p&gt;
&lt;p&gt;The mousepad is a perfect companion for our robotfindskitten project. Speaking of which&amp;hellip;&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;finishing-robotfindskitten-in-assembly-language&#34;&gt;Finishing robotfindskitten in assembly language&lt;/h2&gt;
&lt;p&gt;To complete our robotfindskitten program in assembly language, we need to accept keyboard input, generate random numbers, de-duplicate choices, pause to animate the (very simple) ending sequence, and select from the list of item descriptions.&lt;/p&gt;
&lt;h3 id=&#34;accepting-keyboard-input-from-the-kernal&#34;&gt;Accepting keyboard input from the KERNAL&lt;/h3&gt;
&lt;p&gt;A common way for a program to accept keyboard input is another KERNAL routine, &lt;code&gt;getin&lt;/code&gt; at $FFE4. This loads a PETSCII code into the Accumulator if a key has been pressed, or 0 if not. This isn&amp;rsquo;t necessarily the best method for using the keyboard as a game controller, because it includes typing features like key repeat. But it&amp;rsquo;s easy to use, and for rfk, the built-in key repeat is reasonable behavior.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;getin = $ffe4
; ...

-   jsr getin
    beq -
    cmp #17
    beq cursor_down
    ; ...

cursor_down:
    ; ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In older versions of the ROM, the &lt;code&gt;getin&lt;/code&gt; routine uses CIA registers to scan the keyboard. With the latest beta test version of the core and ROM that I mentioned last month, &lt;code&gt;getin&lt;/code&gt; uses a new typing event queue implemented in hardware for greater accuracy. Your program will get the same result from either version: the pre-conditions and post-conditions of &lt;code&gt;getin&lt;/code&gt; have not changed.&lt;/p&gt;
&lt;p&gt;A program that doesn&amp;rsquo;t use the KERNAL can access the new hardware registers directly, or can implement its own keyboard scanner based on the CIA chips. See a Commodore 64 reference for information on how to do that.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;getin&lt;/code&gt; also supports features like the function key macros and input redirection, which don&amp;rsquo;t apply to a game but could come in handy for other types of programs. &lt;code&gt;getin&lt;/code&gt; and &lt;code&gt;chrout&lt;/code&gt; are both part of the KERNAL&amp;rsquo;s input-output system, of which the screen and keyboard are only two possible devices.&lt;/p&gt;
&lt;h3 id=&#34;chaos&#34;&gt;Chaos&lt;/h3&gt;
&lt;p&gt;We need a way to select randomized locations and appearances for the items. In BASIC, we used the &lt;code&gt;RND()&lt;/code&gt; function for this purpose. What can we do from assembly language?&lt;/p&gt;
&lt;p&gt;The MEGA65 has a dedicated hardware register that produces random values. To use it, a program must loop to wait for a &amp;ldquo;not ready&amp;rdquo; flag to clear, then read the generated random number from a register. The act of reading the number restarts the process, setting the &amp;ldquo;not ready&amp;rdquo; flag while it works on a new number. Internally, the number generator is using a fluctuating oscillator to generate values, and it needs a brief amount of time between reads to produce good results.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;random = $d7ef
random_ready = $d7fe  ; bit 7
; ...

-   bit random_ready
    bmi -
    lda random
    ; A is a random number between 0 and 255&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Important note:&lt;/strong&gt; If you test your software in the Xemu emulator, be sure to use &lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;the &amp;ldquo;next&amp;rdquo; branch release&lt;/a&gt;. As of this writing, the random number register implementation is not in the latest stable release, and the ready-wait loop will never exit.&lt;/p&gt;
&lt;p&gt;The distribution of values returned by this register is even across all possible byte values 0 to 255. Because this distribution is over a range sized by a power of two, you can reduce the range to a smaller power of two by ignoring some of the bits. For example, to get a random value from an even distribution of 0 to 63, use the &lt;code&gt;and&lt;/code&gt; instruction to set the upper two bits to 0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    and #%00111111
    ; A is a random number between 0 and 63&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the range size is not a power of two, it is feasible to simply &amp;ldquo;re-roll&amp;rdquo; for a number within the desired range. This causes all picks outside the range to be distributed evenly across the desired range, so it does not skew the results. Of course, this can take an arbitrary number of tries to roll a value in range, so you can speed this up by combining both techniques: get a number 0 to 255, zero out the unused bits, then test whether the result is in range and re-roll if not.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-   bit random_ready
    bmi -
    lda random      ; 0 to 255
    and #%01111111  ; 0 to 127
    cmp #80
    bcs -
    ; A is now a random number between 0 and 79&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To get a random number larger than 255, fetch two random numbers and treat them as a single 16-bit number. You can use similar techniques to narrow the range.&lt;/p&gt;
&lt;p&gt;Another option is to implement a pseudorandom number generator in your own code. Such algorithms &lt;a href=&#34;https://en.wikipedia.org/wiki/Pseudorandom_number_generator&#34;&gt;range in power and complexity&lt;/a&gt; and can be difficult to get right, but applications like simple games can often get by with something as simple as a &lt;a href=&#34;https://en.wikipedia.org/wiki/Linear-feedback_shift_register&#34;&gt;linear-feedback shift register&lt;/a&gt; (LFSR). Pseudorandom number algorithms generate a sequence of numbers based a starting number, known as the &lt;em&gt;seed.&lt;/em&gt; It can be an advantage during testing to use a known seed to get a predictable result. For the final program, you can use another source of randomness, such as the hardware random number register, to determine the seed.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like to try this, read &lt;a href=&#34;https://en.wikipedia.org/wiki/Linear-feedback_shift_register&#34;&gt;the Wikipedia page on LFSRs&lt;/a&gt; carefully. See also &lt;a href=&#34;https://www.youtube.com/watch?v=QGeLzCmUDDk&#34;&gt;this video from Retro Game Mechanics Explained&lt;/a&gt; on how the game Super Mario Bros. 3 nerfs its card shuffling algorithm by misusing an LFSR, apparently accidentally.&lt;/p&gt;
&lt;h3 id=&#34;avoiding-duplicates&#34;&gt;Avoiding duplicates&lt;/h3&gt;
&lt;p&gt;When we discussed random selection in BASIC last month, we put in some extra effort to store all previous choices in an array, and re-rolled the dice when we accidentally chose an already-selected character, location, or description. This ensured that no two items would be placed on the same location, which would not only appear as fewer items on the screen but might cause the kitten to be hidden by another item. Depending on how it was implemented, the robot might touch the location and only see the Non-Kitten Item even if the kitten was also at the same location. Ensuring diverse characters and descriptions also maintains variety in the gameplay, to avoid the disappointment of seeing the same description more than once in a game.&lt;/p&gt;
&lt;p&gt;The assembly language version of this isn&amp;rsquo;t different, it&amp;rsquo;s just a bit more cumbersome than in BASIC. I allocated some array-like memory within the program&amp;rsquo;s memory space for this purpose, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;num_items = 20  ; max 127
item_description: !fill num_items*2
item_screen_code: !fill num_items
item_x: !fill num_items
item_y: !fill num_items&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Alternatively I could have put this on the base page, or elsewhere between $1700 and $19FF, which is available for program use.)&lt;/p&gt;
&lt;p&gt;I wrote three assembly language routines that detect whether the value at position X is equal to the value at any position 0 through X-1, the idea being that as I fill the array from position 0 upward, I can check each item against the previous items. I needed three routines because each value is stored in a different way: characters are stored as one-byte screen codes, descriptions are stored as two-byte addresses (which we&amp;rsquo;ll see more of later in this article), and coordinates are stored as coordinate pairs in two separate lists.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the simplest of the three routines I came up with that checks for duplicate screen codes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addrl = $00
addrh = $01
vall = $02

is_unique_byte:
    ; Y,Z: starting address of byte set
    ; X: index of last item
    ; Returns: Carry Set if item at X appears elsewhere in the set
    cpx #0
    beq @is_unique
    sty addrl
    stz addrh
    txa
    tay
    lda (addrl),y
    sta vall
-   dey
    lda (addrl),y
    cmp vall
    beq @is_not_unique
    cpy #0
    bne -
@is_unique
    clc
    bra @end
@is_not_unique
    sec
@end
    rts&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A few notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The routine accepts the starting address of &lt;code&gt;item_screen_code&lt;/code&gt; in the Y and Z registers. I could have hard-coded the address into the routine, but this way I could potentially re-use it with a different array, or in another program.&lt;/li&gt;
&lt;li&gt;It uses the Carry flag as the return value, where Carry is set if a duplicate is found. The routine is not responsible for choosing new random values or updating any memory. It&amp;rsquo;s important to separate responsibilities between routines to make code easier to write, test, and re-use.&lt;/li&gt;
&lt;li&gt;It uses base page variables and indirect indexing (via the Y register) to access the array and remember the value under test. 6502-style CPUs have very few registers, so programs must rely on the base page (or the stack) to wrangle variables.&lt;/li&gt;
&lt;li&gt;With the Acme assembler, a symbol whose name starts with an &lt;code&gt;@&lt;/code&gt; character is a &amp;ldquo;cheap local:&amp;rdquo; it is only valid between two global symbols (such as &lt;code&gt;is_unique_byte&lt;/code&gt;). This way I can re-use these symbol names in my other duplicate test routines.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These routines were challenging to get right! The algorithm isn&amp;rsquo;t complicated, but one errant instruction can cause all kinds of havoc. I found it useful to insert a &lt;code&gt;brk&lt;/code&gt; instruction early in my program so that it would open the &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-monitor/&#34;&gt;MEGA65 Monitor&lt;/a&gt;. From here, I would test these routines by writing values into the arrays, setting the registers, calling the routines, and inspecting the Carry flag.&lt;/p&gt;
&lt;p&gt;To do this, I needed to determine the raw addresses of the routines and the arrays assigned by the assembler. You can tell Acme to generate a report of all of the addresses it used throughout the program, using the &lt;code&gt;-r&lt;/code&gt; command line argument:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;acme -r rfk_report.txt rfk.asm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The monitor commands &lt;code&gt;r&lt;/code&gt; and &lt;code&gt;m&lt;/code&gt; inspect registers and memory, respectively. To update values, you can move the cursor up to the lines that these commands print, change a value, then press &lt;kbd&gt;Return&lt;/kbd&gt;. (Remember that addresses and values are in hexadecimal.) To call a subroutine, use the &lt;code&gt;j&lt;/code&gt; command. See &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-monitor/&#34;&gt;my tutorial on the MEGA65 Monitor&lt;/a&gt;, as well as appendix M of &lt;a href=&#34;https://mega65.org/docs&#34;&gt;the manual&lt;/a&gt;, for more information.&lt;/p&gt;
&lt;h3 id=&#34;avoiding-other-bad-choices&#34;&gt;Avoiding other bad choices&lt;/h3&gt;
&lt;p&gt;There are two more cases of bad item placement worth considering, at least briefly.&lt;/p&gt;
&lt;p&gt;The robot also appears on the playfield along with the items. We need to make sure that an item doesn&amp;rsquo;t land on the robot&amp;rsquo;s starting position. My solution is crude but effective: I put the robot in the upper left corner of the playfield, then limit item placement to be within a one-tile border. This way, there is never an item where the robot starts, and the robot can move unimpeded around the entire edge of the playfield.&lt;/p&gt;
&lt;p&gt;With items placed entirely at random within the border, it is possible, however unlikely, that four items might surround a fifth item. And if that fifth item is the kitten, then the robot will never be able to find it! Tragedy! I admit, I did not bother to solve for this edge case in my implementations, but it&amp;rsquo;s worth thinking about how this might be solved. One way is to test a chosen item location for surrounding items, and re-roll if a bad case is noticed. A complete solution would have to handle extremely unlikely cases like 19 items forming a wall around the kitten, and would probably involve path finding algorithms or other magicks.&lt;/p&gt;
&lt;p&gt;A simpler solution is to only place items on odd numbered rows and columns. For example, within an 80-column width, pick a number from 0 to 38, double it, then add one. This produces a column coordinate from 1 to 77 and guarantees at least a one-space gap between items. Do the same for the row coordinate, and the robot is assured a clear path to every item.&lt;/p&gt;
&lt;h3 id=&#34;calm&#34;&gt;Calm&lt;/h3&gt;
&lt;p&gt;One of the responsibilities of the CIA chips is to keep track of time. For coarse-grained timing, the CIA has a built-in &amp;ldquo;time of day&amp;rdquo; clock that counts up by tenths of a second. If your main loop executes faster than ten times per second, you can count upwards by tenths of a second simply by testing for when register $DC08 changes. The bottom four bits are a &amp;ldquo;binary-coded decimal&amp;rdquo; value between 0 and 9, representing the tenths-of-seconds value of the CIA&amp;rsquo;s clock. This can be a bit crude because you might be testing the register just before it ticks, so the actual delay might be off by as much as one tenth of a second.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;todtenths = $dc08

wait_briefly:
    lda todtenths
    sta last_todtenths
-   lda todtenths
    cmp last_todtenths
    beq -
    sta last_todtenths
-   lda todtenths       ; Wait two ticks to pause between 1/10th
                        ; and 2/10ths of a second
    cmp last_todtenths
    beq -
    rts

last_todtenths: !byte $00&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can achieve a more precise wait loop delay using a feature of the VIC video chip. The VIC uses a finely-tuned high speed mechanism to describe the entire screen to a connected display many times per second, one line at a time from top to bottom, known as the &lt;a href=&#34;https://en.wikipedia.org/wiki/Raster_scan&#34;&gt;raster scan&lt;/a&gt;. The current raster line number is stored in the RC register, as nine bits: bits 0 through 7 are at address $D012, and bit 8 of the number is stored as bit 7 at address $D011. In the same way that you can wait for the CIA TOD tenths register to change, you can wait for these register values to change for much shorter durations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wait_very_briefly:
    ; Wait for bit 8 of the raster count to flip negative then positive,
    ; for a delay between 1 and 2 frames.
-   bit $d011
    bpl -
-   bit $d011
    bmi -
    rts&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The tricky bit (because there&amp;rsquo;s always a tricky bit) is that the number of raster lines and the rate at which the screen is drawn differs depending on the video mode of the MEGA65. Back in the day, &lt;a href=&#34;https://en.wikipedia.org/wiki/PAL&#34;&gt;PAL&lt;/a&gt; and &lt;a href=&#34;https://en.wikipedia.org/wiki/NTSC&#34;&gt;NTSC&lt;/a&gt; were competing standards for analog video signals, used for both transmission and rendering on cathode ray tube (CRT) displays. Commodore sold computers with different VIC chips in different regions to be compatible with the technical standard used in the region for televisions. As a result, Commodore games that used raster-based timing ran differently depending on which VIC chip was in the machine. A game might animate slower or faster than was intended, or it might play music at a different speed. In other cases, a game would only function correctly with one kind of VIC chip, and just trip over itself when running with mismatched VIC timing.&lt;/p&gt;
&lt;p&gt;The MEGA65&amp;rsquo;s VIC-IV chip can generate PAL-like or NTSC-like video signals, as separate modes. Some MEGA65 owners are using displays (vintage or modern) that only support one of the modes. I asked everyone about their display modes in &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023-results/&#34;&gt;the 2023 survey&lt;/a&gt;, and 81% of the MEGA65 owners that responded have their video mode set to PAL by default, vs. 18% set to NTSC. Modern digital displays can often support both modes, but only 56% of owners were confident that their display could do this. A program can force the MEGA65 into one mode or the other using registers, but it&amp;rsquo;s best to leave it in the mode selected by the user in the configuration or Freezer menu.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/which_video_mode_do_you_use__primarily_.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/which_video_mode_do_you_use__primarily_.png 1165w, https://dansanderson.com/mega65/robot-finds-kitten-3/which_video_mode_do_you_use__primarily__hu_a2f4010098cb5d55.png 600w, https://dansanderson.com/mega65/robot-finds-kitten-3/which_video_mode_do_you_use__primarily__hu_27e4436a7fcc2e88.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-3/which_video_mode_do_you_use__primarily_.png&#34;
        alt=&#34;Chart from the MEGA65 Community Survey 2023, indicating that 81% of owners use the PAL video mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Video mode support among MEGA65 owners, from the MEGA65 Community Survey 2023.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The upshot is this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In PAL mode, the RC register counts up to 312 raster lines, at a rate of 50 times per second (50 Hz).&lt;/li&gt;
&lt;li&gt;In NTSC mode, the RC register counts up to 263 raster lines, at a rate of 60 times per second (60 Hz).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The actual image size is twice this many lines, fully refreshed at half these rates. The full image is drawn &lt;em&gt;interlaced,&lt;/em&gt; with odd lines and even lines alternating with each refresh. 50 Hz or 60 Hz is the &lt;em&gt;refresh rate&lt;/em&gt;; 25 Hz or 30 Hz is the &lt;em&gt;frame rate&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It is possible for a program to achieve precision timing independently of video mode using the CIA chips and a system feature known as &lt;em&gt;interrupt handling.&lt;/em&gt; Interrupts can also be used for raster-based timing. High speed games are most likely to use raster-based interrupts for timing because it makes it easier to control screen updates, and they will either live with the consequences of the different video modes, or use sophisticated techniques to work around them. Interrupts are a big topic, so we&amp;rsquo;ll leave that for another Digest.&lt;/p&gt;
&lt;p&gt;robotfindskitten doesn&amp;rsquo;t need precise timing for anything, so raster timing is overkill in this case. I use CIA TOD tenths to add a simple delay to my found-kitten experience, and otherwise rely exclusively on keyboard events (and delays introduced by the key repeat handler) to drive the gameplay logic.&lt;/p&gt;
&lt;h3 id=&#34;data&#34;&gt;Data&lt;/h3&gt;
&lt;p&gt;We&amp;rsquo;re almost done! We have all the tools we need to display messages, choose and place items, animate the robot, move the robot based on keyboard input, and check for item interactions and the win condition. We just need a way to store, select, and display the 400+ possible item descriptions.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve already seen how to add the bytes of a text message to the program in Acme, and to assign a label to its address:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;message: !pet &amp;#34;\&amp;#34;I pity the fool who mistakes me for kitten!\&amp;#34;, sez Mr. T.&amp;#34;,0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What we need is a way to select from a table of messages by an index. For my robotfindskitten implementation, I used a &lt;a href=&#34;https://www.python.org/&#34;&gt;Python&lt;/a&gt; script that reads the NKI descriptions from a text file, and generates &lt;code&gt;!pet&lt;/code&gt; directives for all of them, with labels such as &lt;code&gt;i1&lt;/code&gt;, &lt;code&gt;i2&lt;/code&gt;, and so on. The script also generates an address look-up table with all of the generated labels in it. This puts the starting address of each description into memory at regular two-byte intervals. The program can find the description for a given index by multiplying the index by two (the &lt;code&gt;asl&lt;/code&gt; instruction will do the trick), adding it to the address of the lookup table (&lt;code&gt;nki_table&lt;/code&gt;), then reading the description start address from that location. Each description ends with a 0 byte, so the message printing routine knows where to stop.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nki_desc_count_mask = $01ff
nki_desc_count = 401

nki_table:
!16 i0,i1,i2,i3,i4,i5,i6,i7
!16 i8,i9,i10,i11,i12,i13,i14,i15
; ...

i0: !pet &amp;#34;\&amp;#34;I pity the fool who mistakes me for kitten!\&amp;#34;, sez Mr. T.&amp;#34;,0
i1: !pet &amp;#34;That&amp;#39;s just an old tin can.&amp;#34;,0
i2: !pet &amp;#34;It&amp;#39;s an altar to the horse god.&amp;#34;,0
; ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&amp;rsquo;s the full procedure for assigning a unique description to a Non-Kitten Item, using the techniques we&amp;rsquo;ve discussed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For each item, use the random number register to generate 16 bits (two bytes).&lt;/li&gt;
&lt;li&gt;Apply a bitmask to cut down this 16-bit value to a 9-bit value, the smallest mask that would account for the maximum number of descriptions (512 &amp;gt; 401).&lt;/li&gt;
&lt;li&gt;Compare the result to the actual maximum number of descriptions, and re-roll until the selected number is within range. This is the description index.&lt;/li&gt;
&lt;li&gt;Multiply the index by two to get the offset into the lookup table. Add this to the lookup table&amp;rsquo;s starting address.&lt;/li&gt;
&lt;li&gt;Read the description starting address from the lookup table at that location.&lt;/li&gt;
&lt;li&gt;Store the description address in the &lt;code&gt;item_description&lt;/code&gt; array, then test whether it is a duplicate. If so, start again from step 1.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Using tools and scripts to generate data embedded in a machine code program like this is an essential skill, especially for games. Some assemblers have powerful directives that make embedding and manipulating data easy, such as Acme&amp;rsquo;s &lt;code&gt;!binary&lt;/code&gt; directive that pulls in binary data from a file. &lt;a href=&#34;http://theweb.dk/KickAssembler/Main.html#frontpage&#34;&gt;Kick Assembler&lt;/a&gt;&amp;rsquo;s inline scripting capabilities are especially impressive. I find it useful to know a modern scripting language like &lt;a href=&#34;https://www.python.org/&#34;&gt;Python&lt;/a&gt; so I can write my own data conversion tools that generate either assembly code or binary data that can be embedded in my programs.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t want to write your own scripts to generate the NKI description table, you can borrow the source code for my version, linked below.&lt;/p&gt;
&lt;h3 id=&#34;the-final-robotfindskitten-program&#34;&gt;The final robotfindskitten program&lt;/h3&gt;
&lt;p&gt;Here are my final versions of robotfindskitten for the MEGA65, in both BASIC and assembly language:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/rfk-bas.prg&#34;&gt;rfk-bas.prg&lt;/a&gt; : robotfindskitten in BASIC 65; &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/rfk-bas.txt&#34;&gt;BASIC source code&lt;/a&gt; in petcat format&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;rfk-asm.prg&#34;&gt;rfk-asm.prg&lt;/a&gt; : robotfindsktiten in MEGA65 assembly language; &lt;a href=&#34;rfk.asm&#34;&gt;assembly language source code&lt;/a&gt; for the Acme assembler&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don&amp;rsquo;t claim that either of these are the best possible versions of this program. If you find ways that either of these can be improved, or if you have used different designs or techniques in your program, &lt;a href=&#34;mailto:contact@dansanderson.com&#34;&gt;please let me know&lt;/a&gt;!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Whew! That&amp;rsquo;s a whirlwind of programming topics for three Digest issues. Hopefully this is enough for you to get started writing a robotfindskitten of your own, or extending these ideas to making other kinds of games. For example, you could add a system of walls or a maze generator to make locating items more challenging. Or, you could add other non-player robots that move when the player does, attempting to interfere with the search. Maybe when a non-player robot encounters an item, the item gets relocated on the playfield! It&amp;rsquo;d be a much less zen experience, but more like a game.&lt;/p&gt;
&lt;p&gt;Huge thanks to everyone who has jumped in to support the Digest on Ko-fi so far! We&amp;rsquo;re off to a good start to funding the Digest through 2024. If you would like to become a supporter, visit: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;https://ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;See you next year!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/robot-finds-kitten-3/M65Digest_2023Dec.mp3" length="33285141" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1664</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/robot-finds-kitten-3/b1_1.png"/>
      
    </item>
    
    <item>
      <title>MEGA65 mousepads, posters, and new ways to support the Digest</title>
      <link>https://dansanderson.com/mega65/mousepads-and-kofi/</link>
      <pubDate>Wed, 29 Nov 2023 15:00:00 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/mousepads-and-kofi/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;45GS02 Quick Reference mousepads and posters&lt;/a&gt; now available, and a new way to &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;support my work on the MEGA65 and the Digest&lt;/a&gt;!&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;&lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;45GS02 Quick Reference mousepads and posters&lt;/a&gt; now available, and a new way to &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;support my work on the MEGA65 and the Digest&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Hey all! I hope you&amp;rsquo;re all having good holidays and a good time with your MEGA65.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve all received a lot of email in the last week, so here&amp;rsquo;s the super-short version with two links to save some time:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;New MEGA65 45GS02 Quick Reference mousepads and posters now available!&lt;/a&gt; Order this week and get 25% off! Use code ZCYBERDEAL23 during checkout.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;Support my work on the MEGA65 and the Digest with Ko-fi!&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Continue reading for photos and details!&lt;/p&gt;
&lt;h2 id=&#34;new-mega65-mousepads-and-posters&#34;&gt;New MEGA65 mousepads and posters!&lt;/h2&gt;
&lt;p&gt;During my recent experiences learning about MEGA65 assembly language, I&amp;rsquo;ve been wanting some kind of quick reference for all of the instructions supported by the 45GS02 CPU, something that sits on my desk that I can glance at to remind me of how it works. I originally thought it&amp;rsquo;d be fun to make a coffee mug, but as I iterated on a design, it became clear that it&amp;rsquo;d take several mugs to fit all of the instructions! So I wondered, what about a mousepad?&lt;/p&gt;
&lt;p&gt;After some careful layout work and a heap of technical troubleshooting, I landed on this design, and I think it&amp;rsquo;s pretty snazzy:&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/mousepad1.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/mousepad1.jpeg 640w, https://dansanderson.com/mega65/mousepads-and-kofi/mousepad1_hu_d12654554726d7c1.jpeg 600w, https://dansanderson.com/mega65/mousepads-and-kofi/mousepad1_hu_1e37117d245bb03d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/mousepad1.jpeg&#34;
        alt=&#34;MEGA65 45GS02 Quick Reference mousepad&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 45GS02 Quick Reference mousepad.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/mousepad2.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/mousepad2.jpeg 640w, https://dansanderson.com/mega65/mousepads-and-kofi/mousepad2_hu_e17749a2ddf9a4b0.jpeg 600w, https://dansanderson.com/mega65/mousepads-and-kofi/mousepad2_hu_30a8f00698809408.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/mousepad2.jpeg&#34;
        alt=&#34;Mousepad with mouse&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The mousepad performing one of its two functions.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I tried the same design as a 20&amp;quot; x 16&amp;quot; poster, and it&amp;rsquo;s pretty good too:&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/poster1.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/poster1.jpeg 640w, https://dansanderson.com/mega65/mousepads-and-kofi/poster1_hu_2330df640226e4d3.jpeg 600w, https://dansanderson.com/mega65/mousepads-and-kofi/poster1_hu_1adb45e70fe7da74.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/poster1.jpeg&#34;
        alt=&#34;MEGA65 45GS02 Quick Reference poster&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 45GS02 Quick Reference poster.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/poster2.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/poster2.jpeg 480w, https://dansanderson.com/mega65/mousepads-and-kofi/poster2_hu_9ee156c5916f47db.jpeg 600w, https://dansanderson.com/mega65/mousepads-and-kofi/poster2_hu_afe33f606a70cff3.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mousepads-and-kofi/poster2.jpeg&#34;
        alt=&#34;Close-up detail of the 45GS02 poster&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Poster close-up.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;m happy to announce that you can now &lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;get a MEGA65 45GS02 Quick Reference mousepad and poster of your own&lt;/a&gt;, just in time for the holidays! Get one for yourself, and one for that special someone in your life that writes MEGA65 assembly language programs.&lt;/p&gt;
&lt;p&gt;Features of the design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every 6502, 65CE02 (4510), and 45GS02 instruction and addressing mode, color-coded by CPU&lt;/li&gt;
&lt;li&gt;Status register side effects&lt;/li&gt;
&lt;li&gt;Branch instruction flag behaviors&lt;/li&gt;
&lt;li&gt;CMP instruction flag behaviors&lt;/li&gt;
&lt;li&gt;Q virtual register layout&lt;/li&gt;
&lt;li&gt;MAP register layout and call pattern&lt;/li&gt;
&lt;li&gt;A fun colorful design that&amp;rsquo;s a joy to have on your desk or wall!&lt;/li&gt;
&lt;li&gt;Mousepad is also a mousepad!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most of the cost goes to printing and distribution, by Zazzle. All remaining proceeds support my work on the MEGA65 and the Digest.&lt;/p&gt;
&lt;p&gt;This week only, &lt;strong&gt;use code ZCYBERDEAL23 during checkout and get 25% off!&lt;/strong&gt; This is Zazzle&amp;rsquo;s holiday promotion. I think the code is applied automatically. You&amp;rsquo;ll figure it out.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the store link again: &lt;a href=&#34;https://www.zazzle.com/store/m65digest&#34;&gt;https://www.zazzle.com/store/m65digest&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;support-the-mega65-digest-in-2024&#34;&gt;Support the MEGA65 Digest in 2024&lt;/h2&gt;
&lt;p&gt;I have been writing the MEGA65 Digest monthly newsletter since August of 2022, fifteen full issues to date, with one more planned for this calendar year. I&amp;rsquo;m extremely grateful to have had the opportunity to donate my time to the MEGA65 project in this and other ways in the last year and a half.&lt;/p&gt;
&lt;p&gt;Some members of our community have reached out to me to inquire about supporting my efforts through patronage. Several folks even figured out how to contribute through Substack without my ever having asked! (I think Substack asks on my behalf without my knowing, but still, that&amp;rsquo;s amazing!) Huge thanks to everyone who has contributed so far.&lt;/p&gt;
&lt;p&gt;I am humbled to announce that you can now &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;support the Digest and my other MEGA65 work through ko-fi.com&lt;/a&gt;. Ko-fi supports PayPal and Stripe as payment methods, which includes Apple Pay and major credit cards. I&amp;rsquo;m at a point where a small monthly contribution can make a &lt;em&gt;big&lt;/em&gt; difference.&lt;/p&gt;
&lt;p&gt;Important note: &lt;em&gt;The email Digest will always be free for all.&lt;/em&gt; I consider the newsletter to be an essential community resource, especially for project announcements. Your contributions will benefit everyone. (My open source code contributions will also be for everyone, but I assume that goes without saying. 😅)&lt;/p&gt;
&lt;p&gt;I am considering what fun things we can do with supporter exclusives or early access. In particular, I might re-tool the audio version of the Digest as a bonus feature, or as something else entirely. We can discuss it in the Ko-fi comments.&lt;/p&gt;
&lt;p&gt;I will continue to welcome contributions via Substack. That&amp;rsquo;s not everybody&amp;rsquo;s favorite option and I have considered migrating to another email newsletter provider. For now, I&amp;rsquo;ll try to mention anything supporter-exclusive in both places.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;huge&lt;/em&gt; thank you again to everyone who has supported my efforts so far, and to everyone able to offer support going forward.&lt;/p&gt;
&lt;p&gt;The ko-fi link: &lt;a href=&#34;https://ko-fi.com/dddaaannn&#34;&gt;https://ko-fi.com/dddaaannn&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;my-to-done-list&#34;&gt;My to-done list&lt;/h2&gt;
&lt;p&gt;Wistfully reviewing my time here so far, here are some of the things (well, most of the things) I’ve been able to do in the last year or so thanks to everyone’s support:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wrote the &lt;a href=&#34;https://dansanderson.com/mega65/welcome/&#34;&gt;MEGA65 Welcome Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Wrote 15+ issues of &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt;, email newsletter and audio podcast&lt;/li&gt;
&lt;li&gt;Assembled and distributed the &lt;a href=&#34;https://files.mega65.org?ar=ff484da0-d942-4e9b-adf1-3b5a77acaa25&#34;&gt;Real-Time Clock replacement part&lt;/a&gt; for batch #1 and batch #2 owners affected by the RTC issue&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mega65.org/docs&#34;&gt;MEGA65 documentation&lt;/a&gt; maintainer and author since late 2022&lt;/li&gt;
&lt;li&gt;Wrote the new Memory chapter&lt;/li&gt;
&lt;li&gt;Revised the User&amp;rsquo;s Guide for a 2nd edition, including all-new chapters and a revised and tested BASIC reference, to accompany the upcoming v0.96 release&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/blob/main/CHANGELOG.md&#34;&gt;MEGA65 ROM&lt;/a&gt; maintainer since version 920377&lt;/li&gt;
&lt;li&gt;Tested and merged ROM contributions from the development branch&lt;/li&gt;
&lt;li&gt;Implemented the &amp;ldquo;undo Home&amp;rdquo; feature; &lt;a href=&#34;https://dansanderson.com/lab-notes/adding-a-feature-to-mega65/&#34;&gt;blog write-up&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Implemented 27 ROM bug fixes and changes, several core and Freezer fixes and changes&lt;/li&gt;
&lt;li&gt;Completed the new hardware keyboard scanner in the MEGA65 core (originally started by Paul), and upgraded the ROM to use it from the KERNAL and screen editor&lt;/li&gt;
&lt;li&gt;Wrote a semi-automated integration test driver capable of running everything uploaded to Filehost on a real MEGA65 to test outcomes with ROM and core changes&lt;/li&gt;
&lt;li&gt;Implemented the &lt;a href=&#34;https://tilde.zone/@mega65files&#34;&gt;MEGA65 Files bot&lt;/a&gt;, currently available via Mastodon and RSS&lt;/li&gt;
&lt;li&gt;Wrote &lt;a href=&#34;https://dansanderson.com/tags/mega65/&#34;&gt;additional tutorials on MEGA65 programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Wrote and hosted the &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023-results/&#34;&gt;MEGA65 Community Survey 2023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Gave a talk about the MEGA65 at &lt;a href=&#34;https://youtu.be/vYTTn3fLNxc?si=LpkB7KA_cF-qKqLx&#34;&gt;Pacific Commodore Expo Northwest 2023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Other minor projects: &lt;a href=&#34;https://github.com/dansanderson/mega65-symbols&#34;&gt;symbols source generator&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=9a5390c1-3f97-4483-a42d-204844438b41&#34;&gt;BF interpreter&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?ar=ce6ac468-b8d7-4d4d-b191-1feabb92946c&#34;&gt;Welcome FAQ&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;ROM FAQ&lt;/a&gt;, a &lt;a href=&#34;https://dansanderson.com/lab-notes/autotools-in-2022/&#34;&gt;weird detour I took with GNU Autotools&lt;/a&gt; that didn&amp;rsquo;t amount to anything, some unimplemented designs I won&amp;rsquo;t otherwise mention&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lots of ideas for 2024, looking forward to it! And thanks again!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>robotfindskitten, part 2</title>
      <link>https://dansanderson.com/mega65/robot-finds-kitten-2/</link>
      <pubDate>Mon, 13 Nov 2023 20:00:19 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/robot-finds-kitten-2/</guid>
      <description>&lt;p&gt;robotfindskitten, part 2. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for November 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;robotfindskitten, part 2. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for November 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/M65Digest_2023Nov.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/M65Digest_2023Nov.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
robotfindskitten, part 2.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/rfk-bas.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/rfk-bas.png 647w, https://dansanderson.com/mega65/robot-finds-kitten-2/rfk-bas_hu_e85f73101d7494a3.png 600w, https://dansanderson.com/mega65/robot-finds-kitten-2/rfk-bas_hu_c4a448fa82d5be.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/rfk-bas.png&#34;
        alt=&#34;robotfindskitten for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
robotfindskitten for the MEGA65 (BASIC version)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/&#34;&gt;Last month&amp;rsquo;s Digest&lt;/a&gt; introduced robotfindskitten, a programming exercise that unites several major concepts of game programming: updating the display, reading user input, generating random values, timing events, and including and manipulating large amounts of static game data. I offered examples of each of these tasks in BASIC 65, and proposed that these could be used to make a robotfindskitten experience for the MEGA65.&lt;/p&gt;
&lt;p&gt;In this issue, I want to start reviewing these topics again in assembly language. Without BASIC&amp;rsquo;s help, the program will need to turn to hardware registers and low-level programming techniques to achieve similar effects. Some of these topics are too large for a single newsletter, so we&amp;rsquo;ll take this in two parts. I&amp;rsquo;ll try to keep things simple by limiting this to just the needs of a robotfindskitten program. Applications that require higher speed or more memory may need more sophisticated techniques.&lt;/p&gt;
&lt;p&gt;This month&amp;rsquo;s Digest will focus on using the KERNAL, printing messages, and drawing characters to the screen—barely scratching the surface of the MEGA65&amp;rsquo;s graphics capabilities. Next month, we&amp;rsquo;ll finish robotfindskitten in assembly language with random values, user input, item descriptions, and a simple animation delay.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;shipping-update&#34;&gt;Shipping update&lt;/h2&gt;
&lt;p&gt;The work continues to finalize the new R5 main board hardware for the next delivery batch of computers. Getting the test hardware has taken longer than anticipated, and we are now expecting manufacturing lead times to put the batch #3 delivery in early 2024.&lt;/p&gt;
&lt;p&gt;Importantly, the team has decided to proceed with the full verification process for the new design, and not skip any steps just to accelerate the schedule. The MEGA65 is manufactured in small volumes in a not-for-profit operation, so we can&amp;rsquo;t afford to rush the process and risk having to re-make and replace hardware. We want every computer delivered to be as high in quality as possible.&lt;/p&gt;
&lt;p&gt;Some pre-orders have been pending for a &lt;em&gt;very&lt;/em&gt; long time now, and we thank you for your patience! If you have a pending pre-order and need to make changes, contact Trenz Electronic customer support.&lt;/p&gt;
&lt;h2 id=&#34;tristam-island&#34;&gt;Tristam Island&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/tristam-island-mega65~2.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/tristam-island-mega65~2.jpg 1120w, https://dansanderson.com/mega65/robot-finds-kitten-2/tristam-island-mega65~2_hu_fc7233eaf84d5331.jpg 600w, https://dansanderson.com/mega65/robot-finds-kitten-2/tristam-island-mega65~2_hu_8bca672fe485929b.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/tristam-island-mega65~2.jpg&#34;
        alt=&#34;Tristam Island box art&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Tristam Island for the MEGA65.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;Tristam Island,&lt;/em&gt; by Hugo Labrande, is a new text adventure game for multiple platforms, including the MEGA65. You can get the &lt;a href=&#34;https://www.polyplay.xyz/Tristam-Island-MEGA65_1&#34;&gt;deluxe boxed edition&lt;/a&gt;, from publisher poly.play for 35 EUR. The deluxe edition includes the game on 3.5&amp;quot; floppy disk and on microSD card, a hint book, immersive props such as a rock sample and a postcard, and more. You can also get &lt;a href=&#34;https://hlabrande.itch.io/tristam-island&#34;&gt;the digital-only edition&lt;/a&gt; for $3.99 USD.&lt;/p&gt;
&lt;p&gt;Thanks to Hugo for the great game and for supporting the MEGA65, and to poly.play for publishing fun collectible boxed software for our favorite platform!&lt;/p&gt;
&lt;h2 id=&#34;updated-zx-spectrum-core&#34;&gt;Updated ZX Spectrum core&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/ZXSpectrum48k.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/ZXSpectrum48k.jpg 680w, https://dansanderson.com/mega65/robot-finds-kitten-2/ZXSpectrum48k_hu_6d5a6163c60aa8c2.jpg 600w, https://dansanderson.com/mega65/robot-finds-kitten-2/ZXSpectrum48k_hu_fbc937c8baddc6d2.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/ZXSpectrum48k.jpg&#34;
        alt=&#34;The ZX Spectrum&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The ZX Spectrum.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Did you know that you can turn your MEGA65 into a ZX Spectrum? You can, with the ZX Spectrum core! This core just received a major overhaul to use the &lt;a href=&#34;https://github.com/sy2002/MiSTer2MEGA65&#34;&gt;MiSTer2MEGA65&lt;/a&gt; framework, and now works with modern displays.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=bdaeb7e0-9fc8-4185-99de-104d01229f27&#34;&gt;Download the ZX Spectrum core from Filehost&lt;/a&gt;, then &lt;a href=&#34;https://github.com/sy2002/zxuno4mega65/wiki/Getting-Started&#34;&gt;follow these detailed instructions&lt;/a&gt; for set-up and enjoyment. The core expects certain files in specific locations on the SD card, and uses &lt;a href=&#34;http://esxdos.org/index.html&#34;&gt;ESXDOS v0.8.8&lt;/a&gt; (not v0.8.9) for SD card access. It can load &lt;code&gt;.tap&lt;/code&gt; and &lt;code&gt;.trd&lt;/code&gt; files.&lt;/p&gt;
&lt;p&gt;Once again thanks to sy2002 and MJoergen for their amazing work on setting up the MEGA65 for retro core success!&lt;/p&gt;
&lt;h2 id=&#34;more-arcade-cores&#34;&gt;More arcade cores!&lt;/h2&gt;
&lt;p&gt;muse continues the great work of porting arcade game cores to the MEGA65. &lt;a href=&#34;https://files.mega65.org/html/main.php?id=f3ddcbd5-a6c1-42cd-aa9c-db25dfd71c90&#34;&gt;Bombjack&lt;/a&gt; (1984) (&lt;a href=&#34;https://github.com/sho3string/BombjackMEGA65&#34;&gt;installation instructions&lt;/a&gt;) and &lt;a href=&#34;https://files.mega65.org/html/main.php?id=f3ddcbd5-a6c1-42cd-aa9c-db25dfd71c90&#34;&gt;Bosconian&lt;/a&gt; (1981) (&lt;a href=&#34;https://github.com/sho3string/BosconianMEGA65&#34;&gt;installation isntructions&lt;/a&gt;) are both available.&lt;/p&gt;
&lt;p&gt;The complete list of alternate cores for the MEGA65 so far:&lt;/p&gt;
&lt;p&gt;Ports and enhancements by MJoergen and sy2002:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=896a012f-59e4-456c-b91f-7e989b958241&#34;&gt;Commodore 64&lt;/a&gt; v5&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=bdaeb7e0-9fc8-4185-99de-104d01229f27&#34;&gt;ZX Spectrum&lt;/a&gt; v1.0&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=f3ddcbd5-a6c1-42cd-aa9c-db25dfd71c90&#34;&gt;Game Boy&lt;/a&gt; v0.8&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ports and enhancements by muse (shoestring):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=8bc248e3-c29c-4ba8-b8c3-6018a995a9ea&#34;&gt;Galaga&lt;/a&gt; v0.5.1&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=96dd324b-d611-4252-bea4-0dbc4eb899ae&#34;&gt;Bosconian&lt;/a&gt; v0.5.0&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=d32474e9-6f30-48f8-bba3-167cad4bbc4f&#34;&gt;Xevious&lt;/a&gt; v0.5.0&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=f3ddcbd5-a6c1-42cd-aa9c-db25dfd71c90&#34;&gt;Bombjack&lt;/a&gt; v0.5.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Along with a MEGA65 development core in slot 1 and a factory-installed stable core in slot 0, that&amp;rsquo;s more cores than there are core slots on a MEGA65! Just keep the &lt;code&gt;.cor&lt;/code&gt; files on your SD card and flash them as needed.&lt;/p&gt;
&lt;h2 id=&#34;conference-talks&#34;&gt;Conference talks&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/crx_jim.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/crx_jim.png 861w, https://dansanderson.com/mega65/robot-finds-kitten-2/crx_jim_hu_1eee921c974c638f.png 600w, https://dansanderson.com/mega65/robot-finds-kitten-2/crx_jim_hu_fad0a9f0fbb9c499.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten-2/crx_jim.png&#34;
        alt=&#34;Jim Happel (jim_64) at Commodore Retro eXpo 2023&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Jim Happel (jim_64) at Commodore Retro eXpo 2023&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;MEGA65 enthusiasts have been giving talks at computer conferences this year, and several of them now have video online. Check these out!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://media.ccc.de/v/vcfb2023_-_185_-_de_-_202310141545_-_mega65_-_oliver_graf&#34;&gt;Oliver Graf (lydon) at Vintage Computing Festival Berlin 2023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/live/KUTamTXnWB4?si=Vo-NJiJu2j5G6mq9&amp;amp;t=1990&#34;&gt;Jim Happel (jim_64) at Commodore Retro eXpo 2023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/vYTTn3fLNxc?si=LpkB7KA_cF-qKqLx&#34;&gt;Dan Sanderson (dddaaannn) at Pacific Commodore Expo Northwest 2023&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have given a presentation on the MEGA65, even just to your local computer club, and there&amp;rsquo;s video online, please let me know so I can feature it here!&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;robotfindskitten-in-assembly-language&#34;&gt;robotfindskitten in assembly language&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at how you might implement robotfindskitten in MEGA65 assembly language. This month will focus on using the KERNAL API and manipulating the display. Next month, we&amp;rsquo;ll cover the remaining topics to get a robotfindskitten program working, similar to what we did in BASIC last month.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/cross-development/&#34;&gt;As before&lt;/a&gt;, I&amp;rsquo;ll be using &lt;a href=&#34;https://sourceforge.net/projects/acme-crossass/&#34;&gt;the Acme assembler&lt;/a&gt;. Here&amp;rsquo;s a reminder of the starter code for an assembly language program that assembles to a PRG file that can be loaded and run. The &lt;code&gt;!8 ...&lt;/code&gt; values describe a BASIC bootstrap program that invokes the first assembly language instruction.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;!cpu m65
!to &amp;#34;rfk.prg&amp;#34;, cbm

* = $2001

!8 $12,$20,$0a,$00,$fe,$02,$20,$30,$3a,$9e,$20
!pet &amp;#34;$2014&amp;#34;
!8 $00,$00,$00

start:
    ; Program code will go here.&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;introducing-the-kernal&#34;&gt;Introducing the KERNAL&lt;/h3&gt;
&lt;p&gt;Every Commodore computer has a built-in operating system powered by machine code etched into the computer&amp;rsquo;s Read Only Memory (ROM). You see this code running as soon as you turn on the computer: the &lt;code&gt;READY&lt;/code&gt; prompt, the blinking cursor, and the BASIC interpreter and all of the BASIC commands are all built-in code. Included in this code is a collection of machine code routines and subsystems for accessing hardware such as the keyboard, screen, and disk drives. In computer architecture terms, these routines are known as the &lt;em&gt;kernel,&lt;/em&gt; the centerpiece of the system used by other components. Commodore employee Robert Russell originally misspelled the word &amp;ldquo;kernel&amp;rdquo; as &amp;ldquo;KERNAL&amp;rdquo; in the documentation, and this became a nickname for the software. For the sake of tradition, I&amp;rsquo;ll continue to refer to the Commodore kernel as the KERNAL, using uppercase letters.&lt;/p&gt;
&lt;p&gt;A program can call KERNAL routines by way of a &lt;em&gt;jump table,&lt;/em&gt; a list of &lt;code&gt;jmp&lt;/code&gt; instructions built into the ROM at a fixed memory location. Each &lt;code&gt;jmp&lt;/code&gt; instruction redirects to the actual location of the routine elsewhere in memory. The jump table exists to give programmers peace of mind that each &lt;code&gt;jmp&lt;/code&gt; instruction will stay at a consistent address for all future revisions of the KERNAL. When changes in the KERNAL code inevitably push an internal routine to a new location, the jump table is updated accordingly, so programs that use the routine continue to function without needing an update.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a useful example. The KERNAL maintains a system for printing PETSCII codes to the screen. &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/&#34;&gt;As we&amp;rsquo;ve seen before&lt;/a&gt;, these codes manipulate a cursor that determines the location of the next printable character, and maintains other properties such as the text color and display attributes. The BASIC &lt;code&gt;PRINT&lt;/code&gt; command uses this system to display strings of codes and characters. Machine code programs can also access this system using a routine called &lt;code&gt;chrout&lt;/code&gt; (also called &lt;code&gt;bsout&lt;/code&gt; in some documentation), available via the jump table entry at $FFD2.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chrout = $ffd2

    lda #147      ; clear the screen
    jsr chrout

    lda #65       ; the letter &amp;#34;A&amp;#34;
    jsr chrout&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;chrout&lt;/code&gt; routine has a &lt;em&gt;pre-condition&lt;/em&gt; that the PETSCII code to print is in the accumulator (CPU register &amp;ldquo;A&amp;rdquo;). The effect of calling the routine is to print the PETSCII code at the current cursor position. If the code is a printable character, it plots the character, moves the cursor, and performs other effects like scrolling the display as needed. If the code is some other PETSCII code, such as code 147 to clear the screen and move the cursor to the top-left corner, that code takes effect.&lt;/p&gt;
&lt;p&gt;The jump table is part of the Application Programming Interface, or API, of the KERNAL. The API definition also includes the pre-conditions and post-conditions of each routine, and other important behavioral characteristics about what the routine does. All KERNAL jump table entries designed for the C64 and C128 are valid on the MEGA65—with some changes. While neither the C65 nor the MEGA65 have introduced new table entries, future versions of the MEGA65 ROM could extend the table further without changing any of the existing entries.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important to remember that the MEGA65 ROM is an active construction zone, and only some of the KERNAL APIs borrowed from previous Commodores are considered officially supported for now. Some things that C64 programmers may be used to aren&amp;rsquo;t official APIs, even if they appear to function today. When the dust has settled on the major bug fixes, the MEGA65 team will formalize more of the KERNAL API surface, adding documentation about supported features to &lt;a href=&#34;https://mega65.org/docs&#34;&gt;the manuals&lt;/a&gt; and building automated tests to ensure that the APIs work properly. The KERNAL jump table is officially supported, as are certain specific facts about the memory layout, such as $2001 being the start address for BASIC programs.&lt;/p&gt;
&lt;p&gt;Once a machine code program is running, it is not obligated to use the KERNAL. In fact, many games and larger utilities jettison the KERNAL entirely, installing custom interrupt handler routines, defining a custom memory map, and manipulating the computer entirely through hardware registers. For such a program, the only API surface is the hardware itself, and there is no need to integrate with the KERNAL except to launch the program. If the program does use KERNAL routines and systems, it must honor the KERNAL&amp;rsquo;s documented pre-conditions, and stay out of its way.&lt;/p&gt;
&lt;h3 id=&#34;printing-a-short-message-using-the-kernal&#34;&gt;Printing a short message using the KERNAL&lt;/h3&gt;
&lt;p&gt;The following code uses the KERNAL &lt;code&gt;chrout&lt;/code&gt; routine to clear the screen and print a short message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    lda #147       ; clear the screen
    jsr chrout
    
    ldx #0
-   lda message,x  ; read a byte from message, offset by X
    beq +          ; if it&amp;#39;s a zero, we have reached the end of the message
    jsr chrout     ; output the byte
    inx            ; increment X
    bra -          ; loop back
+   rts

message:
!pet 14,&amp;#34;robotfindskitten&amp;#34;,0   ; Acme directive to generate PETSCII bytes&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This example uses the &amp;ldquo;X indexing&amp;rdquo; addressing mode to access characters in the message stored in program memory. &lt;code&gt;lda message,x&lt;/code&gt; takes the address of the message, via the assembler symbol &lt;code&gt;message&lt;/code&gt;, and adds the value in the X register to it. The X register is one byte, with a range of possible values of 0 to 255. This limits the length of the message to 254 PETSCII codes and one 0 byte to indicate the end of the message.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s another way to print short messages, using another KERNAL routine. The &lt;code&gt;primm&lt;/code&gt; routine at $FF7D will print a null-terminated message, with the message bytes immediately following the &lt;code&gt;jsr&lt;/code&gt; instruction. It&amp;rsquo;s like having a &lt;code&gt;PRINT&lt;/code&gt; command for assembly language!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;primm = $ff7d

    jsr primm
!pet 14,&amp;#34;robotfindskitten&amp;#34;,0

    ; Program continues...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It seems like a magic trick for the message bytes to be sitting in the middle of the code like this. How does the CPU know to skip over the message to the next instruction? The &lt;code&gt;primm&lt;/code&gt; routine is quite clever. When the CPU encounters a &lt;code&gt;jsr&lt;/code&gt; instruction, it remembers the address just after the instruction, so it can pick up where it left off when the subroutine exits with the &lt;code&gt;rts&lt;/code&gt; instruction. The &lt;code&gt;primm&lt;/code&gt; routine assumes that this address is the starting byte for the message and starts printing. When &lt;code&gt;primm&lt;/code&gt; finds the 0, it updates the return address to just after the 0, then issues the &lt;code&gt;rts&lt;/code&gt;. The CPU is blissfully unaware that &lt;code&gt;primm&lt;/code&gt; has been messing with the return address and proceeds to execute the rest of the program. Pretty slick!&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;primm&lt;/code&gt; is also limited to messages of 254 characters. To print a longer message, we need a different strategy.&lt;/p&gt;
&lt;h3 id=&#34;printing-longer-messages&#34;&gt;Printing longer messages&lt;/h3&gt;
&lt;p&gt;In the code above, &lt;code&gt;message&lt;/code&gt; is a symbol whose value is determined by the assembler and inserted into the code where the word appears. Wouldn&amp;rsquo;t it be great if we could update the value of the &lt;code&gt;message&lt;/code&gt; symbol as the program executes, like a variable? The value of &lt;code&gt;message&lt;/code&gt; is written into the machine code, and this code is just bytes in memory. One option is to update the address bytes within the code by writing to the appropriate memory locations, then execute the code. This technique, known as &lt;em&gt;self-modifying code&lt;/em&gt;, is quite common, and not that difficult with a bit of care.&lt;/p&gt;
&lt;p&gt;The following routine accepts the low byte and high byte of the message address in the Y and Z registers, and prints the message until it encounters a 0 byte. It relies on the knowledge that the &lt;code&gt;lda $0000,x&lt;/code&gt; instruction assembles to three bytes: one for the instruction code, and two for the address. It uses the X register as before, but this time it tests whether X wraps around from 255 to 0, then increments the high byte of the address and continues printing. This gives us a maximum message length of 65,535 characters, which is more than enough.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    ldy #&amp;lt;intro_message
    ldz #&amp;gt;intro_message
    jsr print_long_message

; ...

print_long_message:
    ; Y,Z = address
    sty .load_selfmod+1
    stz .load_selfmod+2
    ldx #0
.load_selfmod
    lda $0000,x
    beq .end
    jsr chrout
    inx
    bne .load_selfmod
    inc .load_selfmod+2
    bra .load_selfmod
.end
    rts

intro_message:
!pet 147,14,5,27,&amp;#34;8&amp;#34;  ; clear, lowercase, white, 80x25
!pet &amp;#34;robotfindskitten in MEGA65 assembly language&amp;#34;,13
!pet &amp;#34;Based on the game by the illustrious Leonard Richardson (C) 1997, 2000&amp;#34;,13
!pet &amp;#34;Press Return to start.&amp;#34;,0&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;changing-the-cursor-location&#34;&gt;Changing the cursor location&lt;/h3&gt;
&lt;p&gt;Another useful KERNAL routine for printing is the &lt;code&gt;plot&lt;/code&gt; routine, at $FFF0. &lt;code&gt;plot&lt;/code&gt; can do two things: it can either move the cursor to given coordinates, or it can report the coordinates of the cursor&amp;rsquo;s location. You use the carry flag to choose between the two actions. To move the cursor, clear the carry flag (&lt;code&gt;clc&lt;/code&gt;), then set the X register to the column number and the Y register to the row number.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;plot = $fff0

    clc
    ldx #12
    ldy #1
    jsr plot&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To ask &lt;code&gt;plot&lt;/code&gt; to report the current location, set the carry flag (&lt;code&gt;sec&lt;/code&gt;) before calling it. Instead of changing the cursor position, &lt;code&gt;plot&lt;/code&gt; will overwrite the values in the X and Y registers with the current cursor location.&lt;/p&gt;
&lt;p&gt;A word of caution: When the KERNAL print system prints a character in the bottom-right corner of the screen, it assumes that more text needs to appear on the following line, and scrolls the text display to make room. When plotting characters for game graphics, this probably isn&amp;rsquo;t what you want. A simple albeit unsatisfying way to avoid this issue is to never print a character in the bottom-right corner.&lt;/p&gt;
&lt;h3 id=&#34;accessing-screen-memory&#34;&gt;Accessing screen memory&lt;/h3&gt;
&lt;p&gt;You could make a robotfindskitten game using just the KERNAL print system: use &lt;code&gt;plot&lt;/code&gt; and &lt;code&gt;chrout&lt;/code&gt; with PETSCII codes to draw items, and erase and draw the robot character as it moves across the screen. Most games don&amp;rsquo;t use the KERNAL print system to plot characters at all. Instead, they write directly to screen memory, color memory, and registers in the VIC-IV chip. This avoids issues like the KERNAL scrolling the text display, at the expense of doing other things manually, such as calculating memory locations for screen coordinates, and managing character attributes and colors.&lt;/p&gt;
&lt;p&gt;If your program uses the KERNAL print routines, it&amp;rsquo;s best to let the KERNAL manage screen memory as much as possible. The KERNAL uses internal variables to keep track of some screen properties, and these need to be consistent with its own understanding of the state of the video hardware. If you change the screen mode or relocate screen memory via VIC-IV registers without telling the KERNAL, actions performed by PETSCII codes, such as clearing the screen, may not function correctly.&lt;/p&gt;
&lt;p&gt;Handling screen memory is an essential skill for assembly language programmers. It&amp;rsquo;s also a deep topic. So let&amp;rsquo;s limit this discussion of screen memory to a few salient facts. To tell the KERNAL to set the screen mode to 80 x 25 text, print the &lt;kbd&gt;Escape&lt;/kbd&gt; + &lt;kbd&gt;8&lt;/kbd&gt; key sequence with &lt;code&gt;chrout&lt;/code&gt;, as if you were typing it at the &lt;code&gt;READY&lt;/code&gt; prompt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    lda #27  ; Escape
    jsr chrout
    lda #&amp;#39;8&amp;#39; ; PETSCII &amp;#34;8&amp;#34;
    jsr chrout&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&amp;rsquo;re not using the KERNAL, you can select the screen mode with flag registers at location $D031. To get 80 x 25, clear the V400 register (bit 3) and set the H640 register (bit 7). Without the KERNAL, you will need to write your own message printing routines that write directly to screen memory; you can&amp;rsquo;t use &lt;code&gt;chrout&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The starting address of screen memory is in a VIC-IV register known as SCRNPTR, a 28-bit value stored at $D060-$D063, least significant byte first. The KERNAL will set this when you print the escape sequence for the screen mode. If you&amp;rsquo;re not using the KERNAL, you can set this to any address you like in the first 384K of memory by writing its address into the registers.&lt;/p&gt;
&lt;p&gt;The KERNAL&amp;rsquo;s preferred memory location for a 40 x 25 or 80 x 25 screen is address $0800. Strictly speaking, this is not a documented fact: a program that relies on the KERNAL&amp;rsquo;s setting must read it from SCRNPTR, and never assume its value. For propriety, the examples below will read the SCRNPTR value instead of assuming it, but—at least for now—I&amp;rsquo;m also relying on the fact that the address is within bank 0 (addresses $0000 to $FFFF) so we can use 16-bit addressing modes and don&amp;rsquo;t have to worry about accessing upper memory. Note that this won&amp;rsquo;t work with 80 x 50 text mode, because the KERNAL relocates screen memory to bank 1 for this mode.&lt;/p&gt;
&lt;p&gt;As with BASIC&amp;rsquo;s &lt;code&gt;T@&amp;amp;()&lt;/code&gt; special array, screen memory contains &lt;a href=&#34;https://sta.c64.org/cbm64scr.html&#34;&gt;screen codes&lt;/a&gt; that represent the characters in the character set. The codes are organized in columns then rows, from top-left to bottom-right: the first 80 bytes are the top row, the next 80 bytes are the next row, and so on, for 80 x 25 = 2,000 bytes.&lt;/p&gt;
&lt;p&gt;The following example uses the self-modifying code technique to store a value in screen memory. The &lt;code&gt;sta&lt;/code&gt; instruction can only operate on 16-bit addresses, so it uses the lower two bytes of SCRNPTR, and assumes the upper bytes are zero (an address in bank 0).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;scrnptr = $d060

    ; Use self-modification to write to the (16-bit, bank 0) SCRNPTR address
    lda scrnptr
    sta store_screen_selfmod+1
    lda scrnptr+1
    sta store_screen_selfmod+2

    lda #1     ; Screen code for the letter A
store_screen_selfmod
    sta $0000&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;color-memory&#34;&gt;Color memory&lt;/h3&gt;
&lt;p&gt;In the regular text mode, color memory stores the foreground color and attributes for each character on the screen, organized in the same way. One way to access color memory is starting at address $D800.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s one issue, though. By default, only the first 1K of color memory is visible here, from $D800 to $DBFF. That&amp;rsquo;s not enough for all 2,000 characters of a 80 x 25 display! This is solved by yet another of the MEGA65&amp;rsquo;s many modes. The CRAM2K register, bit 0 of $D030, swaps the registers from $DC00 to $DFFF with the remaining color memory. To do this, it hides other hardware registers normally at those locations, such as the CIA chip registers. The KERNAL expects to see the registers here and not color memory, so you must clear the bit before calling KERNAL routines. (The KERNAL IRQ is smart enough to stash and restore your CRAM2K setting, so you do not need to disable interrupts. That&amp;rsquo;s a topic for another time.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cram2k = $d030
color_mem = $d800

    lda #%00000001  ; Enable CRAM2K
    tsb cram2k
    
    lda #5          ; Paint the A green
    sta color_mem

    lda #%00000001  ; Restore registers
    trb cram2k&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;from-coordinates-to-screen-memory-addresses&#34;&gt;From coordinates to screen memory addresses&lt;/h3&gt;
&lt;p&gt;Given screen coordinates of column X and row Y, the offset into screen memory for that coordinate is Y times 80, plus X. The CPU doesn&amp;rsquo;t have an instruction that can multiple any two numbers, but it does have a quick and easy way to multiply a number by two: it can shift the bits of a number to the left, using the Arithmetic Shift Left instruction (&lt;code&gt;asl&lt;/code&gt;). If it&amp;rsquo;s not clear that shifting the bits of a number to the left multiply it by two, write out a binary number, then write a zero at the end. For example, the binary number %0110 is 2 + 4 = 6 in decimal. Write a zero at the end, and it becomes %01100, which is 4 + 8 = 12 in decimal. Just as writing a zero at the end of a decimal (base ten) number multiplies the number by ten, writing a zero at the end of a binary (base two) number multiplies it by two.&lt;/p&gt;
&lt;p&gt;Using a combination of left-shift and addition operations, we can calculate the screen memory address for a given set of coordinates in three steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Calculate the row offset from the Y coordinate, stored in a memory variable (&lt;code&gt;row_offset&lt;/code&gt;), using bit shift and addition operations to multiply Y by 80.&lt;/li&gt;
&lt;li&gt;Add the base address and the row offset, stored in the address part of a &lt;code&gt;sta ...,x&lt;/code&gt; instruction (self-modifying code).&lt;/li&gt;
&lt;li&gt;Use X-indexing with the X coordinate, to determine the final address and set the screen code.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;row_offset: !byte 0,0

plot_char:
    ; Pre-condition:
    ; - A is the screen code
    ; - X register is the X coordinate
    ; - Y register is the Y coordinate
    
    taz         ; Stash the screen code in Z, so
                ; we can use A for other things
    
    lda scrnptr
    sta store_screen_selfmod+1
    lda scrnptr+1
    sta store_screen_selfmod+2

do_plot:
    ; - Z is the value to store in memory

    ; Calculate Y * 80 into row_offset memory variable
    lda #0
    sta row_offset+1 ; reset row_offset&amp;#39;s high byte
    tya
    sta row_offset   ; store the row number as row_offset&amp;#39;s low byte
    asl              ; x2
    asl              ; x4
    adc row_offset   ; x5
    sta row_offset
    asw row_offset   ; x10
    asw row_offset   ; x20
    asw row_offset   ; x40
    asw row_offset   ; x80

    ; Add row_offset to store_screen_selfmod+1
    lda store_screen_selfmod+1
    clc
    adc row_offset
    sta store_screen_selfmod+1
    lda store_screen_selfmod+2
    adc row_offset+1  ; add with carry
    sta store_screen_selfmod+2

store_screen_selfmod:
    stz $0000,x

    rts&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To update color memory, the only difference in this routine would be to use a different base address, and set CRAM2K while updating memory. I added a &lt;code&gt;do_plot&lt;/code&gt; label above so I could share the common code between the two routines.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;color_char:
    ; Pre-condition:
    ; - A is the color
    ; - X register is the X coordinate
    ; - Y register is the Y coordinate

    taz        ; Stash the color code in Z, so
               ; we can use A for other things

    lda #&amp;lt;color_mem
    sta store_screen_selfmod+1
    lda #&amp;gt;color_mem
    sta store_screen_selfmod+2

    lda #%00000001  ; Enable CRAM2K
    tsb cram2k

    jsr do_plot
    
    lda #%00000001  ; Restore registers
    trb cram2k

    rts&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;base-page-indirect-addressing&#34;&gt;Base Page Indirect Addressing&lt;/h3&gt;
&lt;p&gt;Each machine code instruction that accesses memory can operate in one or more &lt;em&gt;addressing modes,&lt;/em&gt; ways for the CPU to figure out what address to use. We&amp;rsquo;ve seen three addressing modes in the examples so far:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Immediate mode:&lt;/strong&gt; use the value given in the instruction. This example loads the number 7 from the instruction into the accumulator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    lda #7&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Absolute mode:&lt;/strong&gt; use the 16-bit address given in the instruction. This example loads the value stored at address $20CF into the accumulator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    lda $20cf&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Absolute X-indexed mode:&lt;/strong&gt; take the given 16-bit address, then add the value from the X register to it, and use that as the address. This example sets the X register to $2F, then loads the value stored at the address calculated as $20CF plus the value in the X register ($20CF + $2F = $20FE) into the accumulator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    ldx #$2f
    lda $20cf,x&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The X register can contain a value from 0 to 255, which limits the range of the X-indexed addressing mode. Earlier, I used self-modifying code to get around this problem, allowing for performing calculations on the entire address. The following example rewrites the 16-bit address portion of an instruction that&amp;rsquo;s using absolute mode addressing, then executes the modified instruction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    lda #$cf
    sta .selfmod+1
    lda #$20
    sta .selfmod+2

.selfmod:
    lda $0000&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Writing the address directly into an instruction like this is only really practical if only one instruction needs the address, and the modifying code knows exactly which address to modify. In many cases, it&amp;rsquo;d be better if we could store the address in one memory location like a variable, then tell the instructions where to find it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Base Page Indirect Addressing mode&lt;/strong&gt; can do exactly that. This example stores a 16-bit address at memory location $10-$11, then accesses it using the Y register as an index:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    lda #$cf
    sta $10
    lda #$20
    sta $11
  
    ldy #0
    lda ($10),y&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So why didn&amp;rsquo;t I do this earlier? Well, there&amp;rsquo;s a catch: the address must be written to the &lt;em&gt;base page,&lt;/em&gt; a region of 256 bytes that gets special treatment. Commodore 64 programmers know this as the &lt;em&gt;zero page&lt;/em&gt;, within the addresses $0000 to $00FF. The CPU uses special forms of its instructions to access these addresses faster and with more compact code than absolute 16-bit addresses, so the base page is a great place to put variables. It&amp;rsquo;s so useful, in fact, that the KERNAL claims &lt;em&gt;all&lt;/em&gt; of the zero page for its own use. If your program uses the KERNAL, you must protect the zero page so that it&amp;rsquo;s the way the KERNAL left it by the time you call a KERNAL routine.&lt;/p&gt;
&lt;p&gt;With the original 6502 CPU, the base page is always at address $0000 (hence the name &amp;ldquo;zero page&amp;rdquo;). The 65CE02 CPU (on which the MEGA65&amp;rsquo;s 45GS02 is based) adds a feature that lets you use any 256-byte page of the first 64K of memory as the base page. The B register holds the top two nibbles (two hexadecimal digits) of the address of the base page. Your program can stake out its own base page and set the B register to that location to use it. I recommend page B = $16 ($1600 to $16FF), which is reserved for use by your program.&lt;/p&gt;
&lt;p&gt;You must change B back to $00 before calling a KERNAL routine. The base page being set to $00 is a pre-condition of all KERNAL routines. (The B register is preserved along with other registers during interrupt handling, so you don&amp;rsquo;t have to worry about confusing the KERNAL IRQ.)&lt;/p&gt;
&lt;p&gt;To set the B register, put the desired value in the accumulator, then use the &lt;code&gt;tab&lt;/code&gt; instruction (Transfer A to B). If you need to read the B register, transfer it back to the accumulator first, with &lt;code&gt;tba&lt;/code&gt;. The requirement to go through A to set or read B sometimes requires a bit of register wrangling.&lt;/p&gt;
&lt;p&gt;Another register consideration to keep in mind: Base Page Indirect Addressing always uses an index register. The &lt;code&gt;lda&lt;/code&gt; instruction supports using the Y or Z registers as indexes for this mode. If you just want to use the address directly, you must set the index register to 0.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s another version of the long message printer using Base Page Indirect addressing, preserving the zero page for the KERNAL and using page $16 for the program&amp;rsquo;s base page. Try to follow which register has which value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print_long_message_2:
    ; Y,Z = address
    lda #$16   ; A = $16
    tab        ; B = $16
    sty $00    ; $1600-$1601 = the message address
    stz $01
    ldy #0     ; Y = 0
.loop
    lda ($00),y  ; Load a character from the message address + Y
    beq .end     ; If the value is 0, end.
    tax          ; Stash the character in X so we can use A to set B.
    lda #0       ; A = 0
    tab          ; B = 0
    txa          ; A = the character
    jsr chrout
    lda #$16      ; A = 16
    tab          ; B = 16
    iny          ; Y = Y + 1
    bne .loop    ; If Y hasn&amp;#39;t rolled over to 0, continue.
    inc $01      ; Y rolled over, so increment the high byte of the message address.
    bra .loop    ; Continue.
.end
    lda #0
    tab
    rts&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is not necessarily better than the earlier version using self-modifying code, especially with all the register flipping required. But it illustrates the use of base page variables as address pointers.&lt;/p&gt;
&lt;p&gt;The 45GS02 CPU has another Base Page Indirect addressing mode, and it&amp;rsquo;s super useful: &lt;strong&gt;32-bit Base Page Indirect Addressing&lt;/strong&gt; lets you use a 32-bit address instead of a 16-bit address. With the Acme assembler in MEGA65 mode, this is indicated using square brackets instead of parentheses. Only the Z register is supported as the index in this mode.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    lda #$16
    tab

    ; Store the address $0001.F800 at base page address $00-$03
    lda #$00
    sta $00
    lda #$F8
    sta $01
    lda #$01
    sta $02
    lda #$00
    sta $03

    ; Store the value 7 at $0001.F800
    lda #7
    ldz #0
    sta [$00],z&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that other addressing modes do not support 32-bit addresses, so we can&amp;rsquo;t use the self-modifying code method to access upper memory, at least not in the same way. We can adapt the second version of the printing routine to be able to print long messages from anywhere in the MEGA65&amp;rsquo;s memory with minimal changes, but we can&amp;rsquo;t adapt the first version as easily.&lt;/p&gt;
&lt;p&gt;Earlier, I made a potentially unsafe assumption that the KERNAL used an address between $0000 and $FFFF for SCRNPTR in 80 x 25 mode, and I just ignored the upper bytes of the SCRNPTR address. With 32-bit base page indirect addressing, I don&amp;rsquo;t have to do that: I can just copy the entire address from SCRNPTR to a four-byte base page variable, then use 32-bit indirect addressing to access screen memory.&lt;/p&gt;
&lt;p&gt;Incidentally, upper memory addresses $1.F800 through $1.FFFF are another way to access the first 2K of color memory, with no need to set the CRAM2K flag. In my implementation of robotfindskitten, I use base page $16 for variable storage, and base page indirect addressing for plotting characters with the full four-byte SCRNPTR address and for plotting colors to 1.F800. I set the B register to $16 at the beginning of the program, and wrap my KERNAL calls to set B to $00 before the call and set it back to $16 afterward.&lt;/p&gt;
&lt;p&gt;As you can see, there are multiple ways to accomplish certain tasks. For high speed applications, you may need to make your choices based on the amount of CPU time each operation takes, measured in CPU cycles. Instruction cycle counts are listed in the manual. robotfindskitten is not speed critical, so I just went with what made my code easiest for me to understand.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;That&amp;rsquo;s a good start. With the KERNAL output routines and screen memory access, we have the tools to replicate BASIC&amp;rsquo;s &lt;code&gt;PRINT&lt;/code&gt;, &lt;code&gt;T@&amp;amp;()&lt;/code&gt;, and &lt;code&gt;C@&amp;amp;()&lt;/code&gt; facilities in assembly language. Next month, we&amp;rsquo;ll look at another important KERNAL facility for accepting keyboard input, and some snazzy MEGA65 hardware features for generating random numbers and measuring time. We&amp;rsquo;ll close by designing data structures to access all of the item descriptions, and prevent two items from landing on the same place on the screen.&lt;/p&gt;
&lt;p&gt;For comparison and enjoyment, here&amp;rsquo;s my BASIC version of robotfindskitten. It&amp;rsquo;s faithful to Leonard Richardson&amp;rsquo;s version, which is not particularly creative of me, but hopefully it serves as a useful reference implementation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;rfk-bas.prg&#34;&gt;rfk-bas.prg&lt;/a&gt; : robotfindskitten in BASIC 65; &lt;a href=&#34;rfk-bas.txt&#34;&gt;BASIC source code&lt;/a&gt; in petcat format&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy coding! See you next month.&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/robot-finds-kitten-2/M65Digest_2023Nov.mp3" length="38525304" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1926</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/robot-finds-kitten-2/rfk-bas.png"/>
      
    </item>
    
    <item>
      <title>robotfindskitten, part 1</title>
      <link>https://dansanderson.com/mega65/robot-finds-kitten/</link>
      <pubDate>Thu, 12 Oct 2023 22:00:19 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/robot-finds-kitten/</guid>
      <description>&lt;p&gt;robotfindskitten, part 1. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for October 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;robotfindskitten, part 1. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for October 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/robot-finds-kitten/M65Digest_2023Oct.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/M65Digest_2023Oct.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
robotfindskitten.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/rfk_petscii.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten/rfk_petscii.png 500w, https://dansanderson.com/mega65/robot-finds-kitten/rfk_petscii_hu_643083f1f9478dfa.png 600w, https://dansanderson.com/mega65/robot-finds-kitten/rfk_petscii_hu_a3d3a1e8d60ab372.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten/rfk_petscii.png&#34;
        alt=&#34;robotfindskitten&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
robotfindskitten.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A new month, a new feature, a new game, a new demo, and a coding exercise that really brings the room together. Let&amp;rsquo;s dig in!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;available-to-test-new-keyboard-scanner&#34;&gt;Available to test: New keyboard scanner&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/linuxpc.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten/linuxpc.jpeg 3024w, https://dansanderson.com/mega65/robot-finds-kitten/linuxpc_hu_8638ded01941caec.jpeg 600w, https://dansanderson.com/mega65/robot-finds-kitten/linuxpc_hu_7a858a400ea4efdb.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten/linuxpc.jpeg&#34;
        alt=&#34;My new Linux PC for building MEGA65 cores&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;My new Linux PC for building MEGA65 cores.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We&amp;rsquo;re getting closer to having a complete release candidate, with features being finalized and bug fixes piling in. There&amp;rsquo;s one new feature that&amp;rsquo;s near and dear to my heart, and I&amp;rsquo;m thrilled to be able to share it with anyone up for early beta testing.&lt;/p&gt;
&lt;p&gt;The very first thing I noticed when I got my MEGA65 is how the typing experience felt &lt;em&gt;nostalgic.&lt;/em&gt; Even with the new mechanical key switches and the 40 MHz CPU, the ability for the computer to recognize key presses felt exactly like a Commodore 64 did back in the day: sluggish and imprecise. I like nostalgia as much as anybody, but I type much faster today than I did when I was nine years old. I wished my MEGA65 could handle fast typing more like a modern computer, so I could enjoy on-device composition without slowing myself down. It was one of the first feature requests that I filed with the MEGA65 team.&lt;/p&gt;
&lt;p&gt;Paul and company started working on an idea for fast typing, and an early version of the chipset support required made it into the core last year. The feature wasn&amp;rsquo;t wired up to the KERNAL ROM, and only a few built-in applications used it. I brought it up again with the team this summer, and we had many design discussions and tried several ideas. I learned a bit of FPGA coding, and even built a high-speed Linux PC just to build and test new cores and ROMs.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m proud to present the all-new MEGA65 hardware-accelerated keyboard scanner. Using &lt;a href=&#34;https://builder.mega65.org/job/mega65-core/job/development/&#34;&gt;the latest development core&lt;/a&gt; and &lt;a href=&#34;https://files.mega65.org/?id=d4f6ef89-6dbf-4e5b-b23f-7822fc12ff24&#34;&gt;ROM beta release&lt;/a&gt;, you can now enjoy a typing experience that is more accurate and more reliable for fast typists throughout the BASIC screen editor and many applications. These changes will be in the v0.96 release, and you can test it today and &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues&#34;&gt;file any bugs&lt;/a&gt; you find. I also wrote &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/44204033/New+keyboard+scanner+v0.96+feature+candidate&#34;&gt;a test plan and detailed description of how it works&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I plastered this all over the instructions, but I&amp;rsquo;ll repeat it here: the latest ROM beta versions (920387 or later) require the latest development core. If you use the newer ROM with an older core, typing won&amp;rsquo;t work. You &lt;em&gt;can&lt;/em&gt; safely use older ROMs with the newer core, so you can revert to the legacy keyboard scanner at any time if you encounter any issues just by going back to an older ROM (920386 or earlier). Also, the latest ROM betas will not work with the Xemu emulator until emulation for the new core feature has been added (hopefully soon), so stick with 920386 or earlier in Xemu for now.&lt;/p&gt;
&lt;p&gt;For me, the difference with the enhanced typing quality is like night and day. On-device programming and other typing applications are much more usable, and I just enjoy using the computer much more, confident that I won&amp;rsquo;t have to struggle with missed keystrokes. Try it out, and let me know what you think!&lt;/p&gt;
&lt;h2 id=&#34;classy-by-deathy&#34;&gt;Classy, by deathy&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/classy.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten/classy.png 705w, https://dansanderson.com/mega65/robot-finds-kitten/classy_hu_49cbb5143c353580.png 600w, https://dansanderson.com/mega65/robot-finds-kitten/classy_hu_bba0c5c0b490c72d.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten/classy.png&#34;
        alt=&#34;Classy, by deathy&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Classy, by deathy.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=3549b82b-b851-41ec-a8d9-918996a4d2ea&#34;&gt;Classy&lt;/a&gt;, by deathy, is a new match-3 game for the MEGA65. Careful with this one: it&amp;rsquo;s addictive! A joystick in either port or the keyboard sets you on your tile swapping journey. If the game is still running, it means you still have moves remaining. Keep looking!&lt;/p&gt;
&lt;h2 id=&#34;megapple-by-miragebd&#34;&gt;MEGApple, by MirageBD&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/megapple.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten/megapple.png 1108w, https://dansanderson.com/mega65/robot-finds-kitten/megapple_hu_79afecb03bfdb8ee.png 600w, https://dansanderson.com/mega65/robot-finds-kitten/megapple_hu_a6d9c0d0d1551568.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten/megapple.png&#34;
        alt=&#34;MEGApple, by MirageBD&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MEGApple, by MirageBD.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 gets its &lt;a href=&#34;https://en.wikipedia.org/wiki/Bad_Apple!!&#34;&gt;Bad Apple!!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=2b32fbaf-f78b-47db-b919-564eba9ddab1&#34;&gt;MEGApple&lt;/a&gt; is MirageBD&amp;rsquo;s MEGA65 version of the popular demo challenge: recreate &lt;a href=&#34;https://knowyourmeme.com/memes/bad-apple&#34;&gt;the shadow-art music video&lt;/a&gt; of the Japanese pop song, &amp;ldquo;Bad Apple!!&amp;rdquo; &lt;a href=&#34;https://www.youtube.com/watch?v=FtutLA63Cp8&#34;&gt;The original video&lt;/a&gt; was a collaboration of animators on the Japanese website &lt;a href=&#34;https://knowyourmeme.com/memes/sites/niconico&#34;&gt;Nico Nico Douga&lt;/a&gt;, based on the pop remix by &lt;a href=&#34;https://en.wikipedia.org/wiki/Nomico&#34;&gt;nomico&lt;/a&gt; of a track from the video game &lt;a href=&#34;https://en.touhouwiki.net/wiki/Lotus_Land_Story&#34;&gt;Touhou Fantasy Land: Lotus Land Story&lt;/a&gt;. Over a decade later, it persists as a popular meme to recreate the music video in unusual media, including (but not limited to) retro computers.&lt;/p&gt;
&lt;p&gt;To run MEGApple, download and expand the archive, then copy the files to the root of your SD card. Start your MEGA65, then type: &lt;code&gt;MOUNT &amp;quot;MEGAPPLE.D81&amp;quot;:RUN &amp;quot;*&amp;quot;&lt;/code&gt; The program on the D81 disk image loads the data from the other larger files.&lt;/p&gt;
&lt;h2 id=&#34;xevious-new-arcade-core-by-muse&#34;&gt;Xevious, new arcade core by muse&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/xevious.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten/xevious.jpg 625w, https://dansanderson.com/mega65/robot-finds-kitten/xevious_hu_ced60c42d50a29fb.jpg 600w, https://dansanderson.com/mega65/robot-finds-kitten/xevious_hu_a90f975fca6f80ea.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten/xevious.jpg&#34;
        alt=&#34;Xevious arcade cabinet&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Xevious (1982).&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;muse has a new arcade cabinet core for us! &lt;a href=&#34;https://files.mega65.org?id=d32474e9-6f30-48f8-bba3-167cad4bbc4f&#34;&gt;Xevious&lt;/a&gt; (1982) and Super Xevious (1984) are early vertical scrolling shooter games by Namco. Fly your Solvalou starship over the planet&amp;rsquo;s surface to stop the Xevious forces by both land and sky. muse&amp;rsquo;s version supports a one-button joystick with a clever adaptation: press the button quickly to shoot at airborne enemies, and hold the button to drop bombs on turrets.&lt;/p&gt;
&lt;p&gt;As with the Galaga core, &lt;a href=&#34;https://github.com/sho3string/XeviousMEGA65&#34;&gt;the installation instructions&lt;/a&gt; include searching for and downloading the original Xevious ROM files, running a Python script to validate the files and prepare a folder that you copy to your MEGA65&amp;rsquo;s SD card with the path &lt;code&gt;/arcade/xevious&lt;/code&gt;, then installing the core in an available core slot. See &lt;a href=&#34;https://discord.com/channels/719326990221574164/801767398675316756/1161247938543108116&#34;&gt;the Discord announcement&lt;/a&gt; for additional notes.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;robotfindskitten&#34;&gt;robotfindskitten&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Yet another zen simulation.&amp;rdquo;
— &lt;a href=&#34;http://robotfindskitten.org/&#34;&gt;robotfindskitten.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In robotfindskitten, you are a robot, who finds a kitten.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Robotfindskitten&#34;&gt;robotfindskitten&lt;/a&gt; was originally written by &lt;a href=&#34;https://www.crummy.com/self/&#34;&gt;Leonard Richardson&lt;/a&gt; in 1997 for DOS, as his submission to the robotfindskitten contest put on by the webzine &amp;ldquo;Nerth Pork.&amp;rdquo; It took first prize. There were no other entries, but there didn&amp;rsquo;t need to be. The theme had found its perfect expression on the first try.&lt;/p&gt;
&lt;p&gt;In the decades that followed, many have made their own versions of the simulation, on many interactive platforms. And now, it is your turn.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/Robotfindskitten.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/robot-finds-kitten/Robotfindskitten.png 484w, https://dansanderson.com/mega65/robot-finds-kitten/Robotfindskitten_hu_7420633cabfe291d.png 600w, https://dansanderson.com/mega65/robot-finds-kitten/Robotfindskitten_hu_f3a822b620fa923a.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/robot-finds-kitten/Robotfindskitten.png&#34;
        alt=&#34;robotfindskitten, by Leonard Richardson&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
robotfindskitten, by Leonard Richardson
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Richardson&amp;rsquo;s version depicts the robot with a single colored ASCII character on a monospaced field that spans the screen. The field is populated sparsely with other colored ASCII characters that represent many Non-Kitten Items (NKIs), and one kitten. To the robot, all items, including the kitten, appear as random colored characters. The operator uses cursor keys to move the robot around the field. When the robot comes into contact with an item, a message is printed describing the item. If the item is the kitten, the experience ends in joyful celebration.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&#34;http://robotfindskitten.org/play/robotfindskitten/&#34;&gt;play robotfindskitten in your browser&lt;/a&gt;. Or, you can install a version for a modern terminal for Linux (&lt;code&gt;sudo apt install robotfindskitten&lt;/code&gt;) or macOS (&lt;code&gt;brew install robotfindskitten&lt;/code&gt;) or &lt;a href=&#34;http://robotfindskitten.org/aw.cgi?main=software.rfk&#34;&gt;many other platforms&lt;/a&gt;. (Some versions are survived only by their &lt;a href=&#34;http://robotfindskitten.org/shots/&#34;&gt;archived screenshots&lt;/a&gt;.) Or you can &lt;a href=&#34;https://github.com/robotfindskitten/robotfindskitten&#34;&gt;build the Linux version from source&lt;/a&gt;. Or you can check out &lt;a href=&#34;https://www.crummy.com/software/robotfindskitten/&#34;&gt;the Ultimate robotfindskitten Fan Site&lt;/a&gt;, by Leonard himself.&lt;/p&gt;
&lt;p&gt;Or you can make your own. Here are some techniques that you might use to rise to this challenge in BASIC 65. Next month, we&amp;rsquo;ll look at how to do similar things in assembly language.&lt;/p&gt;
&lt;h3 id=&#34;display&#34;&gt;Display&lt;/h3&gt;
&lt;p&gt;You will need to control what is displayed on the screen, so the operator can see the robot and the items.&lt;/p&gt;
&lt;p&gt;To clear the screen of all text, you can use the &lt;code&gt;SCNCLR&lt;/code&gt; command. To set the color of text to be printed (from 0 to 31): &lt;code&gt;COLOR number&lt;/code&gt;. Similarly, to change the color of the border or background: &lt;code&gt;BORDER number&lt;/code&gt; or &lt;code&gt;BACKGROUND number&lt;/code&gt;. To set the position of where the next text will be printed: &lt;code&gt;CURSOR column, row&lt;/code&gt;. To print a string of text at the current cursor position: &lt;code&gt;PRINT string&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;One word of caution with &lt;code&gt;PRINT&lt;/code&gt;: if the string you are printing extends beyond the right edge of the screen, the screen below that point will scroll down by one line. This probably isn&amp;rsquo;t what you want in this exercise, so take care with the length and position of your strings.&lt;/p&gt;
&lt;p&gt;To plot a single character at a set of coordinates, you can assign the &lt;a href=&#34;https://sta.c64.org/cbm64scr.html&#34;&gt;screen code&lt;/a&gt; of the character to the &lt;code&gt;T@&amp;amp;&lt;/code&gt; array, and its color to the &lt;code&gt;C@&amp;amp;&lt;/code&gt; array. These are two dimensional arrays, with the first index referring to the column and the second index referring to the row. &lt;code&gt;T@&amp;amp;(0,0)=1&lt;/code&gt; plots the letter &lt;code&gt;A&lt;/code&gt; to the leftmost topmost position. (1 is the screen code for the &lt;code&gt;A&lt;/code&gt; character. Notice that screen codes are not PETSCII codes.) &lt;code&gt;C@&amp;amp;(0,0)=5&lt;/code&gt; paints it green. You can read screen codes and colors from these arrays as well: &lt;code&gt;IF T@&amp;amp;(0,0)=1 THEN ...&lt;/code&gt; and so forth.&lt;/p&gt;
&lt;p&gt;Recall that &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/&#34;&gt;PETSCII codes in strings&lt;/a&gt; give you further control of the display via the &lt;code&gt;PRINT&lt;/code&gt; command. &lt;code&gt;PRINT CHR$(14)&lt;/code&gt; switches the display to the lowercase character set. Be aware that not all PETSCII graphics characters are available in the lowercase set.&lt;/p&gt;
&lt;p&gt;Here is a short program that clears the screen, switches to lowercase, and plots all of the available screen codes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 COLOR 1
110 SCNCLR
120 PRINT CHR$(14)
130 FOR R=0 TO 3
140 FOR C=0 TO 63
150 T@&amp;amp;(C,R)=R*64+C
160 NEXT C
170 NEXT R
180 CURSOR 0,5&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;input&#34;&gt;Input&lt;/h3&gt;
&lt;p&gt;To accept keyboard input, use either &lt;code&gt;GET variable&lt;/code&gt; or &lt;code&gt;GETKEY variable&lt;/code&gt;. These both take a variable name as their parameter. Given a string variable (such as &lt;code&gt;A$&lt;/code&gt;), the key being pressed is loaded into the variable as a single-character string. Given a number variable (such as &lt;code&gt;A&lt;/code&gt;), it is loaded as a PETSCII code. &lt;code&gt;GETKEY&lt;/code&gt; pauses until a key is pressed. &lt;code&gt;GET&lt;/code&gt; will not wait: if no key is pressed, it assigns an empty string or a zero, and moves on. If you want &lt;code&gt;GET&lt;/code&gt; or &lt;code&gt;GETKEY&lt;/code&gt; to provide the PETSCII code as a number, be sure to use a byte type variable, so that the number is in the range 0 to 255: &lt;code&gt;GET K&amp;amp;&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 GETKEY K&amp;amp;
20 PRINT K&amp;amp;
30 GOTO 10&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alternatively, you can accept joystick input using the &lt;code&gt;JOY()&lt;/code&gt; function. The function takes the port number as an argument (1 or 2), and returns a number 0 through 8 indicating the state of the joystick. 0 says the joystick is centered. All other numbers indicate a direction, starting with 1 for &amp;ldquo;up&amp;rdquo; and going clockwise: 2 for &amp;ldquo;up-right,&amp;rdquo; 3 for &amp;ldquo;right,&amp;rdquo; and so forth.&lt;/p&gt;
&lt;h3 id=&#34;chaos&#34;&gt;Chaos&lt;/h3&gt;
&lt;p&gt;The items are assigned random characters, colors, and positions, so you&amp;rsquo;ll need a way to generate randomness. The &lt;code&gt;RND()&lt;/code&gt; function generates numbers using a pseudo-random number generation algorithm. The function takes an argument that determines the &amp;ldquo;seed&amp;rdquo; for the algorithm. For most purposes, an argument of 1 suffices: &lt;code&gt;RND(1)&lt;/code&gt;. The function evaluates to a random fractional number between 0 and 1. To generate numbers within a range of integers, multiply the result by the size of the range, then take the &lt;code&gt;INT()&lt;/code&gt; of the result to lop off the fractional part. &lt;code&gt;INT(RND(1)*80)&lt;/code&gt; generates a random integer between 0 and 79.&lt;/p&gt;
&lt;p&gt;If you want the range of possible values to start at a value other than zero, do the inner multiplication by the size of the range, then add the starting value. &lt;code&gt;INT(RND(1)*77)+1&lt;/code&gt; generates a random integer between 1 and 77.&lt;/p&gt;
&lt;p&gt;The following program plots randomly colored random characters when one of the cursor keys is pressed. See if you can figure out what the variables &lt;code&gt;CL&lt;/code&gt;, &lt;code&gt;CH&lt;/code&gt;, &lt;code&gt;RL&lt;/code&gt;, and &lt;code&gt;RH&lt;/code&gt; do.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 SCNCLR
110 CL=0:CH=79:RL=0:RH=24
120 GET K&amp;amp;
130 IF K&amp;amp;&amp;lt;&amp;gt;17 AND K&amp;amp;&amp;lt;&amp;gt;29 AND K&amp;amp;&amp;lt;&amp;gt;145 AND K&amp;amp;&amp;lt;&amp;gt;157 THEN 120
140 IF K&amp;amp;=17 THEN RL=12 : REM CURSOR DOWN
150 IF K&amp;amp;=29 THEN CL=40 : REM CURSOR RIGHT
160 IF K&amp;amp;=145 THEN RH=12 : REM CURSOR UP
170 IF K&amp;amp;=157 THEN CH=40 : REM CURSOR LEFT
180 C=CL+INT(RND(1)*(CH-CL))
190 R=RL+INT(RND(1)*(RH-RL))
200 T@&amp;amp;(C,R)=INT(RND(1)*256)
210 C@&amp;amp;(C,R)=INT(RND(1)*16)
220 GOTO 110&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Like the Commodore 64, a positive argument generates a new number based on the previously generated number. Unlike the Commodore 64, the algorithm is initially seeded from the MEGA65&amp;rsquo;s Real-Time Clock during boot, so you are unlikely to see the same sequence twice with &lt;code&gt;RND(1)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tip: For RFK, you probably want to prevent randomly selected values from repeating. A simple way to avoid this is to keep track of previously selected values, such as in an array, and scan the array each time a new value is chosen. If it&amp;rsquo;s in the array, restart the process to pick another value. Once a unique value is found, add it to the end of the array. In my version, I used this technique to avoid two items from appearing at the same location, and to ensure that each item uses a unique PETSCII character and a unique description.&lt;/p&gt;
&lt;h3 id=&#34;calm&#34;&gt;Calm&lt;/h3&gt;
&lt;p&gt;To animate the joyful celebration at the end, you&amp;rsquo;ll need a way to pause between frames of an animation. The &lt;code&gt;SLEEP seconds&lt;/code&gt; command pauses the program for the given number of seconds. The number can be fractional.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 FOR X=1 TO 5
20 PRINT CHR$(211);
30 SLEEP 0.6
40 NEXT X
50 PRINT&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;data&#34;&gt;Data&lt;/h3&gt;
&lt;p&gt;Each Non-Kitten Item in robotfindskitten gets assigned a description at random when the item is created. One way to put a large list of descriptions in a BASIC program is with &lt;code&gt;DATA&lt;/code&gt; statements. These statements don&amp;rsquo;t do anything when encountered by control flow. Instead, they make values available to the &lt;code&gt;READ&lt;/code&gt; statement, which finds the next unread value and puts it in a variable.&lt;/p&gt;
&lt;p&gt;A traditional BASIC technique is to read the number of elements from the first &lt;code&gt;DATA&lt;/code&gt; statement, &lt;code&gt;DIM&lt;/code&gt;ension an array of that size, then &lt;code&gt;READ&lt;/code&gt; that many elements into the array. The program can then access any string from the array by its number index. This is a bit wasteful. It keeps two copies of the list in memory: one in the BASIC program listing, and another in variable memory. It also introduces a delay at the beginning of the program to load all of the elements into the array. The primary advantage is that each element can be accessed instantly by index.&lt;/p&gt;
&lt;p&gt;In BASIC 65 (and BASIC 7 for the Commodore 128), there&amp;rsquo;s a better way: use sequential line numbers for the &lt;code&gt;DATA&lt;/code&gt; statements, then use the &lt;code&gt;RESTORE&lt;/code&gt; command to set the &lt;code&gt;READ&lt;/code&gt; pointer to a given line number. &lt;code&gt;RESTORE&lt;/code&gt; accepts a number expression for the line number, so you can select a string programmatically by number.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 READ N
20 K=INT(RND(1)*N)+1
30 RESTORE 1000+K
40 READ NK$
50 PRINT NK$
60 GETKEY A$
70 GOTO 20
1000 DATA 5
1001 DATA &amp;#34;THAT&amp;#39;S JUST AN OLD TIN CAN.&amp;#34;
1002 DATA &amp;#34;IT&amp;#39;S AN ALTAR TO THE HORSE GOD.&amp;#34;
1003 DATA &amp;#34;A BOX OF DANCING MECHANICAL PENCILS. THEY DANCE! THEY SING!&amp;#34;
1004 DATA &amp;#34;IT&amp;#39;S AN OLD DUKE ELLIGTON RECORD.&amp;#34;
1005 DATA &amp;#34;A BOX OF FUMIGATION PELLETS.&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A &lt;code&gt;DATA&lt;/code&gt; statement has a special syntax to allow for string values that contain almost any character: values are separated with commas, and a value that starts with a double-quote contains every character (including commas) up to the next double-quote. This requires special handling if you want a string value to contain a double-quote character. Because NKI descriptions only use letters, numbers, and punctuation, one solution is to use a special character as a substitute for double-quotes, then replace it in code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;41 FOR I=1 TO LEN(NK$)
42 IF MID$(NK$,I,1)=&amp;#34;£&amp;#34; THEN MID$(NK$,I,1)=CHR$(34)
43 NEXT I

1000 DATA 6

1006 DATA &amp;#34;IT&amp;#39;S A DVD OF £CROUCHING MONKEY, HIDDEN KITTEN£, REGION ENCODED FOR THE MOON.&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use &lt;a href=&#34;https://www.crummy.com/software/robotfindskitten/nki/vanilla.nki&#34;&gt;the original list of 406 NKI descriptions&lt;/a&gt;, or write your own. The truly patient can type all of these into &lt;code&gt;DATA&lt;/code&gt; statements by hand, a zen experience of its own. Or you can use one of these that I made for you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/nkis_upper.bas&#34;&gt;nkis_upper.bas&lt;/a&gt; / &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/nkis_upper.prg&#34;&gt;nkis_upper.prg&lt;/a&gt; : uppercase character set&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/nkis_lower.bas&#34;&gt;nkis_lower.bas&lt;/a&gt; / &lt;a href=&#34;https://dansanderson.com/mega65/robot-finds-kitten/nkis_lower.prg&#34;&gt;nkis_lower.prg&lt;/a&gt; : lowercase character set&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;structure&#34;&gt;Structure&lt;/h3&gt;
&lt;p&gt;Your program will have at least a few phases of operation, such as one to decide on the locations and appearances of the items, and another where the player is moving the robot. Each phase will be a section of lines in your program. BASIC executes lines in a given section to produce the experience of that phase. To transition from one phase to another, the program directs BASIC to &lt;code&gt;GOTO&lt;/code&gt; a line in the appropriate section.&lt;/p&gt;
&lt;p&gt;I based my RFK experience on Richardson&amp;rsquo;s version, which can be described as four phases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Introduction.&lt;/strong&gt; Display an intro message, then wait for a keypress. When a key is pressed, proceed to phase 2.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Initialization.&lt;/strong&gt; Set up and draw the items on the screen, set the initial robot position. When complete, proceed to phase 3.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Game loop.&lt;/strong&gt; Listen for player input, move the robot, display NKI descriptions. When the robot finds the kitten, proceed to phase 4.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ending.&lt;/strong&gt; Animate the joyful experience, then wait for a keypress. When a key is pressed, return to phase 1.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My program code also ends with the NKI descriptions as a fifth section of data statements. Control never reaches this section, because &lt;code&gt;DATA&lt;/code&gt; statements do not need to be performed like other commands. (The &lt;code&gt;READ&lt;/code&gt; statement in an earlier section accesses this data.)&lt;/p&gt;
&lt;p&gt;One of the best things about BASIC is how it makes it easy to write and test each section separately. To start a section from the &lt;code&gt;READY.&lt;/code&gt; prompt, provide the first line number to the &lt;code&gt;RUN&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RUN 300&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can temporarily add a &lt;code&gt;STOP&lt;/code&gt; statement in the program to cause execution to return to the &lt;code&gt;READY.&lt;/code&gt; prompt at that point. You can use commands to inspect the state of program variables, such as: &lt;code&gt;?NK$&lt;/code&gt; When you are ready to resume execution of the program, type the &lt;code&gt;CONT&lt;/code&gt; command. You can even assign new values to variables while paused, and it&amp;rsquo;ll use the new values when you continue the program. Don&amp;rsquo;t forget to remove the &lt;code&gt;STOP&lt;/code&gt; statements when you no longer need them.&lt;/p&gt;
&lt;h3 id=&#34;when-youre-finished&#34;&gt;When you&amp;rsquo;re finished&lt;/h3&gt;
&lt;p&gt;As amusing as it would be for everyone to upload their RFK experiences to Filehost, that might not be the most polite use of the site. Let&amp;rsquo;s do this instead: &lt;a href=&#34;mailto:contact@dansanderson.com&#34;&gt;send me a photo or screenshot of your robotfindskitten experience&lt;/a&gt;. I will try to feature a selection of submitted photos in an upcoming issue of the Digest.&lt;/p&gt;
&lt;p&gt;If you have any questions about BASIC programming or would like to discuss the exercise, let&amp;rsquo;s meet up in the &lt;code&gt;#basic&lt;/code&gt; channel of &lt;a href=&#34;https://mega65.org/chat&#34;&gt;the Discord chat&lt;/a&gt;. I&amp;rsquo;m usually there.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Next month, I&amp;rsquo;ll share my BASIC RFK implementation, and we&amp;rsquo;ll look at similar tools for making an RFK game in assembly language. See you then!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/robot-finds-kitten/M65Digest_2023Oct.mp3" length="24165271" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1208</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/robot-finds-kitten/rfk_petscii.png"/>
      
    </item>
    
    <item>
      <title>Survey 2023 Results!</title>
      <link>https://dansanderson.com/mega65/mega65-survey-2023-results/</link>
      <pubDate>Sat, 16 Sep 2023 02:00:53 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/mega65-survey-2023-results/</guid>
      <description>&lt;p&gt;Survey 2023 Results. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for September 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Survey 2023 Results. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for September 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/mega65-survey-2023-results/M65Digest_2023Sept.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023-results/M65Digest_2023Sept.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
The MEGA65 Community Survey 2023.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023-results/m65survey_banner.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mega65-survey-2023-results/m65survey_banner.png 500w, https://dansanderson.com/mega65/mega65-survey-2023-results/m65survey_banner_hu_136c6a40c4f79b42.png 600w, https://dansanderson.com/mega65/mega65-survey-2023-results/m65survey_banner_hu_88a1150c05877b6.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-survey-2023-results/m65survey_banner.png&#34;
        alt=&#34;MEGA65 Community Survey 2023 banner&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Survey 2023 Results
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 Community Survey 2023 is now complete! It opened on August 14, ran for three weeks, and received 509 submissions. &lt;em&gt;A HUGE thank you&lt;/em&gt; to everyone who submitted!&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s do a quick update, then onto the results!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;release-testing-update&#34;&gt;Release testing update&lt;/h2&gt;
&lt;p&gt;We do not yet have a formal release candidate for the upcoming v0.96 release, which is intended to be the factory installed release for the next delivery batch. We are still waiting on test hardware for the revision 5 main board to arrive. Once it does, we will clean up the changes and document a formal test process that you can try on your own computer.&lt;/p&gt;
&lt;p&gt;In the meantime, we&amp;rsquo;re sharing out early test plans for some major features. Before I get you all excited about early availability, please know that what&amp;rsquo;s currently available is &lt;em&gt;not&lt;/em&gt; the release candidate. By definition, development versions are riskier than release candidates, and do not necessarily represent what will be in the release candidate.&lt;/p&gt;
&lt;p&gt;In particular, &lt;em&gt;do not attempt to flash a development core to slot 0&lt;/em&gt; unless you own a JTAG adapter and know how to use it to recover from a broken state. Keep a stable core in slot 0, and use any other slot for the development core. We&amp;rsquo;re working on making it safer to upgrade slot 0 without a JTAG adapter, but this is not yet ready for testing by people that don&amp;rsquo;t actually have one.&lt;/p&gt;
&lt;p&gt;While it is possible to have multiple MEGA65 cores installed and switch between them, this is not the case for system software files (&lt;code&gt;.M65&lt;/code&gt; files) on the SD card. We haven&amp;rsquo;t noticed any issues using newer system software with the earlier stable core, but keep this in mind while troubleshooting issues.&lt;/p&gt;
&lt;p&gt;Here are the development builds of the platform components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://builder.mega65.org/job/mega65-core/job/development/&#34;&gt;mega65-core development builds&lt;/a&gt;; the &lt;code&gt;mega65r3&lt;/code&gt; build is for production units and DevKits&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://builder.mega65.org/job/mega65-tools/job/development/&#34;&gt;mega65-tools development builds&lt;/a&gt;; macOS versions can be built from &lt;a href=&#34;https://github.com/mega65/mega65-tools/tree/development&#34;&gt;the development branch of the repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=d4f6ef89-6dbf-4e5b-b23f-7822fc12ff24&#34;&gt;Latest ROM beta release&lt;/a&gt; (owner registration required); &lt;a href=&#34;https://files.mega65.org?id=22f1eb6c-3df5-43c4-a584-e8212fc80b9d&#34;&gt;patch files&lt;/a&gt; (free access, &lt;a href=&#34;https://files.mega65.org?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;patching instructions&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;available-to-test-ethernet-file-transfer&#34;&gt;Available to test: Ethernet file transfer&lt;/h3&gt;
&lt;p&gt;You are invited to help test Ethernet file transfer, a feature in the development version of the core and tools. See &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/29327361/Ethernet+tools+mega65+ftp+and+etherload&#34;&gt;these instructions for testing Ethernet-based file transfer&lt;/a&gt;. You&amp;rsquo;ll want to be familiar with your PC&amp;rsquo;s command line interface, as the file transfer tools are currently only available in command line form.&lt;/p&gt;
&lt;p&gt;A few things to notice:&lt;/p&gt;
&lt;p&gt;The core download includes a new system software file, &lt;code&gt;ETHLOAD.M65&lt;/code&gt;, so be sure to copy that file to the SD card.&lt;/p&gt;
&lt;p&gt;This feature exposes the MEGA65 to be controlled remotely by another computer over a network. As a safety measure, the feature is locked by a DIP switch on the main board. You will need to open the case to set DIP switch #2 to the &amp;ldquo;on&amp;rdquo; position.&lt;/p&gt;
&lt;p&gt;You can connect your MEGA65 to your local network router, or directly to a PC using an Ethernet cable. You provide the file transfer tool with an available IP address on your local network, so you will need to know how your local network or PC networking settings are configured. Typically, the IP address of your computer&amp;rsquo;s network interface and the subnet mask together indicate the IP address range for the local network. When using a router, you will need to configure your router to reserve an IP address for the MEGA65, so that it doesn&amp;rsquo;t assign it to another device. (The MEGA65 doesn&amp;rsquo;t support DHCP directly.)&lt;/p&gt;
&lt;p&gt;You enable a remote control session on the MEGA65 by pressing the &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Pound&lt;/kbd&gt; key combination. The power light will blink to indicate that it is listening to the network. You can then run the &lt;code&gt;mega65_ftp&lt;/code&gt; command-line tool to transfer files.&lt;/p&gt;
&lt;p&gt;Give it a go, and ask questions in the &lt;a href=&#34;https://discord.com/channels/719326990221574164/1141635435702014014&#34;&gt;Ethernet Tools Testing thread&lt;/a&gt; on Discord.&lt;/p&gt;
&lt;h3 id=&#34;available-for-review-users-guide-2nd-edition&#34;&gt;Available for review: User&amp;rsquo;s Guide, 2nd edition&lt;/h3&gt;
&lt;p&gt;The next delivery batch will include a fresh printing of the User&amp;rsquo;s Guide. We&amp;rsquo;ve taken this opportunity to overhaul the Guide, update it with new information for the v0.96 release and R5 main board, and do a cover-to-cover editing pass over the whole thing including the BASIC reference. The BASIC quick reference card has also been updated, and there&amp;rsquo;s a snazzy new cover image. There are a few remaining to-do items related to features that are still in progress.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://builder.mega65.org/job/mega65-user-guide/job/master/lastSuccessfulBuild/artifact/mega65-userguide.pdf&#34;&gt;Download the latest User&amp;rsquo;s Guide PDF&lt;/a&gt;, &lt;a href=&#34;https://github.com/MEGA65/mega65-user-guide/issues&#34;&gt;file documentation issues on Github&lt;/a&gt;, and discuss in the &lt;a href=&#34;https://discord.com/channels/719326990221574164/720355877701550131&#34;&gt;#manual channel&lt;/a&gt; on the Discord.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;mega65-community-survey-2023-results&#34;&gt;MEGA65 Community Survey 2023 Results&lt;/h2&gt;
&lt;p&gt;The following report attempts to summarize results while preserving the anonymity of respondents. Free text responses will be kept private and will not be quoted verbatim in this report. I will be summarizing based on my own judgement, and I will withhold outliers to preserve privacy. Please know that even if your opinion doesn&amp;rsquo;t seem represented in the report, your free text responses will still be read by the MEGA65 team.&lt;/p&gt;
&lt;p&gt;I will attempt to base conclusions on numerical data where possible. Interpretation of free text responses will inevitably be biased. This bias reflects on me and not the opinions of the MEGA65 team. Similarly, I designed the survey and am solely responsible for flaws and biases in the way questions were structured and worded. This will be pretty casual.&lt;/p&gt;
&lt;h2 id=&#34;owners-and-non-owners&#34;&gt;Owners and non-owners&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;images/owner___preordered___considering___no_interest.png&#34; alt=&#34;Owner / Preordered / Considering / No interest&#34;&gt;&lt;/p&gt;
&lt;p&gt;The survey asked respondents whether they currently own a MEGA65, have one on preorder, are still considering placing an order, are not considering an order, or may have previously owned a MEGA65 and no longer do. Owners were shown additional questions about the configuration of their machine. Non-owners were given additional opportunities to explain their interests and concerns.&lt;/p&gt;
&lt;p&gt;This is a control question for interpreting other responses, and is not a useful indicator of a single population on its own. The relative sizes of the categories only describe the response pool, not the MEGA65 community at large. The survey was promoted in various channels that tend to skew variously towards owners (such as the Digest, Discord) or non-owners (such as Commodore user groups), and non-owners were encouraged to reply, with the rough guidance that anyone who has heard about the MEGA65 is invited.&lt;/p&gt;
&lt;p&gt;When the survey was sent, approximately 900 MEGA65s had been delivered. This helps extrapolate potential population counts from a sample of the owner category. 218 respondents said they own a MEGA65, which is 24% of all owners. In contrast, there is no good way to extrapolate answers from a sample of non-owners to a larger population.&lt;/p&gt;
&lt;p&gt;For some questions asked of all respondents, ownership status has a natural influence on responses. Someone is more likely to engage with community resources after they have received their computer. For example, 86% of current owners said they are aware of the Xemu emulator, compared to 58% of respondents who have not yet placed an order.&lt;/p&gt;
&lt;p&gt;I will try to separate results by ownership status where there appears to be significant difference. &lt;em&gt;This does not intend to imply that responses from any particular group are more or less important.&lt;/em&gt; There are many non-owners that make major contributions to the community, as well as owners that have not yet engaged with the project. Grouping is merely a crude way to control for differences in sampling.&lt;/p&gt;
&lt;h2 id=&#34;whats-interesting-about-the-mega65&#34;&gt;What&amp;rsquo;s interesting about the MEGA65&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;images/what_about_the_mega65_interests_you_.png&#34; alt=&#34;What about the MEGA65 interests you?&#34;&gt;&lt;/p&gt;
&lt;p&gt;The survey offered a list of possible reasons why someone might be interested in the MEGA65 project, and asked for zero or more selections. Raw data from multi-select questions can be difficult to interpret, especially when the question is phrased like a buffet of ideas or desires. The survey could have asked respondents to rank these, or pick a primary reason, but that felt too limiting.&lt;/p&gt;
&lt;p&gt;Many respondents are interested in collecting vintage computers, reproducing the experience of the Commodore 65 prototype, and leveraging the MEGA65&amp;rsquo;s FPGA to reproduce the experiences of other Commodore 8-bit computers. The MEGA65 project&amp;rsquo;s goal of staying connected to history has always been a balancing act between recreating an incomplete, unreleased, and ultimately canceled design, and completing and extending that design to be practical and fun to use in the 21st century. As invigorating as it is to see the MEGA65 as an opportunity to design a new 8-bit computer, it is important to the community that the MEGA65 project values historical preservation.&lt;/p&gt;
&lt;p&gt;Several of the options discuss programming, which is also repeated later in the survey. Many respondents want to run MEGA65 software written by others, write programs for their own enjoyment, and/or write programs for others to use. I&amp;rsquo;m personally gratified to see 19% said they want to use the MEGA65 as a platform for learning how to program computers in general. I&amp;rsquo;m also excited to see 19% said they want to learn FPGA programming. There&amp;rsquo;s a lot of potential for the MEGA65 to be an all-in-one FPGA learning platform, especially with the &lt;a href=&#34;https://github.com/sy2002/MiSTer2MEGA65&#34;&gt;MiSTer2MEGA65 template&lt;/a&gt; as a starting point.&lt;/p&gt;
&lt;p&gt;We can try to relate interest in recreating Commodore computers and interest in programming.
68% selected at least one of the Commodore recreation options. 72% selected at least one programming-related option. 50% of all respondents selected at least one option in both of the re-creation and programming categories.&lt;/p&gt;
&lt;p&gt;This section included a free-text prompt for mentioning other interests and motivations. Many took this opportunity to elaborate on their interest in using the MEGA65 as a Commodore 64, and potentially other Commodore computers, with several people appreciating that new hardware is more available and less likely to fail than vintage hardware. Others gave details about their interests in programming, with some specifically interested in FPGA development. Quite a few people praised the project for its nostalgic feel, and called out wanting to participate in the MEGA65 community.&lt;/p&gt;
&lt;p&gt;The survey asked follow-up questions to people who said they don&amp;rsquo;t use their MEGA65 or are not interested in ordering. The most common concerns are the price being too high and software being too scarce. (The survey phrased this as &amp;ldquo;Not enough software,&amp;rdquo; which was intended as &amp;ldquo;Not enough new third-party MEGA65-platform software.&amp;rdquo;) I won&amp;rsquo;t share specifics on these questions publicly due to low response rates in these categories, but all individual concerns will be seen by the team.&lt;/p&gt;
&lt;h2 id=&#34;platform-versions&#34;&gt;Platform versions&lt;/h2&gt;
&lt;p&gt;The survey asked owners to identify when they received their computers, to determine which delivery batch they received. We know that batch 1 (from mid-2022) and batch 2 (from early 2023) each delivered 400 units. Of these, 35% of batch 1 owners and 16% of batch 2 owners responded to the survey. This might indicate that batch 2 recipients are less engaged with our communication channels than batch 1 recipients.&lt;/p&gt;
&lt;p&gt;(This is not to be confused with the proportions within the responses. Among respondents who said they owned a MEGA65, 64% said batch 1, and 29% said batch 2.)&lt;/p&gt;
&lt;p&gt;I asked owners how often they use their MEGA65s. Batch 2 owners are slightly more likely to be using their computers more frequently than batch 1 owners, which would make sense if batch 1 owners have had more time to move on to other projects.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;More than once per week:&amp;rdquo; 19% of batch 1, 23% of batch 2&lt;/li&gt;
&lt;li&gt;&amp;ldquo;A few times per month:&amp;rdquo; 37% of batch 1, 32% of batch 2&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Less often than once per month, but occasionally:&amp;rdquo; 29% of batch 1, 37% of batch 2&lt;/li&gt;
&lt;li&gt;&amp;ldquo;I used it some when I first got it, but I don&amp;rsquo;t use it any more:&amp;rdquo; 13% of batch 1, 6% of batch 2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;images/how_often_do_you_use_your_mega65_.png&#34; alt=&#34;How often do you use your MEGA65?&#34;&gt;&lt;/p&gt;
&lt;p&gt;The MEGA65 platform (core, ROM, and system software) is upgradable, and the MEGA65 team continues to improve the platform and issue new releases to be installed at the factory for each delivery batch, and made available to everyone as upgrades. Batch 1 owners started out with Release v0.9 and were invited to upgrade to Release v0.95, which was the default for batch 2. We&amp;rsquo;ve tried to make upgrading as easy a process as possible, but it&amp;rsquo;s not clear how easy it is to learn that new versions are available, or learn how to upgrade.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m pleased to see that 72% of owners have upgraded their MEGA65 at least once. Naturally, more batch 1 owners upgraded than batch 2 owners, because batch 2 owners started with the current stable release. Quite a few batch 2 owners reported having upgraded, likely to help beta test new features. Excellent!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/have_you_upgraded_your_mega65_.png&#34; alt=&#34;Have you upgraded your MEGA65?&#34;&gt;&lt;/p&gt;
&lt;p&gt;17% of batch 1 owners report having not upgraded. The survey didn&amp;rsquo;t ask why they did not upgrade, but given the benefits of upgrading, it&amp;rsquo;s worth taking this as an indication that these owners may not know about the newer releases, or may not know how to upgrade.&lt;/p&gt;
&lt;p&gt;Everyone who said they have upgraded was asked what they have for their default core and MEGA65 ROM. Options included the MEGA65 stable release cores and ROMs, newer test versions of each, non-MEGA65 cores, and MEGA65-compatible ROMs such as the C65 prototype ROMs or the MEGA65 Open ROM project. In the following charts, I have included people who said they did not upgrade (and so were not asked which core or ROM they are running) in the results for the stable releases based on their reported delivery batch.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/what_core_is_your_default_.png&#34; alt=&#34;What core is your default?&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/what_rom_is_your_default_.png&#34; alt=&#34;What ROM is your default?&#34;&gt;&lt;/p&gt;
&lt;p&gt;21% of owners admitted that they do not know which core or ROM (or both) that they have installed. I would guess many of these might be people who were not in a position to check their version numbers when they took the survey. This could also suggest that we can do a better job making this information easier to find. While it&amp;rsquo;s an authentic retro experience to not know or care about the chipset and ROM version of a vintage Commodore, it&amp;rsquo;s important that we help everyone keep up with updates so that they get the most out of their machines.&lt;/p&gt;
&lt;p&gt;The survey also asked which cores everyone has installed, regardless of slot. 54% of owners have the C64 for MEGA65 core installed. Once again aggregating responses from people who said they have never upgraded:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/what_cores_do_you_have_installed__in_any_slot_.png&#34; alt=&#34;What cores do you have installed, in any slot?&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;video-and-audio-configuration&#34;&gt;Video and audio configuration&lt;/h2&gt;
&lt;p&gt;Owners were asked several questions about their video and audio configuration, and peripherals they are using.&lt;/p&gt;
&lt;p&gt;81% reported using the PAL video mode as their primary mode. Of these, 17% reported that their display &lt;em&gt;only&lt;/em&gt; supports PAL.&lt;/p&gt;
&lt;p&gt;Similarly, 18% reported using the NTSC video mode as their primary mode. Of these, 24% reported that their display &lt;em&gt;only&lt;/em&gt; supports NTSC.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/which_video_mode_do_you_use__primarily_.png&#34; alt=&#34;Which video mode do you use, primarily?&#34;&gt;&lt;/p&gt;
&lt;p&gt;56% of owners reported that their display supports both PAL and NTSC display modes, so they can run software that switches to either mode. 24% reported that they do not know whether their display supports both modes.&lt;/p&gt;
&lt;p&gt;The survey asked which video and audio outputs you used primarily. Some displays support more than one input. (I actually keep both DVI and VGA connected so I can switch between them as needed.)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/which_video_output_do_you_use_.png&#34; alt=&#34;Which video output do you use?&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/which_audio_output_do_you_use_.png&#34; alt=&#34;Which audio output do you use?&#34;&gt;&lt;/p&gt;
&lt;p&gt;I asked everyone to name the make and model of their display, as free-text. Not everyone knew their make or model, but many attempted to answer. I was hoping to compile a list of recommendations of displays that support both PAL and NTSC. Not surprisingly, almost everyone was using a different model of display.&lt;/p&gt;
&lt;p&gt;The most reported single model was the &lt;a href=&#34;https://www.dell.com/en-us/shop/dell-19-monitor-p1917s/apd/210-aiij/monitors-monitor-accessories&#34;&gt;Dell P1917S&lt;/a&gt;, a 19&amp;quot; 5:4 flat panel LCD display that has both DVI and VGA inputs and supports both PAL and NTSC, and you can still buy it new. It doesn&amp;rsquo;t have built-in sound, so get a pair of powered computer speakers with a 3.5 mm audio input. Note that the Dell soundbar for this model is USB audio only and won&amp;rsquo;t work with the MEGA65. I have used this model, as well as a vintage Dell 2001FP with an older soundbar with a 3.5 mm audio jack. I can report that the P1917S handles the VGA signal much better than the 2001FP, and the P1917S doesn&amp;rsquo;t freak out about sound over HDMI either the way the 2001FP does for DVI video.&lt;/p&gt;
&lt;p&gt;I also asked about video capture equipment. Only a few people said they use it, primarily for making or streaming video of their MEGA65. Generic HDMI-to-USB capture devices seem to work just fine. I use an &lt;a href=&#34;https://www.elgato.com/us/en/p/cam-link-4k&#34;&gt;Elgato Cam Link&lt;/a&gt; for this purpose, and I got a &lt;a href=&#34;https://www.cloner-alliance.com/cloneralliance-box-pro/&#34;&gt;ClonerAlliance Box Pro&lt;/a&gt; based on a recommendation from &lt;a href=&#34;https://www.youtube.com/channel/UCjdKGdIl5leQfhJZiHUYFbQ&#34;&gt;retroCombs&lt;/a&gt; which I also like a lot.&lt;/p&gt;
&lt;h2 id=&#34;peripherals-and-supplies&#34;&gt;Peripherals and supplies&lt;/h2&gt;
&lt;p&gt;I asked everybody (not just owners) about what&amp;rsquo;s in their closet, in an attempt to survey what people can be expected to own that would extend their MEGA65 experience.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/which_controller_peripherals_do_you_own_.png&#34; alt=&#34;Which controller peripherals do you own?&#34;&gt;&lt;/p&gt;
&lt;p&gt;In general, lots of respondents have joysticks, and quite a few have mice and paddles. 11% reported not having any of these.&lt;/p&gt;
&lt;p&gt;Of the paddle owners, 57% have Commodore paddles, and 41% have Atari paddles. Great job knowing what paddles you have! It was only last year that I learned there was a difference. As a kid I used Atari paddles with my Commodore and didn&amp;rsquo;t understand why my paddles had about half a turn of dead space.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/which_iec_devices_do_you_own_.png&#34; alt=&#34;Which IEC devices do you own?&#34;&gt;&lt;/p&gt;
&lt;p&gt;Many respondents, 68%, own a vintage 5-1/4&amp;quot; Commodore disk drive. I included a free-text field for other IEC devices, and plenty of people reminded me that SD2IEC devices are popular. Zero respondents reported owning a vintage dual drive unit, such as the Commodore 4040.&lt;/p&gt;
&lt;p&gt;I asked how many floppy disks you own, of any type and for any purpose. 62% said they have more than 20. 14% have none. I intended this as a rough measure of how many people might use the built-in floppy drive. Of course, the drive could still be used with a future purchase of MEGA65 software distributed on 3-1/2&amp;quot; floppy.&lt;/p&gt;
&lt;h2 id=&#34;connectivity-and-development-hardware&#34;&gt;Connectivity and development hardware&lt;/h2&gt;
&lt;p&gt;88% of overall respondents said they could connect a MEGA65 to their local network via Ethernet from where they use a MEGA65, or from where would use one if they had one. Those new networking features of the MEGA65 will be a game changer for transferring files without extracting the SD card, and for doing cross-development. Anyone without convenient access to an Ethernet connection might be able to use &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/24576037/VONETS+WiFi-Ethernet+Bridge+adaptor&#34;&gt;a Wifi-ethernet bridge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;29% of owners have a JTAG adapter for their MEGA65. 11% of owners have a UART serial adapter. &lt;a href=&#34;https://dansanderson.com/mega65/welcome/using-jtag.html&#34;&gt;JTAG and UART serial&lt;/a&gt; are powerful tools for programmers doing cross development and contributing to the MEGA65 platform, and some have used them just to transfer files back and forth between their PC and their MEGA65. The new Ethernet-based tools can move files and programs at much faster speeds, and are likely to eliminate the need to buy extra hardware for most people. JTAG is still needed for testing bitstreams, and JTAG/UART are still useful for remote debugging tasks, at least until someone makes a similar feature that works over Ethernet.&lt;/p&gt;
&lt;p&gt;Small but non-zero percentages of respondents own a MEGA65 DevKit, and/or a Nexys or Wukong FPGA development board, all of which are alternative ways of running the MEGA65 platform.&lt;/p&gt;
&lt;h2 id=&#34;software&#34;&gt;Software&lt;/h2&gt;
&lt;p&gt;The survey asked how many MEGA65 software titles have you downloaded off of the Internet. It asked this of all respondents, not just MEGA65 owners, because some people use the Xemu MEGA65 emulator as a temporary or permanent substitute for MEGA65 hardware.&lt;/p&gt;
&lt;p&gt;12% of owners say they have never downloaded MEGA65 software. 71% of non-owners have never downloaded software, which makes sense. The non-owner sub-categories break down as you would expect, with greater degrees of interest in the project correlating with more software downloaded.&lt;/p&gt;
&lt;p&gt;Retro software publisher poly.play currently prints two commercial titles for the MEGA65: &lt;a href=&#34;https://www.polyplay.xyz/Hibernated-1-Directors-Cut-MEGA65_1&#34;&gt;Hibernated 1&lt;/a&gt; by Stefan Vogt, and &lt;a href=&#34;https://www.polyplay.xyz/Showdown-Collectors-Edition-MEGA65_1&#34;&gt;Showdown&lt;/a&gt; by Badger Punch Games. 14% of respondents have purchased at least one of these. 6% of respondents have purchased both titles. 40% knew about them but did not purchase either, and 45% did not know about one or both.&lt;/p&gt;
&lt;h2 id=&#34;xemu&#34;&gt;Xemu&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;Xemu MEGA65 emulator&lt;/a&gt; by Gábor Lénárt (LGB) is the definitive PC emulator for the MEGA65 platform. 74% of respondents knew there was an emulator before taking the survey. Of the people who said they knew about Xemu, 48% said they use it.&lt;/p&gt;
&lt;p&gt;There are several reasons people use Xemu, so the survey asked about them.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/how_do_you_use_xemu_.png&#34; alt=&#34;How do you use Xemu?&#34;&gt;&lt;/p&gt;
&lt;p&gt;Selecting just for people who already own a MEGA65, the proportions of uses don&amp;rsquo;t actually change much except, of course, for respondents stating they use Xemu because they don&amp;rsquo;t own hardware.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/how_do_owners_use_xemu_.png&#34; alt=&#34;How do owners use Xemu?&#34;&gt;&lt;/p&gt;
&lt;p&gt;The survey gave everyone an opportunity to provide feedback on Xemu. We collected dozens of excellent suggestions and feedback in a wide variety of categories. Xemu is a well-loved tool and a cornerstone of the MEGA65 project, and we&amp;rsquo;re all grateful to LGB for working on it!&lt;/p&gt;
&lt;h2 id=&#34;documentation&#34;&gt;Documentation&lt;/h2&gt;
&lt;p&gt;Every MEGA65 ships with a first edition printed User&amp;rsquo;s Guide. 28% of owners use it regularly, 44% refer to it occasionally, and 26% rarely or never use it.&lt;/p&gt;
&lt;p&gt;The User&amp;rsquo;s Guide is just one of &lt;a href=&#34;http://mega65.org/docs&#34;&gt;a set of books in progress&lt;/a&gt; that form the complete documentation for the project. The latest versions are available as PDF files, free for anyone to download. The survey asked all respondents how often they use the PDFs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/how_often_do_you_use_the_pdf_manuals_.png&#34; alt=&#34;How often do you use the PDF manuals?&#34;&gt;&lt;/p&gt;
&lt;p&gt;When I first got my MEGA65 in May of 2022, I wrote &lt;a href=&#34;https://dansanderson.com/mega65/welcome/&#34;&gt;Dan&amp;rsquo;s MEGA65 Welcome Guide&lt;/a&gt; as a supplement to the official documentation, intending to patch over the gaps between the intended experience and the first delivery batch that I knew would be fixed in later versions. It ended up being a generally useful resource for many. 62% of respondents were aware of the Welcome Guide.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/how_do_you_prefer_to_read_.png&#34; alt=&#34;How do you prefer to read?&#34;&gt;&lt;/p&gt;
&lt;p&gt;The survey asked about what medium you prefer your documentation. My personal preference would be professionally printed manuals, and the MEGA65 documentation was set up to maybe someday become a multi-volume printed set, similar to the printed User&amp;rsquo;s Guide. I wanted to gauge interest in crowdfunding a professional print run. Crowdfunding can be tricky with a small population, especially one that&amp;rsquo;s difficult to reach. Print-on-demand services are easy to use with no up-front or on-going monetary investment, and they have significant advantages for global fulfillment, but they&amp;rsquo;re lower quality than what I have in mind. My favored option for printing would require a minimum print run.&lt;/p&gt;
&lt;p&gt;In the survey, I proposed a hypothetical version of this project where an &amp;ldquo;entire set&amp;rdquo; (with the actual content to be determined) might cost $150 USD, and individual volumes might cost $35 USD. I asked everyone their preference: the entire set, a couple of volumes, print-on-demand, or digital only.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/purchasing_printed_manuals.png&#34; alt=&#34;Purchasing printed manuals&#34;&gt;&lt;/p&gt;
&lt;p&gt;If the responses are representative of the preferences of everyone who will own a MEGA65 by the end of 2023 &lt;em&gt;and&lt;/em&gt; enough of them could be reached to announce a crowdfunding campaign &lt;em&gt;and&lt;/em&gt; at least half of them backed the project, we could make fancy books a reality. It&amp;rsquo;d be a limited print run, followed up by a secondary print-on-demand version available in perpetuity. I like these odds well enough. Even if the crowdfunding campaign never happens, investing in content will improve the digital versions and we can easily do an official print-on-demand offering when we feel they&amp;rsquo;re in a state worth printing.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m also going to try to get a web version of the documentation working. No promises—it&amp;rsquo;ll be a chunk of work to clear up the LaTeX for web export—but it&amp;rsquo;s a worthy goal.&lt;/p&gt;
&lt;h2 id=&#34;dans-mega65-digest&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re reading this, you&amp;rsquo;re probably aware of my monthly email newsletter, &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt;. I initially announced the survey in the Digest, so it&amp;rsquo;s not surprising that 60% of respondents were aware of the Digest before the survey. I&amp;rsquo;m &lt;em&gt;delighted&lt;/em&gt; to see that 39% of respondents were unaware, because that means two things: 1) there are more people out there who might be interested, and 2) our efforts to promote the survey reached beyond people already aware of the Digest.&lt;/p&gt;
&lt;p&gt;Of the people aware of the Digest, 67% read the text version by email. 15% go to my website directly, and a few use RSS or the Substack website. It&amp;rsquo;s good to see that I could migrate the Digest to another newsletter provider if needed and probably nobody would miss it.&lt;/p&gt;
&lt;p&gt;Did you know that there&amp;rsquo;s an audio podcast version of the Digest? 42% of people familiar with the Digest did not know. 18% listen to at least some issues by audio. 51% of listeners use the Substack service to do so (because clicking on the email takes you there), and 37% of listeners use a podcast app. I enjoy making the audio version and I&amp;rsquo;m grateful that some find it entertaining.&lt;/p&gt;
&lt;p&gt;Thank you all for the generous comments in the free-text field! Some people asked for more advanced technical topics, and others asked for less advanced technical topics. 😊 Several people mentioned interest in a print anthology, or just a printed zine. I&amp;rsquo;m not sure I could fill a print zine each month—at least not without collaborators.&lt;/p&gt;
&lt;h2 id=&#34;community-resources&#34;&gt;Community resources&lt;/h2&gt;
&lt;p&gt;62% of all respondents are aware of the &lt;a href=&#34;https://files.mega65.org/&#34;&gt;MEGA65 Filehost&lt;/a&gt;, an essential community resource. 91% of owners who responded to the survey know about it.&lt;/p&gt;
&lt;p&gt;Of those who are aware, almost everyone has used the Files section to browse and download files. 47% of respondents who own a MEGA65 have redeemed their owner code, which is surprisingly low! You need to redeem your owner code to access release packages containing the closed ROM (though there are other ways to get the closed ROM). The survey asks about other features of Filehost, and it generally looks like people use them proportional to the amount of material posted in those categories. No surprises here.&lt;/p&gt;
&lt;p&gt;83% of all respondents are aware of the &lt;a href=&#34;https://mega65.org/chat&#34;&gt;MEGA65 Discord&lt;/a&gt;, and 54% have an account. Of those that have an account, 29% visit it daily.&lt;/p&gt;
&lt;p&gt;76% of all respondents are aware of the &lt;a href=&#34;https://www.forum64.de/index.php?board/457-mega65/&amp;amp;l=2&#34;&gt;MEGA65 section of Forum64.de&lt;/a&gt;, and 33% have an account. Of those that have an account, 18% visit it daily.&lt;/p&gt;
&lt;p&gt;25% of all respondents have both a Discord account and a Forum64 account. 75% of them visit the Discord at least once a month. 28% of them (7% of all respondents) visit the Discord daily.&lt;/p&gt;
&lt;h2 id=&#34;programming&#34;&gt;Programming&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;images/what_is_your_level_of_experience_with_writing_computer_programs_.png&#34; alt=&#34;What is your level of experience with writing computer programs?&#34;&gt;&lt;/p&gt;
&lt;p&gt;The majority of respondents have more than 10 years of experience writing computer programs. The survey purposefully did not make a distinction between professional vs. hobbyist programming: the survey used phrases like &amp;ldquo;writing computer programs&amp;rdquo; to be inclusive of both.&lt;/p&gt;
&lt;p&gt;79% of all respondents said they are interested in writing their own programs for the MEGA65. Those that expressed interest were presented additional questions about programming tools.&lt;/p&gt;
&lt;p&gt;Of those that want to program, 75% are interested in assembly language, and 75% are interested in BASIC 65.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/programming_languages_of_interest.png&#34; alt=&#34;Programming languages of interest&#34;&gt;&lt;/p&gt;
&lt;p&gt;The survey offered a free-text box to express interest in other programming languages. Python was mentioned multiple times. In my experiences with Python and with retro computing, I&amp;rsquo;ve seen many people wonder aloud if &lt;a href=&#34;https://micropython.org&#34;&gt;MicroPython&lt;/a&gt; could be ported to a vintage computer. In those discussions, the quality of C compilers that target retro platforms has been mentioned as an issue, so I wonder if it&amp;rsquo;s a topic worth revisiting in the context of &lt;a href=&#34;https://llvm-mos.org/wiki/Welcome&#34;&gt;llvm-mos&lt;/a&gt;. Pascal also got multiple mentions, which is more likely to be built from scratch for the MEGA65 by an enterprising hobbyist.&lt;/p&gt;
&lt;p&gt;The survey listed a bunch of popular cross-development tools and let everyone pick their favorites. Visual Studio Code, &lt;a href=&#34;https://www.ajordison.co.uk&#34;&gt;CBM prg Studio&lt;/a&gt;, &lt;a href=&#34;http://theweb.dk/KickAssembler/Main.html#frontpage&#34;&gt;Kick Assembler&lt;/a&gt;, and &lt;a href=&#34;https://cc65.github.io&#34;&gt;cc65&lt;/a&gt; were top of mind for most people. Several people mentioned &lt;a href=&#34;https://github.com/GeorgRottensteiner/C64Studio/&#34;&gt;C64 Studio&lt;/a&gt; in the free-text responses.&lt;/p&gt;
&lt;p&gt;I know people that love cross development, writing programs for the MEGA65 using a modern computer. I also know people that love on-device development, preferring to shut off the modern computer and use the MEGA65 as its own programming environment. The survey asked for your preference, and results were split three ways: on-device development, cross development, and &amp;ldquo;depends on the project&amp;rdquo; all got roughly the same proportion of responses.&lt;/p&gt;
&lt;h2 id=&#34;demographics&#34;&gt;Demographics&lt;/h2&gt;
&lt;p&gt;65% of respondents are between 45 and 54 years old. Remaining respondents are roughly split between 35-44 years old and 55 years or older, with only a few respondents in other age groups.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/surveymap.png&#34; alt=&#34;Heat map of survey respondents by country&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/surveymap_eu.png&#34; alt=&#34;Heat map of survey respondents by country in Europe&#34;&gt;&lt;/p&gt;
&lt;p&gt;The MEGA65 community is international, with strong contingents in Germany and the United States.&lt;/p&gt;
&lt;p&gt;Discussion about the MEGA65 on Forum64.de is almost entirely in the German language, and making MEGA65 programming resources available in the German language is a frequent topic of discussion. For the survey, I asked two questions about spoken language: in what language(s) do you prefer to socialize online, and in what language(s) do you prefer to consume technical information?&lt;/p&gt;
&lt;p&gt;86% of everyone who answered these questions answered both questions with the same language or languages. 80% of these said English. 7% said they preferred German exclusively for both. 10% offered both English and German as their answer in both categories.&lt;/p&gt;
&lt;p&gt;14% of respondents gave different answers for preferred languages for socializing vs. technical information. Of those that gave different answers, 85% said English was preferable or at least acceptable for consuming technical information. 13% preferred technical information in German.&lt;/p&gt;
&lt;p&gt;Danish, Dutch, English, Finnish, French, German, Hungarian, Italian, Norwegian, Polish, Portuguese, Scandinavian, Spanish, and Swedish were all mentioned at least once. I won&amp;rsquo;t draw any conclusions due to sample size, but it&amp;rsquo;s exciting to list them all out!&lt;/p&gt;
&lt;p&gt;The survey asked for everyone&amp;rsquo;s preferred social media service. This is a bad question. Outside of the Digest, the survey was promoted almost exclusively on social media, and so response rates are most likely to correspond to visibility of the survey announcements on those platforms. Nevertheless, it&amp;rsquo;s good to know that Facebook and X.com (née Twitter) are still important ways to reach people.&lt;/p&gt;
&lt;p&gt;Despite how the survey was promoted, 22% of respondents say they do not use a social networking service. There was some ambiguity in the question about whether Discord qualifies as social media. The survey did not include it in the list, but it included a free-text prompt for other services and many used it to mention Discord. Combining social media non-users and users of services the survey did not list, that&amp;rsquo;s 28% of respondents.&lt;/p&gt;
&lt;h2 id=&#34;other-vintage-and-modern-retro-computers&#34;&gt;Other vintage and modern-retro computers&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;images/commodores.png&#34; alt=&#34;Commodore ownership, then and now&#34;&gt;&lt;/p&gt;
&lt;p&gt;Nearly every respondent has owned or used a Commodore 64 in their lifetime. 76% of respondents currently own a Commodore 64. Only 2% of respondents have never owned or used a Commodore computer.&lt;/p&gt;
&lt;p&gt;45% of respondents own an &lt;a href=&#34;https://www.c64-wiki.com/wiki/SD2IEC&#34;&gt;SD2IEC&lt;/a&gt; device. 35% own an &lt;a href=&#34;https://ultimate64.com/&#34;&gt;Ultimate 1541&lt;/a&gt; (any model). Of potential interest to future MEGA65 cartridge authors, 21% of respondents own an &lt;a href=&#34;https://www.go4retro.com/products/easyflash-3/&#34;&gt;EasyFlash 3&lt;/a&gt;, and 10% own an &lt;a href=&#34;https://www.electromaker.io/project/view/easyflash-1cr-cartridge-for-commodore-64&#34;&gt;EasyFlash 1 or 1CR&lt;/a&gt; (&lt;a href=&#34;https://www.sellmyretro.com/offer/details/61882&#34;&gt;purchase link&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;34% own, have preordered, or intend to order at least one of several retro-style modern computers that the survey listed. The breakdown between the models isn&amp;rsquo;t interesting, mostly corresponding to the current availability of those machines.&lt;/p&gt;
&lt;h2 id=&#34;modern-computers&#34;&gt;Modern computers&lt;/h2&gt;
&lt;p&gt;53% of respondents use a Windows computer. 22% use an Apple laptop or desktop. 20% use a Linux laptop or desktop.&lt;/p&gt;
&lt;p&gt;Of the Windows users, 44% are using Windows 11, and 52% are using Windows 10. Several people are using Windows 7.&lt;/p&gt;
&lt;p&gt;Of the Apple users, 73% have an Apple Silicon (M1 or M2) processor, and 26% have an Intel processor. 53% are using macOS 13 Ventura, the latest stable release. 31% are on the macOS 14 Sonoma public beta. 13% are using older versions of macOS.&lt;/p&gt;
&lt;p&gt;I did not ask about Linux distributions or variants, nor did I ask about Intel vs. ARM for Linux or Windows. Tablets (iOS, Android), BSD variants, Windows Subsystem for Linux, AmigaOS 4.1, and MorphOS were represented in the minority replies.&lt;/p&gt;
&lt;h2 id=&#34;mega65-project-feedback&#34;&gt;MEGA65 project feedback&lt;/h2&gt;
&lt;p&gt;The survey concluded with an invitation to provide free-text feedback to the MEGA65 project. I will try to summarize common themes and provide my own commentary based on my experiences with the project in the last year. This will naturally reflect my own biases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enthusiasm.&lt;/strong&gt; Nearly everyone took this opportunity to express words of encouragement and praise for the project. Thank you all for your kindness and generosity! It is gratifying to know there are so many people out there who believe in the MEGA65 project and are enthusiastic about the community and what everyone has accomplished so far.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Price and shipping cost.&lt;/strong&gt; As of this writing, the MEGA65 production model, with the mechanical keyboard, injection molded plastic case, and built-in 3.5&amp;quot; floppy disk drive, has &lt;a href=&#34;https://shop.trenz-electronic.de/en/Products/MEGA65/&#34;&gt;a retail price&lt;/a&gt; of 666.66 € ($722.38 USD), not including taxes or shipping costs. The total cost to buy one delivered to where I am in the United States is 790.20 € ($856.79 USD). This price alienates some people who are interested in the project, due either to the value proposition or the ability to pay. Less expensive options include running the MEGA65 core on a Nexys Artix A7 FPGA development board, or running the MEGA65 ROM in the Xemu emulator. The central FPGA chip dominates the price, and burning the chipset design into cheaper ASICs would require several orders of magnitude more people interested. (And of course, ASIC-based computers would not be upgradeable.) Counterintuitively, eliminating the floppy drive does not meaningfully reduce the cost, and new plastic case shapes would require an up-front investment in new moulds.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shipping delays and shipping updates.&lt;/strong&gt; Many who have preordered a MEGA65 have experienced shipping waits longer than one year. Estimating shipping dates has been nearly impossible over the past two years due to the unavailability of essential components, and a reliable estimate is only possible after all parts have been acquired by our assembly and distribution partner Trenz Electronic. Trenz has been great about responding to customer service inquiries with rough guesses, but it is not currently a regular practice to send periodic emails to pre-order customers during the process. Some survey respondents expressed concern about the lack of proactive order status communication. Due to privacy laws in Germany, Trenz Electronic is not allowed to share their list of pre-order customers with the project team. The best we&amp;rsquo;ve been able to offer so far is to use other communication channels to encourage everyone to &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;subscribe to the newsletter&lt;/a&gt; or follow project announcement channels on the &lt;a href=&#34;https://mega65.org/chat&#34;&gt;Discord&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/channel/UCEz3CQ343r4ssvIdmhDauMQ&#34;&gt;YouTube&lt;/a&gt;, or &lt;a href=&#34;https://c65gs.blogspot.com/&#34;&gt;Paul&amp;rsquo;s developer blog&lt;/a&gt;. It has been a challenge to make sure pre-order customers are aware of these resources.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sources of technical information.&lt;/strong&gt; The MEGA65 has a substantial amount of technical documentation available, but this can be difficult to notice given how that information is stored and disseminated. Survey respondents pointed out that having information spread over PDF manuals, a Confluence Wiki, and Filehost articles is inconvenient, and it&amp;rsquo;s unclear where to find each kind of information. Sometimes the easiest way to get an answer to a technical question is to ask the Discord chat, but answers to questions previously asked are difficult to find, and both the community and its discussion archives are only available to Discord users. Discord is an ephemeral medium and does not function as a technical resource, at least not a passive one, and it&amp;rsquo;s unreasonable to expect all users to read every discussion. Moreover, &lt;em&gt;none&lt;/em&gt; of these resources are reliably indexed by search engines, either by design (Discord cannot be crawled; Confluence blocks crawlers) or by unintended technical limitations. Multiple survey respondents wished for a more traditional open-access web forum, and some are disappointed that only a subset of the community participates on Forum64.de.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Better software.&lt;/strong&gt; Many MEGA65 owners want to use their computer to run games and applications written by others. Without a large library of quality titles (for some relative definition of &amp;ldquo;quality&amp;rdquo;), the MEGA65 is mostly useful for learning to program, writing programs from scratch, or running C64 software via the C64 core (or GO64 mode). Some respondents emphasized that they would be willing to pay for quality MEGA65 software. Some respondents said they are waiting for the software library to grow before investing in a purchase.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;German-language technical resources.&lt;/strong&gt; Multiple respondents used the free-text feedback field to emphasize the need for German-language technical information. There is &lt;a href=&#34;https://65site.de/downloads/MEGA65_BASIC_65_Referenzhandbuch.pdf&#34;&gt;a German MEGA65 handbook&lt;/a&gt; that is highly valued. The topic of German-language video tutorials, livestreams, and classes comes up occasionally on Forum64.de.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Technical issues.&lt;/strong&gt; Several respondents mentioned some of the common technical issues we have experienced in the first year, both in the electrical hardware and in the core and ROM. The new main board revision will help with some of these, and the core and ROM are active projects that welcome contributors. Many respondents expressed gratitude for everyone who is contributing fixes, and are excited to see the work continue.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Feature areas.&lt;/strong&gt; Many respondents were excited about the potential for new features, including networking applications, D64 disk image support, more alternate cores, and more on-device programming environments and tools. Several respondents wished for more programming tutorials and recipes. Several respondents expressed an interest in a more compact version of the keyboard case without the floppy drive. Others reminded us that some owners of R3A boards would be interested in buying a bare R5 board as an upgrade. (I considered asking about interest in an R5 upgrade as a survey question, but we don&amp;rsquo;t know how much such an upgrade would cost. We don&amp;rsquo;t realize economies of scale in the hundreds of units, so it doesn&amp;rsquo;t help to forecast sales.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More community events and publications.&lt;/strong&gt; Respondents expressed an interest in more live streams like the &lt;a href=&#34;https://www.youtube.com/live/wifYmhIRAEs?si=ww0UcfTGzBhaAf43&#34;&gt;MEGAVISION&lt;/a&gt; live stream that took place earlier this year. Conferences were also mentioned. There were multiple suggestions for a print magazine.&lt;/p&gt;
&lt;h2 id=&#34;reach&#34;&gt;Reach&lt;/h2&gt;
&lt;p&gt;One of the biggest questions I wanted to answer with the survey was, how effective have we been at connecting the MEGA65 community with the project, and how can we improve? Communities around projects tend to form layers of engagement, and we want to foster the growth of all of those layers and reach as many people as possible that would benefit from the project. We have known issues with making resources available in search engines and providing information to pre-order customers. We can only hope that as people get more interested, they look for community resources more aggressively.&lt;/p&gt;
&lt;p&gt;The first test was simply, how many people can we get to take the survey? 509 respondents feels downright miraculous considering that only 900 people currently own a MEGA65 (DevKit or production model). We aren&amp;rsquo;t privy to the number of pending pre-orders but we believe it is over 1,000. The survey promotion reached quite a few people who are interested enough in the project to take the survey but have not yet pre-ordered, but it&amp;rsquo;s impossible to guess the size of that population from the survey alone.&lt;/p&gt;
&lt;p&gt;Our limited ability to reach out to the community makes it difficult to promote resources like &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt;, and difficult to promote community projects that require financial support. A small number of free-text responses in the survey ask for things that already exist, which suggests that we could be doing more to promote the resources we already have.&lt;/p&gt;
&lt;p&gt;The survey asked about several specific community resources, projects, and concepts, and made a distinction between &amp;ldquo;I know about that resource but don&amp;rsquo;t use it&amp;rdquo; vs. &amp;ldquo;I didn&amp;rsquo;t know about that resource.&amp;rdquo; These replies are a useful indicator of how well information about the project has disseminated. The following numbers are shown as percentages of owners. Owners are more likely to be familiar with resources, and have a known population size as a basis for the sample. This is not meant to exclude non-owners from consideration, only to have a basis for comparison.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;10% of &lt;strong&gt;owners&lt;/strong&gt; replied that they did not know about the JTAG or UART serial adapter.&lt;/li&gt;
&lt;li&gt;4% did not know about the DevKit.&lt;/li&gt;
&lt;li&gt;13% did not know about the Nexys FPGA dev board.&lt;/li&gt;
&lt;li&gt;34% did not know abut the Wukong FPGA dev board.&lt;/li&gt;
&lt;li&gt;20% did not know about &lt;em&gt;Hibernated 1&lt;/em&gt; by Stefan Vogt. The numbers were similar for &lt;em&gt;Showdown&lt;/em&gt; by Badger Punch Games.&lt;/li&gt;
&lt;li&gt;13% were unaware of the Xemu emulator.&lt;/li&gt;
&lt;li&gt;5% were unaware of the PDF manuals.&lt;/li&gt;
&lt;li&gt;16% were unaware of the MEGA65 Welcome Guide.&lt;/li&gt;
&lt;li&gt;22% were unaware of Dan&amp;rsquo;s MEGA65 Digest.&lt;/li&gt;
&lt;li&gt;8% were unaware of Filehost.&lt;/li&gt;
&lt;li&gt;7% were unaware of the MEGA65 Discord.&lt;/li&gt;
&lt;li&gt;14% were unaware of Forum64.de.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusions-and-next-steps&#34;&gt;Conclusions and next steps&lt;/h2&gt;
&lt;p&gt;The MEGA65 is an open source volunteer-run project. It doesn&amp;rsquo;t have &lt;em&gt;development resources&lt;/em&gt; so much as &lt;em&gt;interested parties.&lt;/em&gt; Nevertheless, many people who work on the project want the project as a whole to succeed, and want to work on important things, so seeing which tasks can have the most impact can influence contributors.&lt;/p&gt;
&lt;p&gt;I can&amp;rsquo;t speak for anyone else, but personally, I&amp;rsquo;m more motivated to work on &lt;em&gt;information visibility.&lt;/em&gt; This was already my area of focus with the Digest. I have ideas for making our information easier to find in search engines, and I hope to use my web development background to improve our web-based resources and community tools. I also want to evolve the Digest to make it more visible and interesting to a larger audience. The Digest is our primary tool for disseminating news and project status—including best available information on shipping updates—and I want everyone who is interested in the project (at any level) to at least be aware of it.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m excited to see that we might be able to afford a high-quality print run of the manuals, if we can finish them. Print books are a fun addition to the retro experience, and they&amp;rsquo;re one of my favorite things to make. It&amp;rsquo;s good to be reminded by the data that many people would prefer browser and e-reader-friendly resources, and hopefully we can produce both print and web resources using the same content.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s an opportunity for German content creators to fill a need. Bloggers, YouTubers, and live streamers capable of producing tutorials and walkthroughs in German—at any level of technical complexity or production value—could have a big impact. I&amp;rsquo;ve seen people ask for German-language BASIC programming introductions on Forum64.de. You don&amp;rsquo;t need to know a ton about the internals of the machine to help others with their first steps, and simply blogging your own learning adventure can attract a grateful audience. We can also consider crowdfunding a professional German translation of the manuals once they are reasonably complete.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s no shortage of interest in improving the platform or the hardware, just a shortage of time. I believe our open source processes are in decent shape, so if anyone is interested in helping out, please reach out on the Discord. Bug reports are always welcome, even if you are unable to submit bug fixes.&lt;/p&gt;
&lt;p&gt;As for growing the software library, the number of owners is expected to more than double by the end of the year. It&amp;rsquo;ll be exciting to see what everyone comes up with!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;That&amp;rsquo;s it for this year&amp;rsquo;s survey! Thanks again to everyone who responded. Let me know if you have any feedback on the survey itself or this report. We might do this again next year.&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/mega65-survey-2023-results/M65Digest_2023Sept.mp3" length="57666789" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>2883</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/mega65-survey-2023-results/m65survey_banner_334.png"/>
      
    </item>
    
    <item>
      <title>The MEGA65 Community Survey 2023</title>
      <link>https://dansanderson.com/mega65/mega65-survey-2023/</link>
      <pubDate>Mon, 14 Aug 2023 00:00:53 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/mega65-survey-2023/</guid>
      <description>&lt;p&gt;The MEGA65 Community Survey 2023. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for August 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;The MEGA65 Community Survey 2023. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for August 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/mega65-survey-2023/M65Digest_2023Aug.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023/M65Digest_2023Aug.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
The MEGA65 Community Survey 2023.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023/ships.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mega65-survey-2023/ships.png 600w, https://dansanderson.com/mega65/mega65-survey-2023/ships_hu_b2aff1f01c04ad22.png 600w, https://dansanderson.com/mega65/mega65-survey-2023/ships_hu_a04f9a3c2beac7d3.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-survey-2023/ships.png&#34;
        alt=&#34;A bomber jet and a space alien&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A bomber jet and a space alien.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Hey all! I&amp;rsquo;m keeping this issue short, because there’s something more important for you to do instead of reading.&lt;/p&gt;
&lt;h2 id=&#34;the-mega65-community-survey-2023&#34;&gt;The MEGA65 Community Survey 2023&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://tally.so/r/mDk4pZ&#34;&gt;The MEGA65 Community Survey 2023&lt;/a&gt; is now open. This survey is for &lt;em&gt;anyone&lt;/em&gt; even a little bit interested in the MEGA65, whether you own one, have preordered, are still considering it, or don&amp;rsquo;t intend to order but still enjoy seeing what&amp;rsquo;s going on. This includes anyone not subscribed to this Digest, so please share this link.&lt;/p&gt;
&lt;p&gt;Responses are anonymous. We will share aggregate anonymized results in a future Digest. Full-text replies will be kept confidential to the MEGA65 Steering Committee.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re targeting &lt;strong&gt;400 responses&lt;/strong&gt; for this year&amp;rsquo;s survey. If everyone subscribed to the Digest responds, we&amp;rsquo;ll hit that easily. (Please only take the survey once, so we get accurate counts.)&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s that link again: please &lt;a href=&#34;https://tally.so/r/mDk4pZ&#34;&gt;take the survey&lt;/a&gt;. Your response will go a long way to guiding the future of the MEGA65 project. Thank you!&lt;/p&gt;
&lt;h2 id=&#34;new-galaga-core&#34;&gt;New Galaga core!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023/galaga_core.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mega65-survey-2023/galaga_core.png 509w, https://dansanderson.com/mega65/mega65-survey-2023/galaga_core_hu_4437ad949599127.png 600w, https://dansanderson.com/mega65/mega65-survey-2023/galaga_core_hu_b4bdd5739eac4c0b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-survey-2023/galaga_core.png&#34;
        alt=&#34;Galaga core for the MEGA65, by muse&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Galaga core for the MEGA65, by muse
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;After you have completed the survey, it&amp;rsquo;s time to hit the arcade! Run don&amp;rsquo;t walk to &lt;a href=&#34;https://files.mega65.org?id=8bc248e3-c29c-4ba8-b8c3-6018a995a9ea&#34;&gt;the Galaga core for the MEGA65&lt;/a&gt; by muse. This isn&amp;rsquo;t just a version of Galaga for the MEGA65, this &lt;em&gt;is&lt;/em&gt; Galaga, a port of the original arcade hardware architecture running directly on the MEGA65 FPGA. The core even supports connecting a vintage VGA monitor turned on its side to fully replicate the arcade experience.&lt;/p&gt;
&lt;p&gt;Installation requires a few steps, including fetching the original Midway Galaga ROM from the Internet (using the link provided) and running a Python script. See muse&amp;rsquo;s &lt;a href=&#34;https://github.com/sho3string/GalagaMEGA65&#34;&gt;installation instructions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When starting the core, give it a minute to go through the arcade hardware test routine. The core displays its keyboard controls briefly; press the spacebar to dismiss. Press &lt;kbd&gt;5&lt;/kbd&gt; to insert a quarter, then press &lt;kbd&gt;1&lt;/kbd&gt; to start a one-player game. You can control the game via a joystick in port 1, or use the keyboard: &lt;kbd&gt;A&lt;/kbd&gt; and &lt;kbd&gt;Z&lt;/kbd&gt; move left and right, and the &lt;kbd&gt;Cursor Up&lt;/kbd&gt; key fires. The &lt;kbd&gt;P&lt;/kbd&gt; key pauses. As with the C64 core, press the &lt;kbd&gt;Help&lt;/kbd&gt; key to open a settings menu.&lt;/p&gt;
&lt;p&gt;Huge thanks to muse for this effort, and to all of the original implementors of the core. (And to Midway too, but they already have all of my lunch money.)&lt;/p&gt;
&lt;h2 id=&#34;r4-is-now-r5&#34;&gt;R4 is now R5&lt;/h2&gt;
&lt;p&gt;Last month I mentioned that there will be a new revision of the main board that will start shipping with the next delivery batch, known as R4. Due to restricted availability of a component, the board &lt;a href=&#34;https://c65gs.blogspot.com/2023/07/last-minute-changes-to-r4-board.html&#34;&gt;needs one more revision&lt;/a&gt;. This gives us an opportunity to further refine the cartridge interface before the revised board goes into production, so we&amp;rsquo;re taking that opportunity. The core needs a corresponding adjustment, so the board is now known as &amp;ldquo;R5&amp;rdquo; to distinguish between the core builds. R4 boards will not be manufactured. The next delivery batch will receive R5 boards.&lt;/p&gt;
&lt;p&gt;The cartridge interface enhancements will make it possible to support fancier utility cartridges. As with the other revisions, only time will tell what differences will actually be notable in practice. The most important reason to know which main board revision you have is to download the correct versions of core files.&lt;/p&gt;
&lt;h2 id=&#34;pudding-mountain-miner-65&#34;&gt;Pudding Mountain Miner 65&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023/pudding64.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mega65-survey-2023/pudding64.png 659w, https://dansanderson.com/mega65/mega65-survey-2023/pudding64_hu_335c94fef108ad46.png 600w, https://dansanderson.com/mega65/mega65-survey-2023/pudding64_hu_806d23046e49fe7e.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-survey-2023/pudding64.png&#34;
        alt=&#34;Pudding Mountain Miner, by Charles Brannon, as it appears on a Commodore 64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pudding Mountain Miner, by Charles Brannon, on a Commodore 64.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I said I&amp;rsquo;d keep this short, but I can&amp;rsquo;t resist including a bit of BASIC fun.&lt;/p&gt;
&lt;p&gt;Of all the Commodore 64 games that could have been a staple of my childhood, an unlikely contender was &amp;ldquo;Pudding Mountain Miner&amp;rdquo; by Charles Brannon. Brannon was an editor for &lt;em&gt;Compute!&amp;rsquo;s Gazette&lt;/em&gt; magazine, and originally wrote &amp;ldquo;Pudding Mountain Miner&amp;rdquo; as a short type-in to appear in newspapers promoting the magazine when it was getting started. He wrote up an explainer in &lt;a href=&#34;https://archive.org/details/computes.gazette/Compute_Gazette_Issue_22_1985_Apr/&#34;&gt;the April 1985 issue&lt;/a&gt; of &lt;em&gt;Gazette&lt;/em&gt;, in the &amp;ldquo;Horizons&amp;rdquo; column.&lt;/p&gt;
&lt;p&gt;The game is a one-button shooter where you&amp;rsquo;re a fighter pilot dropping bombs on Pudding Mountain, digging for buried treasure. If you hit the dollar sign, you win the big bucks. If you hit the mantle underneath the pudding, it&amp;rsquo;s game over.&lt;/p&gt;
&lt;p&gt;I liked Miner because it was fun and cute, and also because it was only 17 lines of BASIC code. I don&amp;rsquo;t think I ever bothered to save it to disk. I would just type it in any time I wanted to play it.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023/pudding64_cg198504.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mega65-survey-2023/pudding64_cg198504.png 397w, https://dansanderson.com/mega65/mega65-survey-2023/pudding64_cg198504_hu_7ff0d1c71e10a189.png 600w, https://dansanderson.com/mega65/mega65-survey-2023/pudding64_cg198504_hu_682335d967a5caa6.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-survey-2023/pudding64_cg198504.png&#34;
        alt=&#34;Pudding Mountain Miner program listing, from Compute!&amp;amp;#39;s Gazette April 1985&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pudding Mountain Miner program listing, from Compute!&#39;s Gazette, April 1985.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Here&amp;rsquo;s the program listing converted to a form where you can use it with &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/&#34;&gt;petcat&lt;/a&gt; to generate a PRG in case you don&amp;rsquo;t want to type it in (but what&amp;rsquo;s the fun in that?). This version runs just fine with the MEGA65&amp;rsquo;s &lt;code&gt;GO64&lt;/code&gt; mode.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 v=(peek(0)=76):w=40+18*v:t=1024-6656*v:c=55296+16896*v:s=53281+16402*v
110 c$=chr$(147):printc$:pokes,1-26*v:for i=0tow-1:q=22*w+i
115 poket+q,160:pokec+q,7:next
120 s$=chr$(32)+chr$(158)+chr$(18)+chr$(188)+chr$(146)+chr$(156)+chr$(185)
130 s$=s$+chr$(31)+chr$(175):q=rnd(1)*(w-7)+3+22*w:poket+q,164:pokec+q,5
140 fori=0tow-1:forj=0to7*rnd(1)+3:q=(21-j)*w+i:poket+q,160:pokec+q,2:next:next
150 printchr$(142);chr$(19);:y%=4*rnd(1)+1:fori=1toy%:print:next:x=0
160 l$=chr$(157):prints$;l$;l$;l$;:x=x+1:geta$:ifa$=&amp;#34;&amp;#34;andx&amp;lt;w-4then160
170 ifx=w-4thenprinttab(x);chr$(32);chr$(32);chr$(32);:goto150
180 fori=y%+2to22:q=i*w+x+1:p=peek(t+q)
190 poket+q-w,32:poket+q,90:pokec+q,8*rnd(1):ifp=32thennext
200 b=b+1:poket+q,32:ifi&amp;lt;22goto160
210 ifp&amp;lt;&amp;gt;164thenfori=0to255:pokec+q,i:poket+q,i:next:printc$;&amp;#34;you lost&amp;#34;:goto230
220 fori=1to50:poket+q,32+132*f:f=1-f:next:printc$;&amp;#34;you won! &amp;#34;;b;&amp;#34;bombs&amp;#34;
230 print:print&amp;#34;press &amp;#34;chr$(18);&amp;#34;return&amp;#34;;chr$(146);&amp;#34; to play  again&amp;#34;
240 geta$:ifa$&amp;lt;&amp;gt;chr$(13)then240
250 run&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Brannon&amp;rsquo;s article gives a line-by-line description of how the program works. I&amp;rsquo;ll try not to repeat the whole analysis, but I do want to notice a few things.&lt;/p&gt;
&lt;p&gt;For starters, it&amp;rsquo;s difficult to read. Brannon wrote this to appear in a newspaper ad, so he used Commodore BASIC&amp;rsquo;s abilities to combine multiple statements on a single line and omit spaces to cram all of the code into a dense rectangle. C64 programmers are accustomed to omitting spaces because it speeds up the program slightly when running at 1 MHz, and it uses slightly less BASIC memory. At the MEGA65&amp;rsquo;s 40 MHz, omitting spaces makes no measurable difference and isn&amp;rsquo;t worth doing.&lt;/p&gt;
&lt;p&gt;Early Commodore BASICs lack built-in commands for graphics and sound, so programs like games tend to contain many &lt;code&gt;POKE&lt;/code&gt; statements. As a result, very few lines of code say what they mean, at least to a reader that didn&amp;rsquo;t write the program. To work backwards from an obscure statement like &lt;code&gt;POKET+Q,160&lt;/code&gt;, you have to recognize that this actually says &lt;code&gt;POKE T + Q, 160&lt;/code&gt;, that the variables &lt;code&gt;T&lt;/code&gt; and &lt;code&gt;Q&lt;/code&gt; are forming an address, that &lt;code&gt;T&lt;/code&gt; is assigned the number 1024 under some circumstances, and that this is the start of C64 screen memory. Then you know to look up &lt;a href=&#34;https://sta.c64.org/cbm64scr.html&#34;&gt;a screen code table&lt;/a&gt; to determine that the value 160 represents a blank space. This statement is probably writing a blank space somewhere on the screen determined by the &lt;code&gt;Q&lt;/code&gt; variable.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not criticizing the way the program is written. If anything, I&amp;rsquo;m criticizing the way programs &lt;em&gt;had&lt;/em&gt; to be written for the Commodore 64, at least under some circumstances. Of course, Brannon intentionally wrote this program to take up as little printed space as possible, so it is designed, crunched, and organized in an atypical way.&lt;/p&gt;
&lt;p&gt;One of the most interesting parts of the program is this bit in the very first line: &lt;code&gt;V=(PEEK(0)=76)&lt;/code&gt; When this runs on a Commodore 64, the &lt;code&gt;V&lt;/code&gt; variable is set to 0. Some simple arithmetic determines how the other variables on this line are set: &lt;code&gt;W&lt;/code&gt; is set to 40, &lt;code&gt;T&lt;/code&gt; is set to 1024, &lt;code&gt;C&lt;/code&gt; is 55296, &lt;code&gt;S&lt;/code&gt; is 53281. 40 is the number of characters that fit on a single line of a C64&amp;rsquo;s screen, so &lt;code&gt;W&lt;/code&gt; probably stands for &amp;ldquo;width,&amp;rdquo; and sure enough that&amp;rsquo;s what it appears to mean elsewhere in the code.&lt;/p&gt;
&lt;p&gt;But what&amp;rsquo;s up with the &lt;code&gt;PEEK(0)&lt;/code&gt;? It turns out that this program also works on the VIC-20! When this runs on VIC-20 hardware, &lt;code&gt;PEEK(0)&lt;/code&gt; evaluates to 76, so the comparison &lt;code&gt;PEEK(0)=76&lt;/code&gt; evaluates to true, so the &lt;code&gt;V&lt;/code&gt; variable is set to -1, which is how &amp;ldquo;true&amp;rdquo; is represented in Commodore BASIC. This affects the settings for the other variables: &lt;code&gt;W=40+18*V&lt;/code&gt; becomes 22, which is the screen width for the VIC-20.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023/puddingvic.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mega65-survey-2023/puddingvic.png 666w, https://dansanderson.com/mega65/mega65-survey-2023/puddingvic_hu_a9a0ce4c5b4cf543.png 600w, https://dansanderson.com/mega65/mega65-survey-2023/puddingvic_hu_58130679eb8d0249.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-survey-2023/puddingvic.png&#34;
        alt=&#34;Pudding Mountain Miner, as it appears on a VIC-20&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pudding Mountain Miner on the VIC-20, with no code changes.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This game takes advantage of the similarities between the C64 and VIC-20, along with some intentional design choices, to scale its display to fit the computer it&amp;rsquo;s running on. This poses a question: what&amp;rsquo;s the smallest change we can make to this program so that it runs on the MEGA65 in 80-column mode?&lt;/p&gt;
&lt;p&gt;On the MEGA65, the BASIC syntax is the same, the PETSCII character and screen codes are the same, and the VIC-II registers are present at the same addresses by default. Screen memory is relocatable and not at the same location by default, so we&amp;rsquo;ll have to do something about that. Color memory (whose location is stored in the &lt;code&gt;C&lt;/code&gt; variable) needs to be accessed at a different memory location if we want to access the full 80 column&amp;rsquo;s worth.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s just try this and see what happens:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 w=80:t=$0800:c=$1f800:s=$d021&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(I&amp;rsquo;m using hexadecimal values here because I&amp;rsquo;m used to thinking of these addresses in hex, and BASIC 65 supports hexadecimal value literals.)&lt;/p&gt;
&lt;p&gt;I had read through the whole program to make sure this would work and was still surprised that it did. There&amp;rsquo;s only one issue: it&amp;rsquo;s way too fast! We need to slow down the MEGA65 processor to make it playable. Thankfully, this is possible with a BASIC 65 command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;105 speed 1&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-survey-2023/pudding65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mega65-survey-2023/pudding65.png 509w, https://dansanderson.com/mega65/mega65-survey-2023/pudding65_hu_b6b004e5c2b7deb0.png 600w, https://dansanderson.com/mega65/mega65-survey-2023/pudding65_hu_1d5fa57fe7b4c639.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-survey-2023/pudding65.png&#34;
        alt=&#34;Pudding Mountain Miner, MEGA65 version&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pudding Mountain Miner, MEGA65 version.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s the nature of this game that the denser character width makes it more difficult to hit the target, but it works! No other changes are necessary.&lt;/p&gt;
&lt;p&gt;Consolidating this into a single BASIC listing that works on all three machines would be straightforward—or not so straightforward if you want to preserve the compactness of the original. I&amp;rsquo;ll leave that as an exercise.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;That&amp;rsquo;s it! Next month should be action-packed: we&amp;rsquo;re about to open public beta testing of the next major platform release. I&amp;rsquo;m trying to do my part and fix as many bugs as I can before the deadline. Of course, this is an open project, so you can get involved with testing right away if you like. Inquire in &lt;a href=&#34;https://mega65.org/chat&#34;&gt;the Discord&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Go &lt;a href=&#34;https://tally.so/r/mDk4pZ&#34;&gt;take the survey&lt;/a&gt;, and tell your friends. See you next month!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/mega65-survey-2023/M65Digest_2023Aug.mp3" length="12861565" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>643</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/mega65-survey-2023/ships.png"/>
      
    </item>
    
    <item>
      <title>Cross Development for Fun and Profit, part 2</title>
      <link>https://dansanderson.com/mega65/cross-development-2/</link>
      <pubDate>Sat, 15 Jul 2023 00:26:15 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/cross-development-2/</guid>
      <description>&lt;p&gt;Cross Development for Fun and Profit, part 2. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for July 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Cross Development for Fun and Profit, part 2. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for July 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/cross-development-2/M65Digest_2023July.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/M65Digest_2023July.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Cross Development for Fun and Profit, part 2.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/cprog.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/cprog.png 932w, https://dansanderson.com/mega65/cross-development-2/cprog_hu_94cbcd9195bfa2dc.png 600w, https://dansanderson.com/mega65/cross-development-2/cprog_hu_5beea628c12a027d.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/cprog.png&#34;
        alt=&#34;A simple program in the C language for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A simple program in the C language for the MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/&#34;&gt;last month&amp;rsquo;s Digest&lt;/a&gt;, we introduced &lt;em&gt;cross development&lt;/em&gt;, the practice of writing MEGA65 programs using a modern PC. We looked at several tools for writing programs in the BASIC 65 language and in 45GS02 assembly language, and we welcomed a new BASIC-like compiled language with MEGA65 support called XC=BASIC.&lt;/p&gt;
&lt;p&gt;Let us take one step further into the world of compiled languages. The &lt;a href=&#34;https://en.wikipedia.org/wiki/C_(programming_language)&#34;&gt;C programming language&lt;/a&gt; is one of the most widely used programming languages in computing history, suitable for everything from microcomputers to mainframes. It was the language that built the &lt;a href=&#34;https://en.wikipedia.org/wiki/Unix&#34;&gt;Unix operating system&lt;/a&gt;—or maybe it was the other way around. Fifty years later, C is still in widespread use, for better and for worse.&lt;/p&gt;
&lt;p&gt;As fun as it is to write in assembly language, larger programs benefit from a language with a bit more structure to manage the inherent complexity of software. There are several cross-development tool chains for writing Commodore programs in C, and these can also be used to write programs for the MEGA65. In this issue, we will try using one of these tools to write our first C program, and walk through the concepts involved. We&amp;rsquo;ll look briefly at other tools and resources for getting started with C programming for microcomputers. And we&amp;rsquo;ll consider a much newer language vying to be the C of the next fifty years, called &lt;a href=&#34;https://www.rust-lang.org&#34;&gt;Rust&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ve been talking about coding tools lately, so let&amp;rsquo;s do an all-tools edition of Featured Files!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/tcc.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/tcc.png 1021w, https://dansanderson.com/mega65/cross-development-2/tcc_hu_6bcaae7ece30f0ef.png 600w, https://dansanderson.com/mega65/cross-development-2/tcc_hu_1e2d8335932e2ac8.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/tcc.png&#34;
        alt=&#34;The Coffeebreak Compiler, by TOS22&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The Coffeebreak Compiler, by TOS22.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=4fc0ab25-e381-4a64-a43c-d1d338166a7c&#34;&gt;The Coffeebreak Compiler&lt;/a&gt; by TOS22. Matthias wanted a comfortable way to hack on assembly language code directly on his MEGA65 that he could extend with modern conveniences. The result is a lightly structured custom language and IDE that accepts inline assembly code and produces machine code programs, similar to ubik&amp;rsquo;s &lt;a href=&#34;https://files.mega65.org?id=8b189d0b-ea1e-45a7-a4de-87bcb0b11696&#34;&gt;Eleven&lt;/a&gt; for BASIC. Press the &lt;kbd&gt;Help&lt;/kbd&gt; key to browse the built-in documentation and tutorials.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/forth-alpha.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/forth-alpha.png 720w, https://dansanderson.com/mega65/cross-development-2/forth-alpha_hu_7040df1ca81dd678.png 600w, https://dansanderson.com/mega65/cross-development-2/forth-alpha_hu_d4b725bb7f9112b5.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/forth-alpha.png&#34;
        alt=&#34;MEGA65-Forth alpha, by carthibar&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MEGA65-Forth alpha, by carthibar.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=3ef45802-446a-4325-bcc2-b387f818b33c&#34;&gt;MEGA65-Forth alpha&lt;/a&gt; by carthibar. MEGA65-Forth is a project to build an interpreter and interactive environment of the &lt;a href=&#34;https://www.forth.com/forth/&#34;&gt;Forth programming language&lt;/a&gt; for the MEGA65. This is an early release with some features still in progress, but enough has been implemented to start learning the language. It is based on &lt;a href=&#34;https://github.com/ptorric/figforth&#34;&gt;FIG Forth 1.1&lt;/a&gt;. Check out the &lt;a href=&#34;https://github.com/timmoorhouse/mega65-forth&#34;&gt;source code and release notes&lt;/a&gt; on Github, as well as the &lt;a href=&#34;https://github.com/timmoorhouse/mega65-forth/wiki/Getting-Started&#34;&gt;Getting Started documentation&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/bf65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/bf65.png 720w, https://dansanderson.com/mega65/cross-development-2/bf65_hu_de0a0aa906d75515.png 600w, https://dansanderson.com/mega65/cross-development-2/bf65_hu_712275dd3a00ab2b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/bf65.png&#34;
        alt=&#34;bf65, by dddaaannn&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;bf65, by dddaaannn.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=9a5390c1-3f97-4483-a42d-204844438b41&#34;&gt;bf65&lt;/a&gt; by dddaaannn (that&amp;rsquo;s me!). The experimental minimalist programming language known as &lt;a href=&#34;https://en.wikipedia.org/wiki/Brainfuck&#34;&gt;Brainfuck&lt;/a&gt; was invented by Urban Müller in 1993 as an attempt to design a language with as small a compiler as possible that is still &lt;a href=&#34;https://en.wikipedia.org/wiki/Turing_completeness&#34;&gt;Turing complete&lt;/a&gt;. The language is famous for its funny name and for having only eight parameterless instructions. I was motivated to write bf65 when I had the idea to take advantage of the MEGA65&amp;rsquo;s built-in BASIC editor as the editor for bf65 programs, including the ability to combine BASIC and bf65 code in the same program. The D81 disk image includes the bf65 interpreter and several demo programs. See &lt;a href=&#34;https://github.com/dansanderson/bf-mega65&#34;&gt;documentation and source code&lt;/a&gt; on Github.&lt;/p&gt;
&lt;h2 id=&#34;c64-for-mega65-v5-is-official&#34;&gt;C64 for MEGA65 V5 is official!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/c64formega_trailer.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/c64formega_trailer.png 1174w, https://dansanderson.com/mega65/cross-development-2/c64formega_trailer_hu_1715d944370d3c37.png 600w, https://dansanderson.com/mega65/cross-development-2/c64formega_trailer_hu_b76749e8eb3327e7.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/c64formega_trailer.png&#34;
        alt=&#34;C64 for MEGA65, title image from the release trailer video&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;C64 for MEGA65&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We&amp;rsquo;ve mentioned the Commodore 64 core for the MEGA65 a few times in this Digest, and with good reason. For many owners, the potential of the MEGA65 to be an FPGA-based multi-Commodore platform is a major attraction, a chip-level recreation of an entire line of vintage computers that share a non-PC keyboard layout, made from all-new components and modern hardware conveniences. The Commodore 64 core by MJoergen and sy2002 is a huge step toward this potential.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=896a012f-59e4-456c-b91f-7e989b958241&#34;&gt;C64 for MEGA65 version 5&lt;/a&gt; is now officially released. For installation instructions, see &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/&#34;&gt;the May issue of the Digest&lt;/a&gt;, and the &lt;a href=&#34;https://github.com/MJoergen/C64MEGA65&#34;&gt;excellent documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t miss the epic &lt;a href=&#34;https://www.youtube.com/watch?v=n3ke0alwjds&#34;&gt;video trailer for the new release&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id=&#34;megavision-video-now-available&#34;&gt;MEGAVision video now available&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/megavision_livestream.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/megavision_livestream.png 1173w, https://dansanderson.com/mega65/cross-development-2/megavision_livestream_hu_c1cf1d59901aa708.png 600w, https://dansanderson.com/mega65/cross-development-2/megavision_livestream_hu_1fe940fadef0a63.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/megavision_livestream.png&#34;
        alt=&#34;MEGAVision livestream title card&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MEGAVision!&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The first ever MEGAVision live streaming event took place on July 1st and was a huge success! Hosted by RetroCombs, Gurce, and lydon, MEGAVision featured nine short talks about MEGA65 projects. &lt;a href=&#34;https://www.youtube.com/watch?v=wifYmhIRAEs&#34;&gt;Watch the replay online&lt;/a&gt;, then visit the &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/31948801/MEGA+VISION+1&#34;&gt;MEGAVision wiki page&lt;/a&gt; for links to resources for everything discussed in the presentation. I was happy to present my bf65 toy language interpreter at the event.&lt;/p&gt;
&lt;p&gt;This was so successful that we&amp;rsquo;re excited to do another one sometime soon. Start thinking about topics you&amp;rsquo;d like to know more about, or topics you&amp;rsquo;d maybe like to talk about at the next MEGAVision. If you have an idea for a talk, send a message to Gurce or lydon on Discord.&lt;/p&gt;
&lt;p&gt;Huge thanks to the organizers, to everyone who gave a talk, and to everyone who attended!&lt;/p&gt;
&lt;h2 id=&#34;r4-mainboard-announced&#34;&gt;R4 mainboard announced&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/r4board.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/r4board.jpg 4000w, https://dansanderson.com/mega65/cross-development-2/r4board_hu_8e4f00880c7e6fa0.jpg 600w, https://dansanderson.com/mega65/cross-development-2/r4board_hu_f58b71c691262288.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/r4board.jpg&#34;
        alt=&#34;A photo of the MEGA65 main board revision 4&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The MEGA65 main board, revision 4.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 project continues to invest in improving every aspect of our favorite computer. On June 30, Paul posted &lt;a href=&#34;https://c65gs.blogspot.com/2023/06/mega65r4-bring-up.html&#34;&gt;an in-depth article&lt;/a&gt; to his developer blog describing some of the recent improvements made to the design of the MEGA65 main board. The next revision of the main board, known as R4, will start shipping with the next delivery batch later this year.&lt;/p&gt;
&lt;p&gt;Several of the improvements in the R4 board are electrical. There&amp;rsquo;s a fix for an HDMI back-power issue, improved audio quality from the 3.5 mm jack, a new Real-Time Clock (RTC) unit, and improved RF shielding for the major components. The design has also been reworked to use one fewer FPGA chip. These changes resolve some minor issues, but they otherwise do not affect the operation of the computer.&lt;/p&gt;
&lt;p&gt;Two changes enhance the capability of the system slightly. There is now additional RAM hardware that can be used by FPGA cores, enabling porting of a larger variety of MiSTer cores in the future. Also, the joystick ports are now bi-directional, a capability used by &lt;a href=&#34;https://retrocomputing.stackexchange.com/questions/12015/did-any-devices-use-the-commodore-64-joystick-ports-as-outputs-or-two-way-commun&#34;&gt;a few peripherals&lt;/a&gt; like the &lt;a href=&#34;https://www.protovision.games/shop/protopad/protopad.php?language=en&#34;&gt;Protovision Protopad&lt;/a&gt; and the Commodore version of the &lt;a href=&#34;https://en.wikipedia.org/wiki/AtariLab&#34;&gt;AtariLab&lt;/a&gt; science kit that I had as a kid.&lt;/p&gt;
&lt;p&gt;Nothing about the MEGA65 platform changes with this revision. Any program written for the MEGA65 will run on both R3 and R4 boards. While the RAM hardware is intended to enable broader development of alternate cores, no core currently exists that needs it, and it&amp;rsquo;ll be a while before one does. Moreover, future cores that don&amp;rsquo;t need the extra RAM are unlikely to use it, so that they will work on all MEGA65s.&lt;/p&gt;
&lt;p&gt;Nevertheless, it&amp;rsquo;s natural to wonder: will MEGA65 owners with the R3 main board be able to buy the R4 board as a replacement? Hopefully someday! The first priority is to fulfill all of the remaining preorders for complete MEGA65s. Beyond that, it&amp;rsquo;s not obvious that Trenz Electronic can feasibly stock spare parts, especially pre-assembled main boards with expensive FPGAs. So far, preorders have been fulfilled in batches, and it&amp;rsquo;ll take time to figure out the costs, risks, and logistics of switching to an in-stock distribution model. I know I&amp;rsquo;d love to be able to someday buy MEGA65 parts for upgrades, repairs, and building new machines with custom configurations.&lt;/p&gt;
&lt;p&gt;For now, I&amp;rsquo;m excited by how the R4 main board is an investment in the MEGA65&amp;rsquo;s continued success. More than anything else, it means we will all get more out of our computers, no matter which version we have.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;a-single-file-c-program&#34;&gt;A single-file C program&lt;/h2&gt;
&lt;p&gt;A &lt;em&gt;compiler&lt;/em&gt; is a tool that takes a computer program written in some programming language and generates an equivalent program for the target platform&amp;rsquo;s machine code. You can write a program in the C programming language, then use a C compiler to generate the equivalent machine code program for the MEGA65.&lt;/p&gt;
&lt;p&gt;As with other development tools, a compiler could be a program that runs on the target device directly, like how &lt;a href=&#34;https://files.mega65.org?id=3b101d41-5128-4a21-879c-0cf7988edfec&#34;&gt;Mega Assembler&lt;/a&gt; runs on the MEGA65. There is not yet a C compiler that runs natively on the MEGA65, but it is possible to use a cross development workflow as we did in &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/&#34;&gt;the previous issue of the Digest&lt;/a&gt;. You create a &lt;em&gt;source file&lt;/em&gt; on our PC, then use a &lt;em&gt;cross compiler&lt;/em&gt; to generate a MEGA65 PRG file.&lt;/p&gt;
&lt;p&gt;As much as I want to, I can&amp;rsquo;t fit a full C language tutorial in this Digest. Nevertheless, let&amp;rsquo;s start with a small C program, so we have something to play with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
  puts(&amp;#34;IT&amp;#39;S A C PROGRAM!\n&amp;#34;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Put this in a file named &lt;code&gt;hello.c&lt;/code&gt;. This is our source file.&lt;/p&gt;
&lt;p&gt;Most C programs consist of multiple source files, with filenames ending in &lt;code&gt;.c&lt;/code&gt; for definitions and &lt;code&gt;.h&lt;/code&gt; for declarations (&amp;ldquo;header&amp;rdquo; files). Exactly one &lt;code&gt;.c&lt;/code&gt; file defines a function named &lt;code&gt;main()&lt;/code&gt;, which is where the program begins. A source file can &lt;code&gt;#include&lt;/code&gt; header files to learn about functions provided by other modules. In this case, &lt;code&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/code&gt; brings in the declarations from a module of the C standard library, including a declaration for the &lt;code&gt;puts()&lt;/code&gt; function used by the &lt;code&gt;main()&lt;/code&gt; function. Refer to any good book on C programming for an explanation of how C programs are organized.&lt;/p&gt;
&lt;p&gt;An ideal compiler targeting the MEGA65 would know all about the inner workings of the MEGA65&amp;rsquo;s CPU, so it can use all of the CPU&amp;rsquo;s features in its machine code. So far, nobody has written a C compiler that targets the MEGA65 specifically. Instead, we&amp;rsquo;ll take advantage of the MEGA65&amp;rsquo;s Commodore lineage and use a cross compiler that targets earlier Commodore computers. Several Commodore cross compilers can be adjusted to generate programs that run on the MEGA65.&lt;/p&gt;
&lt;h2 id=&#34;installing-llvm-mos&#34;&gt;Installing llvm-mos&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://llvm-mos.org/wiki/Welcome&#34;&gt;llvm-mos&lt;/a&gt; by Daniel Thornburgh and John Byrd is a cross compiler toolchain for target platforms based on the 6502 CPU. It provides a version of &lt;a href=&#34;https://clang.llvm.org&#34;&gt;Clang&lt;/a&gt; for compiling C programs. Thanks to Mikael Lund (wombat on the Discord), llvm-mos supports building programs for the MEGA65. It supports generating code for CPUs in the 6502 lineage up to the 65C02, which will run fine on a MEGA65.&lt;/p&gt;
&lt;p&gt;Visit &lt;a href=&#34;https://github.com/llvm-mos/llvm-mos-sdk&#34;&gt;the llvm-mos Github page&lt;/a&gt;, then scroll down to find the download link for your PC&amp;rsquo;s operating system. As usual, macOS requires an additional step to allow unsigned command line tools to run. A complete procedure for macOS users:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-macos.tar.xz&#34;&gt;Download llvm-mos for macOS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tar xzf llvm-mos-macos.tar.xz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xattr -d com.apple.quarantine llvm-mos/bin/*&lt;/code&gt; Ignore the list of &amp;ldquo;No such xattr&amp;rdquo; warnings.&lt;/li&gt;
&lt;li&gt;Verify that the &lt;code&gt;mos-mega65-clang&lt;/code&gt; command line tool works: &lt;code&gt;./llvm-mos/bin/mos-mega65-clang --help&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As noted in the llvm-mos documentation, you can add the &lt;code&gt;bin/&lt;/code&gt; folder to your command path for convenient access. macOS users, heed the warning that doing so may conflict with other versions of the Clang compiler you may have installed. The Apple Xcode Command Line Tools provide another version of Clang, and you may have this installed if you use &lt;a href=&#34;https://brew.sh&#34;&gt;Homebrew&lt;/a&gt; even if you don&amp;rsquo;t otherwise use Xcode. You do not need to have llvm-mos on your command path to use it: simply provide the full path to the llvm-mos commands when using them.&lt;/p&gt;
&lt;p&gt;You can compile the &lt;code&gt;hello.c&lt;/code&gt; example program with the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./llvm-mos/bin/mos-mega65-clang -Wall -Os -o hello.prg hello.c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This produces the file &lt;code&gt;hello.prg&lt;/code&gt; that you can run in Xemu or on your MEGA65, as we discussed in &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/&#34;&gt;the previous issue&lt;/a&gt;. It loads to the top of BASIC memory with a BASIC bootstrap header, similar to the one we used for our assembly language program.&lt;/p&gt;
&lt;h2 id=&#34;the-equivalent-program&#34;&gt;The equivalent program&lt;/h2&gt;
&lt;p&gt;So far, a compiler sounds a lot like an assembler: it takes a source file and produces a PRG file that does what we want. What&amp;rsquo;s different is how the tool decides what machine code to generate. When we write a program in assembly language, we must say exactly which machine code instructions the target machine&amp;rsquo;s CPU should execute. Assembly language mnemonics like &lt;code&gt;LDA&lt;/code&gt; represent machine code instructions in a somewhat-human-readable syntax, and the assembler translates the assembly language to machine code, one instruction at a time.&lt;/p&gt;
&lt;p&gt;When you write a program in a compiled language, the compiler reads through your program, then decides which machine code instructions will do what you intend. You can ask llvm-mos to show you the assembly language program that it came up with for your C program with this command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./llvm-mos/bin/mos-mega65-clang -Os -o hello.s -Wl,--lto-emit-asm hello.c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This generates an assembly language listing as the file &lt;code&gt;hello.s&lt;/code&gt;. Open this in a text editor to see the result. It is quite large because it includes the code for the &lt;code&gt;puts()&lt;/code&gt; function from the standard library.&lt;/p&gt;
&lt;p&gt;To get a better idea of what compilers can do, consider a simpler program that doesn&amp;rsquo;t involve a call to a large function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int square(int num) {
  return num * num;
}

int main(void) {
  return square(5);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s a website called &lt;a href=&#34;https://godbolt.org&#34;&gt;Compiler Explorer&lt;/a&gt;, aka &amp;ldquo;GodBolt.org,&amp;rdquo; that can show C code and the compiled assembly code side by side directly in your browser. It supports many compilers and target CPUs, including llvm-mos and the MEGA65, so you can see the result in 6502 assembly language.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:&#39;1&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,selection:(endColumn:11,endLineNumber:7,positionColumn:11,positionLineNumber:7,selectionStartColumn:11,selectionStartLineNumber:7,startColumn:11,startLineNumber:7),source:&#39;/*+Type+your+code+here,+or+load+an+example.+*/%0Aint+square(int+num)+%7B%0A++++return+num+*+num%3B%0A%7D%0A%0Aint+main(void)+%7B%0A++++return+square(5)%3B%0A%7D&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;C+source+%231&#39;,t:&#39;0&#39;)),k:50,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:compiler,i:(compiler:cmos-mega65-trunk,deviceViewOpen:&#39;1&#39;,filters:(b:&#39;0&#39;,binary:&#39;1&#39;,binaryObject:&#39;1&#39;,commentOnly:&#39;0&#39;,debugCalls:&#39;1&#39;,demangle:&#39;0&#39;,directives:&#39;0&#39;,execute:&#39;1&#39;,intel:&#39;0&#39;,libraryCode:&#39;0&#39;,trim:&#39;1&#39;),flagsViewOpen:&#39;1&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,libs:!(),options:&#39;&#39;,overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;+llvm-mos+mega65+(Editor+%231)&#39;,t:&#39;0&#39;)),k:50,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;)),l:&#39;2&#39;,n:&#39;0&#39;,o:&#39;&#39;,t:&#39;0&#39;)),version:4&#34;&gt;Follow this link&lt;/a&gt; to see one possible version of &lt;code&gt;square()&lt;/code&gt; and &lt;code&gt;main()&lt;/code&gt; produced from this C code.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/godbolt.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/godbolt.png 753w, https://dansanderson.com/mega65/cross-development-2/godbolt_hu_3d154b39a916f1f8.png 600w, https://dansanderson.com/mega65/cross-development-2/godbolt_hu_d5962591de93abb9.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/godbolt.png&#34;
        alt=&#34;The Compiler Explorer website, with a short C program and the llvm-mos MEGA65 result&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Compiler Explorer.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In this example, you can see how llvm-mos converts the &lt;code&gt;square()&lt;/code&gt; function into several dozen instructions. The labels that begin with two underscores, such as &lt;code&gt;__rc0&lt;/code&gt;, refer to addresses in the base page that llvm-mos sets up to be used as temporary variables by the generated code. Later in the listing is the implementation for the &lt;code&gt;main()&lt;/code&gt; function that sets up the argument (&lt;code&gt;5&lt;/code&gt;), calls the &lt;code&gt;square()&lt;/code&gt; function, and ends with the result in a variable. The C language requires that the &lt;code&gt;main()&lt;/code&gt; routine returns a number, which is used by some operating systems as a result code from a program. The MEGA65 just ignores this return value.&lt;/p&gt;
&lt;p&gt;But that&amp;rsquo;s just one possible assembly language program. Check out &lt;a href=&#34;https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:&#39;1&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,selection:(endColumn:11,endLineNumber:7,positionColumn:11,positionLineNumber:7,selectionStartColumn:11,selectionStartLineNumber:7,startColumn:11,startLineNumber:7),source:&#39;/*+Type+your+code+here,+or+load+an+example.+*/%0Aint+square(int+num)+%7B%0A++++return+num+*+num%3B%0A%7D%0A%0Aint+main(void)+%7B%0A++++return+square(5)%3B%0A%7D&#39;),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;C+source+%231&#39;,t:&#39;0&#39;)),k:50,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:compiler,i:(compiler:cmos-mega65-trunk,deviceViewOpen:&#39;1&#39;,filters:(b:&#39;0&#39;,binary:&#39;1&#39;,binaryObject:&#39;1&#39;,commentOnly:&#39;0&#39;,debugCalls:&#39;1&#39;,demangle:&#39;0&#39;,directives:&#39;0&#39;,execute:&#39;1&#39;,intel:&#39;0&#39;,libraryCode:&#39;0&#39;,trim:&#39;1&#39;),flagsViewOpen:&#39;1&#39;,fontScale:14,fontUsePx:&#39;0&#39;,j:1,lang:___c,libs:!(),options:&#39;-Os&#39;,overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;+llvm-mos+mega65+(Editor+%231)&#39;,t:&#39;0&#39;)),k:50,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;)),l:&#39;2&#39;,n:&#39;0&#39;,o:&#39;&#39;,t:&#39;0&#39;)),version:4&#34;&gt;this version with the &lt;code&gt;-Os&lt;/code&gt; flag enabled&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/godbolt_opt.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/godbolt_opt.png 717w, https://dansanderson.com/mega65/cross-development-2/godbolt_opt_hu_49494c4fac7f1d7.png 600w, https://dansanderson.com/mega65/cross-development-2/godbolt_opt_hu_b6032a48b9e69269.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/godbolt_opt.png&#34;
        alt=&#34;The Compiler Explorer, with the optimization flag set and a much shorter assembly language result&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Compiler Explorer with llvm-mos in optimization mode; complete listing shown
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Given the &lt;code&gt;-Os&lt;/code&gt; flag, llvm-mos generates different assembly language code for the same C program. It&amp;rsquo;s much shorter and much faster than the previous version. How can a compiler look at the same program and produce two drastically different results?&lt;/p&gt;
&lt;p&gt;In the first version, llvm-mos took our C program literally: we wrote it as two functions, so it generated code for two functions. In this new version, llvm-mos studied the C source code, realized that this program always returns the number 25, so it produced machine code that returns the number 25. Both of these assembly language programs are equivalent to the original C program: they both return 25.&lt;/p&gt;
&lt;p&gt;An &lt;em&gt;optimizing compiler&lt;/em&gt; uses many complex techniques to calculate the smallest and fastest machine code possible that is equivalent to your original program. The &lt;code&gt;-Os&lt;/code&gt; flag enables all of llvm-mos&amp;rsquo;s optimization rules. Optimization is typically smart enough that you can leave it enabled for nearly all purposes. It&amp;rsquo;s not always perfect—I can&amp;rsquo;t explain why llvm-mos generates a few instructions for the &lt;code&gt;square()&lt;/code&gt; function in the optimized version even though it never calls them—but it&amp;rsquo;s a huge benefit.&lt;/p&gt;
&lt;p&gt;Just as modern chess computers can play chess better than any human, modern compilers can write machine code so efficient that it&amp;rsquo;s almost not worth writing in assembly language at all. We still write assembly language programs for the same reason we still play chess: for fun.&lt;/p&gt;
&lt;h2 id=&#34;cmake-mega65-libc-and-mega65-llvm-template&#34;&gt;CMake, mega65-libc, and mega65-llvm-template&lt;/h2&gt;
&lt;p&gt;Running the &lt;code&gt;mos-mega65-clang&lt;/code&gt; command is fine enough for simple one-file experiments. When your project grows to multiple source files or involves third-party libraries, you will want a build management tool. &lt;a href=&#34;https://cmake.org&#34;&gt;CMake&lt;/a&gt; and &lt;a href=&#34;https://ninja-build.org&#34;&gt;Ninja&lt;/a&gt; are popular with the modern C crowd. (I still use &lt;a href=&#34;https://www.gnu.org/software/make/&#34;&gt;GNU Make&lt;/a&gt;, but I&amp;rsquo;m old school.)&lt;/p&gt;
&lt;p&gt;One third-party library you&amp;rsquo;ll want to consider early on is &lt;a href=&#34;https://github.com/mega65/mega65-libc&#34;&gt;mega65-libc&lt;/a&gt;, the MEGA65 project&amp;rsquo;s own set of utility functions. This library provides functions that access files from a disk or the SD card, access memory, power a console-like user interface, and more. The library is useful enough for things like debugging that you pretty much always want to include it in your project, even if you don&amp;rsquo;t intend to use most of it. The compiler will only generate code for the functions that you use.&lt;/p&gt;
&lt;p&gt;Thanks to kibo, there&amp;rsquo;s an easy way to get everything you need to set up your MEGA65 C project, including CMake and mega65-libc. &lt;a href=&#34;https://github.com/ki-bo/mega65-llvm-template&#34;&gt;mega65-llvm-template&lt;/a&gt; is a Github project template that you can either use to create a new Github repository, or just download to try it out. See the template&amp;rsquo;s documentation for instructions.&lt;/p&gt;
&lt;h2 id=&#34;mega65-c-tips-and-tricks&#34;&gt;MEGA65 C tips and tricks&lt;/h2&gt;
&lt;p&gt;Before you dive into a good book on the C language, it&amp;rsquo;s important to note that llvm-mos has a few limitations when it comes to standard C. For starters, it does not support the &lt;code&gt;float&lt;/code&gt; or &lt;code&gt;double&lt;/code&gt; fractional number types. The 6502 CPU does not have built-in support for floating point math, and llvm-mos does not provide a floating point math library. If you&amp;rsquo;re ambitious, you could consider third-party assembly language routines for this purpose, such as &amp;ldquo;&lt;a href=&#34;http://www.6502.org/source/floats/wozfp1.txt&#34;&gt;Floating Point Routines for the 6502&lt;/a&gt;&amp;rdquo; by Steve Wozniak, from the magazine Dr. Dobb&amp;rsquo;s Journal in August 1976.&lt;/p&gt;
&lt;p&gt;llvm-mos provides a stripped-down version of the C standard library implemented for Commodore computers, using C64-style kernel calls for things like printing messages. The implementation is incomplete, and some functions may not work correctly on the MEGA65. It&amp;rsquo;s worth trying, just don&amp;rsquo;t expect everything to work.&lt;/p&gt;
&lt;p&gt;If your C program returns from &lt;code&gt;main()&lt;/code&gt;, either with the &lt;code&gt;return&lt;/code&gt; statement or by allowing control to reach the end of the function, the program llvm-mos generates will attempt to return to BASIC. This doesn&amp;rsquo;t always work with the MEGA65 kernel. I sometimes get weird display artifacts, false BASIC errors, or crashes when returning from &lt;code&gt;main()&lt;/code&gt;. Consider ending your program with an infinite loop (&lt;code&gt;while(1);&lt;/code&gt;) and not relying on exiting to BASIC.&lt;/p&gt;
&lt;p&gt;In C, character values (&lt;code&gt;&#39;x&#39;&lt;/code&gt;) and string values (&lt;code&gt;&amp;quot;xyz&amp;quot;&lt;/code&gt;) are treated as ASCII byte values. These are neither PETSCII values nor Commodore screen codes, so you will need to account for this when defining and printing text messages to the screen. Using uppercase ASCII letters in your C source code along with the MEGA65&amp;rsquo;s default uppercase character mode will print uppercase letters.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re writing a game—or pretty much anything, honestly—your program will need to access registers and memory addresses directly, similar to &lt;code&gt;POKE&lt;/code&gt; and &lt;code&gt;PEEK&lt;/code&gt; from BASIC, or &lt;code&gt;lda&lt;/code&gt; and &lt;code&gt;sta&lt;/code&gt; in assembly language. This is possible in C, taking care to use C&amp;rsquo;s pointer dereferencing features correctly. Use an appropriate value type for bytes (such as &lt;code&gt;uint8_t&lt;/code&gt; from &lt;code&gt;stdint.h&lt;/code&gt;), and be sure to refer to an I/O register as &lt;code&gt;volatile&lt;/code&gt; to prevent the optimizer from taking shortcuts. mega65-libc&amp;rsquo;s &lt;code&gt;memory.h&lt;/code&gt; provides useful macros and functions for accessing registers, so it looks cleaner in your code and you don&amp;rsquo;t have to remember the details:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdint.h&amp;gt;

// From mega65-libc:
#include &amp;lt;memory.h&amp;gt;

...
  POKE(0xD020, 5);
  uint8_t joy2 = PEEK(0xDC00);

  // Without mega65-libc:
  (*(volatile uint8_t *)(0xD020)) = 5;
  uint8_t joy2 = (*(volatile uint8_t *)(0xDC00));&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Programs generated by llvm-mos start by unmapping the BASIC ROM to make more room for program memory. The program code starts at address &lt;code&gt;$2001&lt;/code&gt;, including the BASIC bootstrap program. The space beyond the end of the program up to address &lt;code&gt;$CFFF&lt;/code&gt; is used for memory managed by the C language, a total of 44 kilobytes for both program and memory. Memory allocated by the program using the C standard library &lt;code&gt;malloc()&lt;/code&gt; function, a mechanism known as the &lt;em&gt;heap&lt;/em&gt;, starts just after the program and &amp;ldquo;grows upward&amp;rdquo; toward higher addresses. The &lt;em&gt;stack,&lt;/em&gt; used for keeping track of function calls and local variables, ends at address &lt;code&gt;$CFFF&lt;/code&gt; and &amp;ldquo;grows downward&amp;rdquo; toward lower addresses. The I/O registers remain in &lt;code&gt;$D000-$DFFF&lt;/code&gt;, and the kernel ROM in &lt;code&gt;$E000-$FFFF&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Sometimes you&amp;rsquo;ll want the ability to write assembly language code inside your C code. Clang supports the &lt;a href=&#34;http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html&#34;&gt;GCC inline assembly syntax&lt;/a&gt;, expecting to output 6502 assembly language for llvm-mos&amp;rsquo;s assembler. This requires giving the optimizer some hints about what the assembly code does, so it can make decisions about using CPU registers and relocating code. The following example from mega65-libc takes an &lt;code&gt;unsigned char&lt;/code&gt; variable from the C code and calls a &amp;ldquo;Hypervisor trap&amp;rdquo; with a bit of assembly language, informing the optimizer that this code must be executed in this location (&lt;code&gt;volatile&lt;/code&gt;) and that it uses the accumulator (&lt;code&gt;&amp;quot;a&amp;quot;&lt;/code&gt;). Notice how the assembly language text is a single C string with newline delimiters (&lt;code&gt;\n&lt;/code&gt;).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;unsigned char the_char;
void debug_msg(char* m)
{
  // Write debug message to serial monitor
  while (*m) {
    the_char = *m;
    asm volatile(&amp;#34;lda the_char\n&amp;#34;
                 &amp;#34;sta $d643\n&amp;#34;
                 &amp;#34;clv&amp;#34; ::: &amp;#34;a&amp;#34;);
    m++;
  }
  // ...
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A sophisticated program might want to install &lt;a href=&#34;https://www.c64-wiki.com/wiki/Interrupt&#34;&gt;interrupt handlers&lt;/a&gt; that call C functions, such as a &lt;a href=&#34;https://www.c64-wiki.com/wiki/Raster_interrupt&#34;&gt;raster interrupt&lt;/a&gt; handler that is called once per frame. This is an advanced technique that requires disabling interrupts, setting the address of the function, and updating the MAP register to disable the kernel. I won&amp;rsquo;t include a complete example here, but here&amp;rsquo;s one way to get the address of a C function as two bytes, using &lt;code&gt;volatile&lt;/code&gt; once again to make sure the optimizer keeps the function even if it isn&amp;rsquo;t called by the rest of the program.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;volatile void do_frame(void) {
  // ...
}

// ...
  unsigned char addrlow = (long)do_frame &amp;amp; 0xff;
  unsigned char addrhigh = ((long)do_frame &amp;gt;&amp;gt; 8) &amp;amp; 0xff;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enable compiler warnings. The C language gives you plenty of opportunity to make mistakes, and Clang is very smart about noticing potential issues in your code. The command line flags &lt;code&gt;-Wall -Wextra -Wpedantic&lt;/code&gt; tell the compiler to go crazy with the constructive feedback. To enable this using the mega65-llvm-template, add this to the file &lt;code&gt;CMakeLists.txt&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;target_compile_options(hello.prg PRIVATE
  -Wall -Wextra -Wpedantic
)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;learning-more-about-c&#34;&gt;Learning more about C&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/cbooks.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/cbooks.png 1013w, https://dansanderson.com/mega65/cross-development-2/cbooks_hu_a3cd13f48c52f0b8.png 600w, https://dansanderson.com/mega65/cross-development-2/cbooks_hu_bea5a71373112d21.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/cbooks.png&#34;
        alt=&#34;Book covers: The C Programming Language, by Brian W. Kernighan; C Programming: A Modern Approach, by K. N. King&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Books about C.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The most famous book for learning the C programming language is &lt;a href=&#34;https://archive.org/details/the_c_programming_language_2_20181213&#34;&gt;The C Programming Language&lt;/a&gt; by Brian W. Kernighan and Dennis M. Ritchie. Ritchie invented the C language, and this concise book is a computer science classic.&lt;/p&gt;
&lt;p&gt;My favorite book for learning C is &lt;a href=&#34;http://knking.com/books/c2/&#34;&gt;C Programming: A Modern Approach&lt;/a&gt;, 2nd edition, by K. N. King. It&amp;rsquo;s excellent for self-learning with high quality and well tested examples and exercises. I&amp;rsquo;ve literally read this book cover to cover and have done nearly all of the exercises, and I still go back to it to remind myself of language intricacies.&lt;/p&gt;
&lt;p&gt;I wouldn&amp;rsquo;t be surprised if many of the examples from these books worked on the MEGA65, but I would be surprised if they &lt;em&gt;all&lt;/em&gt; did. If you&amp;rsquo;re new to the C language, I would recommend starting with a C compiler for a modern computer first: &lt;a href=&#34;https://developer.apple.com/xcode/&#34;&gt;Xcode for macOS&lt;/a&gt;, &lt;a href=&#34;https://gcc.gnu.org&#34;&gt;GNU C for Linux&lt;/a&gt;, &lt;a href=&#34;https://visualstudio.microsoft.com/vs/community/&#34;&gt;Visual Studio Community for Windows&lt;/a&gt;. You will only need a subset of C&amp;rsquo;s features to write substantial programs for the MEGA65.&lt;/p&gt;
&lt;p&gt;There are several other C compilers that work reasonably well for MEGA65 development. &lt;a href=&#34;https://cc65.github.io&#34;&gt;cc65&lt;/a&gt; is popular with C64 programmers and has a long history. It is used by the MEGA65 project in many places. &lt;a href=&#34;https://gitlab.com/camelot/kickc&#34;&gt;KickC&lt;/a&gt; is another, using the venerable &lt;a href=&#34;http://theweb.dk/KickAssembler/Main.html#frontpage&#34;&gt;Kick Assembler&lt;/a&gt; for generating machine code. &lt;a href=&#34;https://www.calypsi.cc&#34;&gt;Calypsi&lt;/a&gt; by hth313 is a C and assembly development toolkit for several vintage computers. Calypsi’s MEGA65 support is in early stages, but it already supports 45GS02 instructions, 64-bit integers (&lt;code&gt;long long&lt;/code&gt;), and floating point math.&lt;/p&gt;
&lt;p&gt;I chose llvm-mos for this Digest because it takes advantage of the LLVM ecosystem to have the most complete implementation of the C language and the best optimizer. With a built-in MEGA65 configuration, it&amp;rsquo;s also just the easiest to get running for MEGA65 projects.&lt;/p&gt;
&lt;h2 id=&#34;other-llvm-mos-tools&#34;&gt;Other llvm-mos tools&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://llvm.org&#34;&gt;LLVM&lt;/a&gt; project reinvents the way cross compilers are built: instead of a single compiler dedicated to a single language and target system, LLVM is divided into separate layers for the language, the optimizer, and the target. llvm-mos is a target &lt;em&gt;backend&lt;/em&gt; for Commodore computers, and is able to take advantage of a suite of cutting edge tools and language &lt;em&gt;frontends&lt;/em&gt;. Because it is based on LLVM, llvm-mos is able to power multiple language compilers, and use the state-of-the-art optimizer from the LLVM core.&lt;/p&gt;
&lt;p&gt;The llvm-mos package you just installed includes not only the C compiler called &lt;em&gt;Clang,&lt;/em&gt; but also a &lt;a href=&#34;https://en.wikipedia.org/wiki/C%2B%2B&#34;&gt;C++&lt;/a&gt; compiler &lt;em&gt;Clang++.&lt;/em&gt; Start writing C++ programs for your MEGA65 today with the &lt;code&gt;mos-mega65-clang++&lt;/code&gt; command!&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;clang-tidy&lt;/code&gt; command is a tool known as a &lt;em&gt;static analyzer&lt;/em&gt;. It can examine your C code, find bugs, and recommend improvements. Programming IDEs like Visual Studio Code can be configured to run such tools automatically to highlight problems as you are coding. Tell VSCode to use the language server included with llvm-mos, called &lt;code&gt;clangd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can find all of these and more in the &lt;code&gt;bin/&lt;/code&gt; folder of llvm-mos.&lt;/p&gt;
&lt;h2 id=&#34;rust&#34;&gt;Rust&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development-2/rust-logo-blk.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/cross-development-2/rust-logo-blk.png 400w, https://dansanderson.com/mega65/cross-development-2/rust-logo-blk_hu_33025dad3d777907.png 600w, https://dansanderson.com/mega65/cross-development-2/rust-logo-blk_hu_2554c433fc044b52.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development-2/rust-logo-blk.png&#34;
        alt=&#34;The Rust programming language logo&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Rust programming language.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Take everything you&amp;rsquo;ve just learned about C and throw it in the bin! The new hotness that all the kids are on about is &lt;a href=&#34;https://www.rust-lang.org&#34;&gt;Rust&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#[start]
fn _main(_argc: isize, _argv: *const *const u8) -&amp;gt; isize {
    let mut rng = sid::SIDRng::new(c64::sid());
    for offset in 0..80 * 25 {
        let character = [77u8, 78u8].choose(&amp;amp;mut rng).copied().unwrap();
        unsafe {
            mega65::DEFAULT_SCREEN
                .add(offset)
                .write_volatile(character)
        };
    }
    println!(&amp;#34;HELLO MEGA65 FROM RUST&amp;#34;);
    0
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust is an important new language that intends to be just as powerful as C while making it easier to write programs that are more secure and have fewer bugs. I won&amp;rsquo;t go into detail on Rust for this Digest—I&amp;rsquo;m still learning it myself—but I wanted to take a moment to highlight the work wombat has done to bring Rust programming to the MEGA65. See &lt;a href=&#34;https://www.youtube.com/live/wifYmhIRAEs?feature=share&amp;amp;t=2535&#34;&gt;wombat&amp;rsquo;s MEGAVision talk&lt;/a&gt; for a brief video overview.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/mrk-its/rust-mos&#34;&gt;rust-mos&lt;/a&gt; by Mariusz Krynski is a version of the Rust compiler customized for Commodore microcomputers. It requires llvm-mos, with modified installation instructions. Setting up the tool chain is somewhat involved, so read the README file carefully, or consider using &lt;a href=&#34;https://hub.docker.com/r/mrkits/rust-mos&#34;&gt;a pre-made Docker image&lt;/a&gt; if you&amp;rsquo;re familiar with how to do that. wombat&amp;rsquo;s &lt;a href=&#34;https://crates.io/crates/mos-hardware&#34;&gt;mos-hardware&lt;/a&gt; is a Rust &amp;ldquo;crate&amp;rdquo; with libraries and examples for interfacing with MEGA65 hardware. There&amp;rsquo;s also a project template: &lt;a href=&#34;https://github.com/mlund/mos-hardware-template&#34;&gt;mos-hardware-template&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For learning the Rust language, start with &lt;a href=&#34;https://www.rust-lang.org/learn&#34;&gt;Learn Rust&lt;/a&gt;, the official online book and other resources. We&amp;rsquo;re still figuring out the best way to write Rust programs for the MEGA65, so be sure to join us in the #rust channel on &lt;a href=&#34;http://mega65.org/chat&#34;&gt;the MEGA65 Discord&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Compared to assembly language, languages like C and Rust provide &lt;em&gt;abstractions&lt;/em&gt; that make programs easier to write and understand. They are essential tools for producing large programs whose complexity can be difficult or expensive to manage. Even without perfect compilers that take full advantage of the MEGA65 CPU and memory system, the tools currently available provide plenty of power for MEGA65 development. I still try to write in assembly language occasionally to feel a sense of camaraderie with early programmers that didn&amp;rsquo;t have these tools, but it&amp;rsquo;s good to know that they&amp;rsquo;re just an arm&amp;rsquo;s reach away.&lt;/p&gt;
&lt;p&gt;Happy coding!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/cross-development-2/M65Digest_2023July.mp3" length="38370136" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1918</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/cross-development-2/cprog.png"/>
      
    </item>
    
    <item>
      <title>Cross Development for Fun and Profit, part 1</title>
      <link>https://dansanderson.com/mega65/cross-development/</link>
      <pubDate>Tue, 20 Jun 2023 23:01:43 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/cross-development/</guid>
      <description>&lt;p&gt;Cross Development for Fun and Profit, part 1. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for June 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Cross Development for Fun and Profit, part 1. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for June 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/cross-development/M65Digest_2023June.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/cross-development/M65Digest_2023June.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Cross Development for Fun and Profit, part 1.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/tempconv.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development/tempconv.png 872w, https://dansanderson.com/mega65/cross-development/tempconv_hu_6b62353cf67f5a4f.png 600w, https://dansanderson.com/mega65/cross-development/tempconv_hu_11ae2e74cd3ed0e8.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development/tempconv.png&#34;
        alt=&#34;A program being written for the MEGA65, in Visual Studio Code on a Mac, in the XC=BASIC language&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A program being written for the MEGA65, in Visual Studio Code on a Mac.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There&amp;rsquo;s something wholesome about writing a program on a vintage computer. Such a computer was designed to give equal attention to programs written by their operator and programs written by software companies, and included everything you would need to get started writing such programs. Compared to modern software development, the constraints of on-device retro coding can be comforting and inspiring. When all you have is a Commodore, some graph paper, and a reference manual, you can concentrate on creating programs and solving problems without distraction.&lt;/p&gt;
&lt;p&gt;Professional software companies didn&amp;rsquo;t always do it this way. Larger companies often used other computers to produce Commodore software, such as a mainframe computer with larger storage, computation, and multi-user collaboration capabilities. They would write code using languages like C, and use specialized tools that combined the efforts of programmers and artists into data that could be written to a disk and run on a Commodore. Known as &lt;em&gt;cross development&lt;/em&gt;, this workflow gave these companies a competitive advantage: they could work faster, collaborate better, reuse code across projects, and even develop their programs for multiple kinds of computers at the same time.&lt;/p&gt;
&lt;p&gt;Today, many hobbyists use modern computers to write programs for vintage machines. There are so many good cross-development tools at our disposal that we can&amp;rsquo;t cover them all in one Digest. This month, we&amp;rsquo;ll consider the advantages of cross development, and survey a few tools you can use to write MEGA65 programs in BASIC and assembly language. We&amp;rsquo;ll highlight recent developments in these tools made specifically for MEGA65 programming. And we&amp;rsquo;ll introduce an exciting new cross-development language that has just added MEGA65 support: XC=BASIC.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;Three quick entertainments in this month&amp;rsquo;s selections.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/bumppocket.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development/bumppocket.png 881w, https://dansanderson.com/mega65/cross-development/bumppocket_hu_13edc895d3c80e51.png 600w, https://dansanderson.com/mega65/cross-development/bumppocket_hu_c66eb5fce2148aaf.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development/bumppocket.png&#34;
        alt=&#34;Bump Pocket, by MightyAxle&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Bump Pocket, by MightyAxle.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=7cbdae17-2d36-4599-bb44-b48b8aba4b7d&#34;&gt;Bump Pocket&lt;/a&gt;, by MightyAxle. Collect colored orbs for points and dodge bombs in this action game, written in BASIC using CBM prg Studio. Use a joystick in port 2.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/10printracer.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development/10printracer.png 705w, https://dansanderson.com/mega65/cross-development/10printracer_hu_79dcd34db1dcf796.png 600w, https://dansanderson.com/mega65/cross-development/10printracer_hu_a1c02e45ea4be56a.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development/10printracer.png&#34;
        alt=&#34;10 PRINT Racer 80 Column, by JaixBly&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;10 PRINT Racer 80 Column, by JaixBly.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=bd94ff20-af0a-4bb4-8829-6108679da41e&#34;&gt;10 PRINT Racer 80 Column&lt;/a&gt; by JaixBly. Speed down a path cut through the famous &lt;a href=&#34;https://10print.org&#34;&gt;10 PRINT&lt;/a&gt; pattern, in this conversion of &lt;a href=&#34;https://www.youtube.com/watch?v=bCTrdVhjjWo&#34;&gt;a game by Robin of 8-Bit Show and Tell&lt;/a&gt;. Press 4 and 6 to move left and right.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/megapoly.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development/megapoly.jpg 1024w, https://dansanderson.com/mega65/cross-development/megapoly_hu_fe123179a41eee27.jpg 600w, https://dansanderson.com/mega65/cross-development/megapoly_hu_77d65d0a7a0b08a5.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development/megapoly.jpg&#34;
        alt=&#34;MegaPoly, by MirageBD&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MegaPoly, by MirageBD.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=3c4067cf-2d89-46ca-a936-536b835e724e&#34;&gt;MegaPoly&lt;/a&gt;, by MirageBD. An homage to the &lt;a href=&#34;http://www.generationamiga.com/2020/04/14/amiga-history-the-story-of-the-boing-ball/&#34;&gt;Amiga Boing Ball&lt;/a&gt; demo, this modern take renders a smoothly animated rotating 3D shape using the MEGA65&amp;rsquo;s DMA hardware. Keep this running in the background at your next club meeting!&lt;/p&gt;
&lt;h2 id=&#34;megavision-project-share-july-1&#34;&gt;MEGAVision project share, July 1&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/megavision.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development/megavision.png 3509w, https://dansanderson.com/mega65/cross-development/megavision_hu_3111e6579da17202.png 600w, https://dansanderson.com/mega65/cross-development/megavision_hu_ba3bde137ec11149.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development/megavision.png&#34;
        alt=&#34;MEGAVision project share logo&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;MEGAVision logo.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Mark your calendars! On Saturday July 1st at 7pm UTC (that&amp;rsquo;s 12 noon Pacific Time), Gurce is hosting the first ever &lt;em&gt;MEGAVision&lt;/em&gt;, an online project share event hosted over &lt;a href=&#34;https://zoom.us&#34;&gt;Zoom&lt;/a&gt;. All topics are welcome, from hardware to software, completed projects or works in progress, or even just personal experiments that you don&amp;rsquo;t intend to upload to &lt;a href=&#34;http://files.mega65.org&#34;&gt;Filehost&lt;/a&gt;. And if you can&amp;rsquo;t make the date, you&amp;rsquo;re invited to pre-record a presentation to be shown at the event.&lt;/p&gt;
&lt;p&gt;Contact Gurce &lt;a href=&#34;http://mega65.org/chat&#34;&gt;on Discord&lt;/a&gt; if you&amp;rsquo;d like to present something, and keep an eye out on Discord for further instructions. The meeting link will be made available just before the event.&lt;/p&gt;
&lt;h2 id=&#34;pacommex-northwest-seattle-washington-usa-june-24-25&#34;&gt;PaCommEx Northwest, Seattle, Washington, USA, June 24-25&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/pacommex_banner.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development/pacommex_banner.png 700w, https://dansanderson.com/mega65/cross-development/pacommex_banner_hu_b451a5e7b382dfed.png 600w, https://dansanderson.com/mega65/cross-development/pacommex_banner_hu_d21f68af2bc71554.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development/pacommex_banner.png&#34;
        alt=&#34;Pacific Commodore Expo Northwest 2023 banner&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Pacific Commodore Expo Northwest 2023.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If you&amp;rsquo;ll be near the Pacific Northwest of the United States the weekend of June 24th through 25th, mark your calendars again! &lt;a href=&#34;https://portcommodore.com/dokuwiki/doku.php?id=pacommex:start&#34;&gt;Pacific Commodore Expo Northwest 2023&lt;/a&gt; is an annual gathering of Commodore enthusiasts in Seattle, Washington, hosted by Robert Bernardo, the Fresno Commodore User Group, and the Seattle Commodore Computer Club. This year&amp;rsquo;s venue is the Old Rainier Brewery Intraspace. Attendance is free, no tickets required!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll be at PaCommEx all weekend giving talks and demos of the MEGA65. Challenge me with your toughest questions! If I don&amp;rsquo;t know the answer, I&amp;rsquo;ll make something up!&lt;/p&gt;
&lt;h2 id=&#34;four-player-joystick-adapter&#34;&gt;Four-player joystick adapter&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/fourplayer.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development/fourplayer.jpeg 2685w, https://dansanderson.com/mega65/cross-development/fourplayer_hu_24bdd4bdb3927407.jpeg 600w, https://dansanderson.com/mega65/cross-development/fourplayer_hu_c272d05b0b996279.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development/fourplayer.jpeg&#34;
        alt=&#34;The four-player joystick adapter for the MEGA65, produced by jim_64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The four-player joystick adapter for the MEGA65, produced by jim_64.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Like other Commodores, the MEGA65 includes two peripheral ports for joysticks and other controllers. That&amp;rsquo;s fine if you only have one friend, but what if you have more than one friend?&lt;/p&gt;
&lt;p&gt;Paul Gardner-Stephens designed &lt;a href=&#34;https://c65gs.blogspot.com/2018/12/super-simple-protovision-compatible.html&#34;&gt;a joystick port expansion interface&lt;/a&gt; that connects to the expansion (cartridge) port of a MEGA65. Gurce &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/7012353/Super+simple+Protovision-compatible+Joystick+Expander+for+MEGA65&#34;&gt;reproduced these results&lt;/a&gt;, and if you&amp;rsquo;re electronics savvy you can make your own.&lt;/p&gt;
&lt;p&gt;Thanks to Jim of BIT Zeal (&lt;code&gt;jim_64&lt;/code&gt; on the Discord), you can now &lt;a href=&#34;https://www.bit-zeal.com/product/4PlayerMEGA65/6&#34;&gt;buy a pre-assembled four-player joystick interface&lt;/a&gt; for the MEGA65. Jim has also put together &amp;ldquo;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=4b46aca8-ec3b-4483-ae64-df1dfec3ee66&#34;&gt;Four Fun&lt;/a&gt;,&amp;rdquo; a disk of four-player games that work with the adapter. Jim even includes a disk label for &amp;ldquo;Four Fun&amp;rdquo; when you buy the interface.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/fourfun.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development/fourfun.png 692w, https://dansanderson.com/mega65/cross-development/fourfun_hu_b0ffaba0c8a118d9.png 600w, https://dansanderson.com/mega65/cross-development/fourfun_hu_654e8ef50579794c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development/fourfun.png&#34;
        alt=&#34;Four Fun, a disk of four-player games for the MEGA65, compiled by jim_64&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Four Fun, a disk of four-player games for the MEGA65, compiled by jim_64.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 four-player interface is inspired by a similar Commodore 64 peripheral that connected to the User port. Protovision makes &lt;a href=&#34;https://www.protovision.games/hardw/4_player.php?language=en&#34;&gt;a modern version&lt;/a&gt; of this peripheral, but it doesn&amp;rsquo;t work with the MEGA65 because the MEGA65 does not (yet) have a User port. However, both adapters use &lt;a href=&#34;https://www.protovision.games/hardw/build4player.php?language=en#codeit&#34;&gt;the same software interface&lt;/a&gt;, so they should be compatible with the same four-player games.&lt;/p&gt;
&lt;p&gt;See also Jim&amp;rsquo;s &lt;a href=&#34;https://files.mega65.org/html/main.php?pr=b908ebb9-1145-4761-bd99-031f802d2a2f&#34;&gt;Filehost page for the adapter&lt;/a&gt; for links to all of these resources.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;the-cross-development-workflow&#34;&gt;The cross-development workflow&lt;/h2&gt;
&lt;p&gt;Cross development tools allow you to use a modern computer to develop software for the MEGA65. Typically, you write your code as one or more text files using a modern programmer&amp;rsquo;s text editor such as &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;Visual Studio Code&lt;/a&gt;. You use a tool called a &lt;em&gt;cross compiler&lt;/em&gt; to convert your text files into a program that your MEGA65 can run. In cross development terminology, the MEGA65 is the &lt;em&gt;target&lt;/em&gt; platform, and the computer you use to develop the software is the &lt;em&gt;host&lt;/em&gt; platform.&lt;/p&gt;
&lt;p&gt;Typically, the output of a cross compiler targeting Commodore computers is a PRG file. You can put the PRG file on a D81 disk image using a program such as &lt;a href=&#34;https://droid64.sourceforge.net&#34;&gt;droiD64&lt;/a&gt;, which we looked at in &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/&#34;&gt;a previous issue of the Digest&lt;/a&gt;. Copy the D81 disk image to your MEGA65, then use the &lt;code&gt;DLOAD&lt;/code&gt; and &lt;code&gt;RUN&lt;/code&gt; commands at the &lt;code&gt;READY.&lt;/code&gt; prompt to run the program.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s possible for a large program to consist of multiple files on one or more disk images. These are typically built with cross development tools to manage all of the code and data, and to create the disk images in an automated workflow. This is an advanced technique and requires specialized code to read from the disks. For this Digest, we&amp;rsquo;ll focus on single-file programs.&lt;/p&gt;
&lt;h2 id=&#34;running-your-program&#34;&gt;Running your program&lt;/h2&gt;
&lt;p&gt;Having a quick and easy way to run code immediately after it is written is essential to the task of programming. This is easy enough if you&amp;rsquo;re running the software on the same computer where you wrote it: when you want to try your BASIC program, you simply type &lt;code&gt;RUN&lt;/code&gt;. For cross development, that last step of getting the PRG to your MEGA65 can be a challenge. Moving the SD card back and forth between your PC and the MEGA65 for each bug fix would drive you crazy. Thankfully, there are other options.&lt;/p&gt;
&lt;h3 id=&#34;running-a-prg-with-xemu&#34;&gt;Running a PRG with Xemu&lt;/h3&gt;
&lt;p&gt;The most common way people cross develop for the MEGA65 is with the &lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;Xemu emulator&lt;/a&gt;, which runs on your PC. Xemu is like having a MEGA65 on your computer, so you don&amp;rsquo;t have to transfer your program to another computer to test it. You&amp;rsquo;ll need a copy of &lt;a href=&#34;https://files.mega65.org?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;the latest ROM file&lt;/a&gt;, and you&amp;rsquo;ll follow &lt;a href=&#34;https://github.com/lgblgblgb/xemu/wiki/MEGA65-quickstart&#34;&gt;the Xemu MEGA65 Quick Start Guide&lt;/a&gt; to set it up.&lt;/p&gt;
&lt;p&gt;An easy way to run a MEGA65 PRG file is to drag it into the running Xemu window, then click &amp;ldquo;Run/inject as PRG&amp;rdquo; in the dialog window that opens. A faster and nerdier way to run a PRG in Xemu is to start Xemu from the command line, using the &lt;code&gt;-prg&lt;/code&gt; command line flag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/Applications/Xemu/bin/xmega65 -prg hello.prg&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I like to automate everything as much as possible, so I make this command part of a build script or shell command sequence so I can build and run my program in a single step. You can also put this along with your build command (such as &lt;code&gt;petcat&lt;/code&gt;) in a &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;Visual Studio Code&lt;/a&gt; run configuration.&lt;/p&gt;
&lt;h3 id=&#34;running-a-prg-on-mega65-hardware&#34;&gt;Running a PRG on MEGA65 hardware&lt;/h3&gt;
&lt;p&gt;I also like to test my programs on an actual MEGA65 as much as possible. I use a device called a &amp;ldquo;JTAG adapter&amp;rdquo; that connects to the MEGA65 mainboard on one end and to my PC via a USB cable on the other. With this connected, I can use a PC app like M65Connect or the &lt;code&gt;m65&lt;/code&gt; command line tool to beam a PRG file directly to the MEGA65. Search for &amp;ldquo;M65Connect&amp;rdquo; or &amp;ldquo;MEGA65 Tools&amp;rdquo; on &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt; and download these tools for your PC&amp;rsquo;s operating system. If you want to go this route, see &lt;a href=&#34;https://dansanderson.com/mega65/welcome/using-jtag.html&#34;&gt;detailed instructions in my MEGA65 Welcome Guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We won&amp;rsquo;t need the JTAG/UART method for much longer. The MEGA65 team has nearly completed a new feature that allows you to transfer files and run programs over the MEGA65&amp;rsquo;s ethernet jack connected to your local network. This hotly anticipated feature will enable much faster file transfers than a USB serial connection, and won&amp;rsquo;t require any additional hardware other than a common ethernet cable. Expect ethernet file transfer support later this year.&lt;/p&gt;
&lt;h2 id=&#34;cross-developing-basic-programs&#34;&gt;Cross developing BASIC programs&lt;/h2&gt;
&lt;p&gt;In &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/&#34;&gt;a previous issue of the Digest&lt;/a&gt;, we introduced two tools for doing cross development of BASIC programs for the MEGA65. One of these is &lt;code&gt;petcat&lt;/code&gt;, a command-line tool that takes a text file of BASIC code and produces a PRG file.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the example we used in the previous issue, a BASIC program that calculates the Celsius value for a temperature in Fahrenheit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 print &amp;#34;enter a temperature in degrees fahrenheit:&amp;#34;
110 input f
120 c=(f-32)*5/9
130 print
140 print f;&amp;#34; degrees fahrenheit is &amp;#34;;c;&amp;#34; degrees celsius.&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To convert this to a MEGA65 PRG file using petcat, use this shell command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;petcat -w65 -o tempconv.prg -- tempconv.bas&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The command-line tool &lt;code&gt;petcat&lt;/code&gt; is included with the &lt;a href=&#34;https://vice-emu.sourceforge.io/&#34;&gt;VICE suite of Commodore emulators&lt;/a&gt;. In late February, the VICE project accepted an update that completes its support for BASIC 65. This update has not yet been included in an official release of VICE. For the convenience of the MEGA65 community, I built &lt;a href=&#34;https://files.mega65.org?id=9561505c-a36d-4d3e-b158-d52a718e818e&#34;&gt;the latest version of petcat&lt;/a&gt; for each major platform, so you can just download it and use it. Enjoy!&lt;/p&gt;
&lt;p&gt;Also remember that there&amp;rsquo;s &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/27492353/Using+petcat+for+cross-developing+BASIC+programs&#34;&gt;a MEGA65 wiki page on petcat&lt;/a&gt; that describes how to use it and its text-based syntax.&lt;/p&gt;
&lt;h2 id=&#34;cbm-prg-studio-410-update&#34;&gt;CBM PRG Studio 4.1.0 update&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/cross-development/cbmprgstudio.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/cross-development/cbmprgstudio.png 2286w, https://dansanderson.com/mega65/cross-development/cbmprgstudio_hu_3cc749757564cebe.png 600w, https://dansanderson.com/mega65/cross-development/cbmprgstudio_hu_b181f48fa0317dc5.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/cross-development/cbmprgstudio.png&#34;
        alt=&#34;CBM PRG Studio 4.1, with the character editor&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
CBM PRG Studio 4.1, with the character editor
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://www.ajordison.co.uk/download.html&#34;&gt;CBM PRG Studio&lt;/a&gt; is a suite of tools for writing programs for Commodore computers with a visual interface for Windows. As we mentioned in a previous Digest, CBM PRG Studio added support for the MEGA65 with its version 4 release. Arthur Jordison continues to add MEGA65 features, and has just released version 4.1.&lt;/p&gt;
&lt;p&gt;This new version includes a tool for composing music that can output &lt;code&gt;PLAY&lt;/code&gt; commands, as well as a way to export &lt;code&gt;CHARDEF&lt;/code&gt; statements from the character glyph editor. Support for BASIC 65 has been improved, and the assembly language workflow uses &lt;a href=&#34;http://theweb.dk/KickAssembler/Main.html#frontpage&#34;&gt;Kick Assembler&lt;/a&gt; for MEGA65 projects.&lt;/p&gt;
&lt;p&gt;CBM PRG Studio is an all-in-one cross development suite for Commodore computers, and it&amp;rsquo;s exciting to see it get more and more useful for MEGA65 programming. If you run Windows on your PC, give the new version a try.&lt;/p&gt;
&lt;h2 id=&#34;whats-in-a-prg&#34;&gt;What&amp;rsquo;s in a PRG?&lt;/h2&gt;
&lt;p&gt;When you save a BASIC program to disk on the MEGA65 using the &lt;code&gt;DSAVE&lt;/code&gt; command, it creates a file of type PRG (short for &amp;ldquo;program&amp;rdquo;). This file can be loaded back into memory from disk using the &lt;code&gt;DLOAD&lt;/code&gt; command. With cross development, you use a tool on a modern computer to produce a PRG file that can be loaded into the memory of a MEGA65.&lt;/p&gt;
&lt;p&gt;Consider this simple BASIC program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 PRINT &amp;#34;MEGA65 RULES&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the bytes of a PRG file for that program, in hexadecimal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;01 20 16 20 0a 00 99 20
22 4d 45 47 41 36 35 20
52 55 4c 45 53 22 00 00
00&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The PRG file format is very simple: it contains raw data to be written to the MEGA65&amp;rsquo;s memory, along with the starting address. The address comes first, in Little Endian format (smallest digits first). In the case of a BASIC 65 program, the BASIC program data starts at address $2001, so the first two bytes of a BASIC 65 PRG file are $01 and $20. All remaining bytes are program data stored at that location.&lt;/p&gt;
&lt;p&gt;BASIC 65 interprets the data bytes like so:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Loaded address&lt;/th&gt;
          &lt;th&gt;PRG bytes&lt;/th&gt;
          &lt;th&gt;BASIC&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;2001&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;16&lt;/code&gt; &lt;code&gt;20&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Address of next line: $2016&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;2003&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;0A&lt;/code&gt; &lt;code&gt;00&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Line number: &lt;code&gt;10&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;2005&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;99&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Keyword token: &lt;code&gt;PRINT&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;2006&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;20&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Space&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;2007&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;22&lt;/code&gt; &lt;code&gt;4d&lt;/code&gt; &lt;code&gt;45&lt;/code&gt; &lt;code&gt;47&lt;/code&gt; &lt;code&gt;41&lt;/code&gt; &lt;code&gt;36&lt;/code&gt; &lt;code&gt;35&lt;/code&gt; &lt;code&gt;20&lt;/code&gt; &lt;code&gt;52&lt;/code&gt; &lt;code&gt;55&lt;/code&gt; &lt;code&gt;4c&lt;/code&gt; &lt;code&gt;45&lt;/code&gt; &lt;code&gt;53&lt;/code&gt; &lt;code&gt;22&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;&amp;quot;MEGA65 RULES&amp;quot;&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;2015&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;00&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;End of line&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;2016&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;00&lt;/code&gt; &lt;code&gt;00&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;End of program&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The &lt;code&gt;DLOAD&lt;/code&gt; command makes no effort to validate that the data is a BASIC program or that it starts at a particular address. It just reads the starting address, then loads the data into memory at that address. This means that a PRG file can contain anything intended to be stored in memory. This could be machine code, or data such as graphics and music. You can write a BASIC program that contains &lt;code&gt;DLOAD&lt;/code&gt; commands to populate regions of memory from multiple PRG files. Notice that each region must begin in the first 64 kilobytes of memory (with an address between $0000 and $FFFF), because there are only 16 bits (two bytes) for the address in a PRG file.&lt;/p&gt;
&lt;p&gt;A common technique for cross development of machine code programs is to produce a PRG file that starts with a short BASIC program followed by the machine code. The BASIC program uses the &lt;code&gt;SYS&lt;/code&gt; command to invoke the machine code program at the expected memory location. This allows the user to load everything into memory with a single &lt;code&gt;DLOAD&lt;/code&gt; command, then start the program with the &lt;code&gt;RUN&lt;/code&gt; command.&lt;/p&gt;
&lt;h2 id=&#34;cross-developing-assembly-language&#34;&gt;Cross developing assembly language&lt;/h2&gt;
&lt;p&gt;Cross development is my favorite way to &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-game-of-life-in-assembly/&#34;&gt;write assembly language programs for the MEGA65&lt;/a&gt;. Assembly language programs can get very long—literally one line of text per instruction—and it can be a big advantage to use modern text editing and source management tools to develop the code. A &lt;em&gt;cross assembler&lt;/em&gt; can take 45GS02 assembly language code and produce a machine language PRG file. You can create reusable libraries of routines in files shared across multiple projects, and even write &lt;em&gt;macros&lt;/em&gt; that can generate code in useful patterns.&lt;/p&gt;
&lt;p&gt;My cross-assembler of choice for MEGA65 coding is the &lt;a href=&#34;https://sourceforge.net/projects/acme-crossass/&#34;&gt;Acme&lt;/a&gt; assembler by Marco Baye. I like it because it is fast, featureful, and written in portable C that can be built for any modern platform. It has a traditional assembly language syntax that is easy to learn. Best of all, Acme has native support for the MEGA65 and 45GS02 instructions and mnemonics (such as &amp;ldquo;LDQ&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Here is a short Acme assembler source file that generates a BASIC launcher and a two-line machine code program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;!cpu m65
!to &amp;#34;hello.prg&amp;#34;, cbm

* = $2001

!8 $12,$20,$0a,$00,$fe,$02,$20,$30,$3a,$9e,$20
!pet &amp;#34;$2014&amp;#34;
!8 $00,$00,$00

    inc $d020
    rts&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see that this listing includes more than just the assembly language instructions for the program. It also includes instructions that tell the assembler how to produce the PRG file that we desire. The lines beginning with an exclamation point (&lt;code&gt;!&lt;/code&gt;) tell Acme to perform certain actions, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!cpu&lt;/code&gt; : Run in MEGA65 mode, including support for 45GS02 instructions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!to&lt;/code&gt; : Generate a file named &lt;code&gt;&amp;quot;hello.prg&amp;quot;&lt;/code&gt; in Commodore PRG format.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!8&lt;/code&gt; and &lt;code&gt;!pet&lt;/code&gt; : Add some raw bytes to the PRG file that represent this short BASIC program: &lt;code&gt;10 BANK 0:SYS $2014&lt;/code&gt; This program invokes the machine language code that follows the BASIC program in memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The 45GS02 CPU is exclusive to the MEGA65. It is based on the &lt;a href=&#34;https://en.wikipedia.org/wiki/CSG_65CE02&#34;&gt;65CE02 CPU&lt;/a&gt;, a successor to the &lt;a href=&#34;https://en.wikipedia.org/wiki/WDC_65C02&#34;&gt;65C02 CPU&lt;/a&gt; which itself is a descendant of the 6502/6510 CPU we know from earlier Commodores. This means you can use a cross assembler for the 6502 CPU to write MEGA65 software, though you won&amp;rsquo;t be able to access all of its capabilities. A cross assembler needs to support 65CE02 instructions to access some features, such as the Z and B registers.&lt;/p&gt;
&lt;p&gt;The 45GS02&amp;rsquo;s extensions to the 65CE02 all take the form of combinations of 65CE02 instructions. For example, even though the 45GS02&amp;rsquo;s &amp;ldquo;LDQ&amp;rdquo; is not an instruction of the 65CE02, you can invoke the &amp;ldquo;LDQ&amp;rdquo; instruction in a 65CE02 cross assembler with the magic incantation &lt;code&gt;NEG NEG LDA ...&lt;/code&gt;. See appendices G and H in &lt;a href=&#34;https://mega65.org/docs&#34;&gt;the Compendium&lt;/a&gt; for a complete description of how this works. It&amp;rsquo;s pretty neat. The Acme assembler knows about 45GS02 instructions like &amp;ldquo;LDQ&amp;rdquo; and will generate the appropriate incantations automatically.&lt;/p&gt;
&lt;p&gt;Many MEGA65 developers enjoy &lt;a href=&#34;http://theweb.dk/KickAssembler/Main.html#frontpage&#34;&gt;Kick Assembler&lt;/a&gt;. The main release only supports 6502 and 65C02 instructions and not 65CE02 instructions, though &lt;a href=&#34;https://gitlab.com/jespergravgaard/kickassembler65ce02&#34;&gt;this fork by Jesper Balman Gravgaard&lt;/a&gt; adds support all the way up to the 45GS02. Kick has a rich feature set for writing and generating structured assembly language code, and is well loved by serious Commodore developers. &lt;a href=&#34;https://github.com/smnjameson/S65&#34;&gt;Shallan&amp;rsquo;s MEGA65 macro toolkit&lt;/a&gt; is written for Kick, which is a strong endorsement. Kick Assembler is written in Java and requires a Java runtime. And don&amp;rsquo;t miss &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=paulhocker.kick-assembler-vscode-ext&#34;&gt;Kick Assembler 8-Bit Retro Studio&lt;/a&gt;, a powerful extension for Visual Studio Code.&lt;/p&gt;
&lt;p&gt;Other fine 6502 cross assemblers include &lt;a href=&#34;https://dasm-assembler.github.io&#34;&gt;dasm&lt;/a&gt;, &lt;a href=&#34;https://michaelcmartin.github.io/Ophis/&#34;&gt;Ophis&lt;/a&gt;, and &lt;a href=&#34;https://cc65.github.io&#34;&gt;ca65&lt;/a&gt;. Note that each assembler has its own syntax, so be sure to read their manuals to figure out how to do things like the BASIC start-up routine. The Acme listing above will only work with Acme.&lt;/p&gt;
&lt;h2 id=&#34;xcbasic&#34;&gt;XC=BASIC&lt;/h2&gt;
&lt;p&gt;Want the simplicity of BASIC with the power and speed of machine code? &lt;a href=&#34;https://xc-basic.net&#34;&gt;XC=BASIC&lt;/a&gt; by Csaba Fekete is a cross-compiled BASIC-like language for Commodore computers. Csaba has just released &lt;a href=&#34;https://github.com/neilsf/xc-basic3/releases/tag/v3.2.0-beta&#34;&gt;XC=BASIC version 3.2.0-beta&lt;/a&gt; with support for the MEGA65.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s that temperature conversion program written for XC=BASIC:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dim f as float
dim c as float
dim fstr as string * 20

print &amp;#34;enter a temperature in degrees fahrenheit:&amp;#34;
input fstr

f=val(fstr)
c=(f-32)*5/9
print &amp;#34;&amp;#34;
print f;&amp;#34; degrees fahrenheit is &amp;#34;;c;&amp;#34; degrees celsius.&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This example only highlights a couple of features of the language, but they&amp;rsquo;re worth noticing. For starters, there are no line numbers. XC=BASIC uses named labels and subroutines to indicate how control flows through the program. This program does not make use of labels or subroutines, so it just executes instructions top to bottom.&lt;/p&gt;
&lt;p&gt;XC=BASIC variables must be declared before they are used, and the declaration must say what &lt;em&gt;type&lt;/em&gt; of value will be stored in the variable. This differs from BASIC 65 (and other Commodore BASICs) that use a symbol like the dollar sign (&lt;code&gt;$&lt;/code&gt;) at the end of the name to indicate the value type. In this example, the variables &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;c&lt;/code&gt; are declared as floating point decimal values. These can contain numbers like 75.4 or -273.15.&lt;/p&gt;
&lt;p&gt;The variable &lt;code&gt;fstr&lt;/code&gt; is declared as a string, with a maximum length of 20. Unlike Commodore BASIC, strings must have a pre-declared maximum length, so that the memory can be allocated in advance by the compiler. Deciding on a maximum length requires extra effort during programming, but it helps the XC=BASIC compiler produce a faster and more memory-efficient program. This program uses the &lt;code&gt;input&lt;/code&gt; statement to accept user input into the reserved string memory, then uses the &lt;code&gt;val()&lt;/code&gt; function to convert the string to a floating point for use in the calculation. Also notice that the variable name can be a comfortable length, and is not limited to two letters as in Commodore BASIC.&lt;/p&gt;
&lt;p&gt;XC=BASIC is a powerful language with many useful features for structuring and organizing large programs. The XC=BASIC compiler produces a machine code program, so the program runs much faster than BASIC 65, especially with the MEGA65&amp;rsquo;s 40 MHz processor speed. You can even &lt;a href=&#34;https://xc-basic.net/doku.php?id=v3:asm&#34;&gt;mix BASIC and assembly language code&lt;/a&gt; in the same XC=BASIC program.&lt;/p&gt;
&lt;p&gt;The XC=BASIC compiler relies on the &lt;a href=&#34;https://dasm-assembler.github.io&#34;&gt;dasm&lt;/a&gt; assembler mentioned earlier to produce the final PRG. As you get deeper into cross development, you&amp;rsquo;ll notice that a complete workflow often involves multiple tools, sometimes in a &lt;em&gt;tool chain&lt;/em&gt; where the output of one tool is used as the input of another, until the final tool produces a PRG or D81 disk image. In this case, the XC=BASIC compiler generates assembly language code intended for dasm, and dasm produces the PRG. (XC=BASIC invokes the assembler automatically.)&lt;/p&gt;
&lt;p&gt;I was able to get XC=BASIC running on my Mac with the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://dasm-assembler.github.io&#34;&gt;Download dasm&lt;/a&gt;. Expand the archive to get the &lt;code&gt;dasm&lt;/code&gt; command line tool.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/neilsf/xc-basic3/releases/tag/v3.2.0-beta&#34;&gt;Download XC=BASIC 3.2.0-beta&lt;/a&gt;, using the &amp;ldquo;Source code&amp;rdquo; link (either zip or tar.gz). This archive contains pre-built command line tools in the &lt;code&gt;bin/&lt;/code&gt; subdirectory, so you do not need to build this from source code.&lt;/li&gt;
&lt;li&gt;On a Mac, you need to tell macOS that it&amp;rsquo;s okay to run these tools even though they lack Apple developer signatures. Use these commands: &lt;code&gt;xattr -d com.apple.quarantine dasm; xattr -d com.apple.quarantine xc-basic3-3.2.0-beta/bin/macOS/xcbasic3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;dasm&lt;/code&gt; command must be on the command path for your shell. For example, if the &lt;code&gt;dasm&lt;/code&gt; tool is located at &lt;code&gt;/Users/yourname/Downloads/dasm&lt;/code&gt;, this command adds the folder to the command path: &lt;code&gt;export PATH=$PATH:/Users/yourname/Downloads&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To compile a program for the MEGA65, invoke the &lt;code&gt;xcbasic3&lt;/code&gt; command with the &lt;code&gt;--target=mega65&lt;/code&gt; option.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xcbasic3 --target=mega65 tempconv.bas tempconv.prg&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;I&amp;rsquo;m as nostalgic for the days of writing programs directly on my Commodore as anyone else, and I still do it sometimes. I use cross development for larger projects for several reasons. On a modern machine, I can type faster, I can save and backup multiple versions of my code more easily, and I can use more powerful tools and languages to write programs. Eventually we&amp;rsquo;ll have more on-device programming tools like &lt;a href=&#34;https://files.mega65.org?id=3b101d41-5128-4a21-879c-0cf7988edfec&#34;&gt;Mega Assembler&lt;/a&gt; so I can do more without leaving the comfort of the MEGA65. Both methods have their place.&lt;/p&gt;
&lt;p&gt;In next month&amp;rsquo;s Digest, we&amp;rsquo;ll continue exploring cross development tools, with a look at programming your MEGA65 using the C language, as well as a language that&amp;rsquo;s newer than any of our vintage computers, called Rust.&lt;/p&gt;
&lt;p&gt;Until then!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/cross-development/M65Digest_2023June.mp3" length="29688602" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1484</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/cross-development/tempconv.png"/>
      
    </item>
    
    <item>
      <title>Bitmap Bonanza!</title>
      <link>https://dansanderson.com/mega65/bitmap-bonanza/</link>
      <pubDate>Sun, 14 May 2023 18:22:17 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/bitmap-bonanza/</guid>
      <description>&lt;p&gt;Bitmap Bonanza! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for May 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Bitmap Bonanza! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for May 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/M65Digest_2023May.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/M65Digest_2023May.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Bitmap Bonanza!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/beaker.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/beaker.png 637w, https://dansanderson.com/mega65/bitmap-bonanza/beaker_hu_3c8eba580c08f16.png 600w, https://dansanderson.com/mega65/bitmap-bonanza/beaker_hu_941da8c9e3389ce5.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/beaker.png&#34;
        alt=&#34;A photo of Beaker of the Muppet Show, as displayed on the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Beaker of the Muppet Show, as displayed on the MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65&amp;rsquo;s VIC-IV video chip has multiple graphics modes. Each mode and feature pulls ideas from some point in vintage computing history: terminal-style text output, character graphics, hardware sprites, palette banks, full-screen scrolling, and even Amiga-style blitter objects and graphics-optimized DMA operations. Several VIC-IV modes are fully backwards compatible with the VIC-II of the Commodore 64 and 128, and the VIC-III of the Commodore 65.&lt;/p&gt;
&lt;p&gt;In today&amp;rsquo;s Digest, we&amp;rsquo;ll be looking at the VIC-III bitplane graphics mode. While this mode doesn&amp;rsquo;t show off all of the MEGA65&amp;rsquo;s capabilities, it&amp;rsquo;s one of the more fun modes to use with BASIC 65 thanks to its library of 31 drawing commands and functions. In Featured Files, we&amp;rsquo;ll see a new game that takes advantage of BASIC 65&amp;rsquo;s graphics system to draw vector art. We&amp;rsquo;ll also try using a built-in feature to display full-screen high color photographs and illustrations.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;This month&amp;rsquo;s Features Files are all brand new, hot off the presses!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/hungry-dinosaurs.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/hungry-dinosaurs.jpg 654w, https://dansanderson.com/mega65/bitmap-bonanza/hungry-dinosaurs_hu_4063d3da0146add0.jpg 600w, https://dansanderson.com/mega65/bitmap-bonanza/hungry-dinosaurs_hu_dd29780ada9baa1a.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/hungry-dinosaurs.jpg&#34;
        alt=&#34;Onion Cake and the Hungry Dinosaurs, by Gurce&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Onion Cake and the Hungry Dinosaurs, by Gurce.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=e15d97b6-af4d-47a0-969a-3a6691034bfd&#34;&gt;Onion Cake and the Hungry Dinosaurs&lt;/a&gt;, by Gurce. This short comedy adventure game combines a text command interface with gorgeous full-screen vector art by Gurce&amp;rsquo;s sister Ayca and original music. You get to watch the BASIC code fill in the image as it loads each scene, and the code cleverly uses the MEGA65&amp;rsquo;s memory and DMA features to cache the render so they display instantly on subsequent visits.&lt;/p&gt;
&lt;p&gt;Gurce wrote a MEGA65 vector art editing tool, called &lt;a href=&#34;https://github.com/gurcei/vart/&#34;&gt;VART&lt;/a&gt;, to develop the image format used by the game. Both the game and the editor are written in the &lt;a href=&#34;https://files.mega65.org?id=8b189d0b-ea1e-45a7-a4de-87bcb0b11696&#34;&gt;Eleven&lt;/a&gt; programming environment.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Onion Cake and the Hungry Dinosaurs&lt;/em&gt; is inspired by another MEGA65 game, &lt;a href=&#34;https://www.youtube.com/watch?v=TvFXC_quuDo&#34;&gt;Escape from Onion Cake&lt;/a&gt; by MrZaadii, from his &lt;a href=&#34;https://www.forum64.de/index.php?thread/69618-mehr-sw-f%C3%BCr-den-commodore-65-bzw-mega65/&amp;amp;postID=1407896#post1407896&#34;&gt;Mega65 Games Pack&lt;/a&gt; from 2018. MrZaadii&amp;rsquo;s game also uses bitplane graphics with pixel art, pre-dating some of the newer graphics features that were added by the MEGA65 team.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t miss &lt;a href=&#34;https://youtu.be/GGjqSzDBq7g&#34;&gt;Gurce&amp;rsquo;s behind-the-scenes presentation&lt;/a&gt; of the making of Onion Cake.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/oldminehoist.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/oldminehoist.png 705w, https://dansanderson.com/mega65/bitmap-bonanza/oldminehoist_hu_1fce5b6d4d927de7.png 600w, https://dansanderson.com/mega65/bitmap-bonanza/oldminehoist_hu_b4c3e2c033c1053c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/oldminehoist.png&#34;
        alt=&#34;Old Mine Hoist, by GierS&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Old Mine Hoist, by GierS.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=8b52bfbd-86cd-4261-a186-947f30f2da7f&#34;&gt;Old Mine Hoist&lt;/a&gt; by GeirS. This addictive one button game has you lowering a box of supplies down a perilous mine shaft. Struts on the mineshaft walls and barrels of dynamite risk damaging your payload. How far can you get?&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/rescue-inc.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/rescue-inc.png 669w, https://dansanderson.com/mega65/bitmap-bonanza/rescue-inc_hu_f2993f0e6608d5d3.png 600w, https://dansanderson.com/mega65/bitmap-bonanza/rescue-inc_hu_453de206cc6c0cc7.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/rescue-inc.png&#34;
        alt=&#34;Rescue Inc., by SirLazarus&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Rescue Inc., by SirLazarus.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=e7903add-4a8b-4a67-b33d-cd9423cf0dd8&#34;&gt;Rescue Inc.&lt;/a&gt; by SirLazarus. An original solitaire strategy game written in BASIC 65. Launch probes to locate missing battleships in the dark ocean waters. Try to find all the ships with as few probes as possible.&lt;/p&gt;
&lt;h2 id=&#34;c64-for-mega65-v5-alpha-releases&#34;&gt;C64 for MEGA65 V5 alpha releases&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_c64games.jpeg&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_c64games.jpeg 700w, https://dansanderson.com/mega65/bitmap-bonanza/mega65_c64games_hu_a64fbb0689bfa15e.jpeg 600w, https://dansanderson.com/mega65/bitmap-bonanza/mega65_c64games_hu_d368fcd81c0d180c.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_c64games.jpeg&#34;
        alt=&#34;Commodore 64 games running on the C64-for-MEGA65 core: Sam&amp;amp;#39;s Journey (left), Rogue 64 (top right), Choplifter (bottom right)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Commodore 64 games running on the C64-for-MEGA65 core: Sam&amp;rsquo;s Journey (left), Rogue 64 (top right), Choplifter (bottom right)&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In last November&amp;rsquo;s Digest we mentioned the &lt;a href=&#34;https://github.com/MJoergen/C64MEGA65/blob/master/README.md&#34;&gt;Commodore 64 core for the MEGA65&lt;/a&gt; by MJoergen and sy2002, the best way to run Commodore 64 software on MEGA65 hardware. The core completely reconfigures the FPGA for a precise recreation of the Commodore 64 chipset, capable of running software with a very high degree of accuracy and compatibility. The latest stable release is version 4, with support for D64 disk images on the SD card, joystick port peripherals, built-in RAM expansion, and multiple display modes for modern displays.&lt;/p&gt;
&lt;p&gt;The C64 for MEGA65 project is ramping up for a major upgrade with release 5. sy2002 has been posting alpha releases to the Discord, and you&amp;rsquo;re invited to help test! As of &lt;a href=&#34;https://discord.com/channels/719326990221574164/794775503818588200/1105803288877731870&#34;&gt;V5 alpha 22&lt;/a&gt;, the core supports:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Running virtual cartridges as CRT files from the SD card&lt;/li&gt;
&lt;li&gt;Running Commodore 64 PRG files directly from the SD card&lt;/li&gt;
&lt;li&gt;Connecting IEC devices to the MEGA65&amp;rsquo;s IEC port, including external disk drives and printers&lt;/li&gt;
&lt;li&gt;Connecting C64 hardware cartridges to the MEGA65&amp;rsquo;s expansion port, with support for EasyFlash 1 cartridges&lt;/li&gt;
&lt;li&gt;Installing a licensed JiffyDOS ROM for use with IEC disk drives&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As this is an alpha testing release, it comes with a few caveats and has &lt;a href=&#34;https://github.com/MJoergen/C64MEGA65/issues&#34;&gt;known issues&lt;/a&gt;. Be sure to read through the list before installing an alpha release.&lt;/p&gt;
&lt;p&gt;For simpler C64 hardware cartridges, you can turn off the MEGA65, connect the cartridge, hold the &lt;kbd&gt;No Scroll&lt;/kbd&gt; key while turning it on, then select the C64 core from the core selection menu. Remember that if you allow it to boot with the MEGA65 core, it&amp;rsquo;ll just try to run the cartridge software in its C64 mode, which is not the same as the C64 core and is less likely to be successful. lydon is working on improving the MEGA65 core such that the boot-up process can be configured to automatically select different cores for different types of hardware cartridges.&lt;/p&gt;
&lt;p&gt;For EasyFlash and some fancier cartridges, the core selection menu won&amp;rsquo;t work at all with the cartridge connected. To get this to work, you have to do something we would have considered unthinkable in the days of static-sensitive PLA chips: start with the cartridge &lt;em&gt;not&lt;/em&gt; connected, boot with &lt;kbd&gt;No Scroll&lt;/kbd&gt;, select the C64 core, &lt;em&gt;then&lt;/em&gt; connect the cartridge and press the reset button on the side of the machine.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://skoe.de/easyflash/efintro/&#34;&gt;EasyFlash 1 or 1CR&lt;/a&gt; works with the latest alpha release. &lt;a href=&#34;https://skoe.de/easyflash/ef3intro/&#34;&gt;EasyFlash 3&lt;/a&gt; does not yet work. You can &lt;a href=&#34;https://www.sellmyretro.com/offer/details/easyflash-1cr-cartridge--_-assembled-61882&#34;&gt;buy an EasyFlash 1CR&lt;/a&gt; from Daniel Mantione (dmantione in the MEGA65 Discord). Be sure to also order a Protoparts enclosure from Daniel (or from &lt;a href=&#34;https://www.protoparts.at/product-category/gehaeuse/&#34;&gt;Protoparts&lt;/a&gt; directly) to ensure the best fit in the MEGA65 cartridge port.&lt;/p&gt;
&lt;p&gt;When using the IEC port with the C64 core to connect disk drives, keep in mind that the C64 core always uses device number 8 for the virtual drive for D64 disk images. Set your external drive to any other device number for use with the C64 core. You can use this set-up to copy D64 disk images to physical floppy disks and vice versa.&lt;/p&gt;
&lt;p&gt;Whether you&amp;rsquo;re installing the C64 core&amp;rsquo;s latest stable &lt;a href=&#34;https://files.mega65.org?id=896a012f-59e4-456c-b91f-7e989b958241&#34;&gt;release V4&lt;/a&gt; or trying out the V5 alpha release, the installation process is the same:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download the C64-for-MEGA65 release that you want to install, and unpack the archive.&lt;/li&gt;
&lt;li&gt;Copy the &lt;code&gt;.cor&lt;/code&gt; file to the root of your MEGA65 SD card.&lt;/li&gt;
&lt;li&gt;Make a folder in the root of the SD card named &lt;code&gt;c64&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Copy the file named &lt;code&gt;c64mega65&lt;/code&gt; to the &lt;code&gt;c64&lt;/code&gt; folder. Also take this opportunity to copy any D64, CRT, and C64 PRG files you want to try to the &lt;code&gt;c64&lt;/code&gt; folder as well.&lt;/li&gt;
&lt;li&gt;Reinstall the SD card in your MEGA65.&lt;/li&gt;
&lt;li&gt;With the MEGA65 turned off, hold the &lt;kbd&gt;No Scroll&lt;/kbd&gt; key, then turn it on. This opens the core selection menu.&lt;/li&gt;
&lt;li&gt;Select a core slot to overwrite with the core, then hold &lt;kbd&gt;Ctrl&lt;/kbd&gt; and press the number for that slot. Follow the prompts to install the &lt;code&gt;C64M65~1.cor&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you&amp;rsquo;re juggling multiple versions of the C64 core, be sure to use the &lt;code&gt;c64mega65&lt;/code&gt; file that comes with that version. This file saves your menu preferences, and the file format has changed between V4 and V5.&lt;/p&gt;
&lt;p&gt;Visit the &lt;code&gt;#c64-core&lt;/code&gt; channel in the MEGA65 Discord for alpha release downloads, release notes, and troubleshooting issues.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;saying-hello-to-basic-65-bitmap-graphics&#34;&gt;Saying hello to BASIC 65 bitmap graphics&lt;/h2&gt;
&lt;p&gt;Gurce&amp;rsquo;s &lt;em&gt;Onion Cake and the Hungry Dinosaurs&lt;/em&gt; and MrZaadii&amp;rsquo;s original &lt;em&gt;Escape from Onion Cake&lt;/em&gt; both use the bitmap graphics system built in to BASIC 65. This subsystem allows for rendering high resolution pixel perfect images using BASIC commands. Bitmap graphics are implemented as a separate graphics mode from the text mode you see when writing programs, so you can only see either the text screen or a graphics screen on the display at one time. There are 31 commands and functions you can use to manipulate screens and draw figures in your BASIC programs.&lt;/p&gt;
&lt;p&gt;Because the graphics screen hides the text screen, this isn&amp;rsquo;t easy to experiment with from the &lt;code&gt;READY.&lt;/code&gt; prompt. Instead, you can use a short program like this one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SCREEN 320,200,2
20 PEN 1
30 LINE 25,25,295,175
40 GETKEY A$
50 SCREEN CLOSE&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_line.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_line.jpeg 480w, https://dansanderson.com/mega65/bitmap-bonanza/mega65_line_hu_13ea3702a2c8446e.jpeg 600w, https://dansanderson.com/mega65/bitmap-bonanza/mega65_line_hu_abbb5949f710b235.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_line.jpeg&#34;
        alt=&#34;The result of a program that draws a white diagonal line on a black graphics screen&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The result of the program: a white line on a black background.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In this example, line 10 opens a new screen that is 320 pixels wide and 200 pixels tall, with a palette of four colors (a &amp;ldquo;bit depth&amp;rdquo; of 2). Line 20 sets the color used by subsequent drawing commands (the &amp;ldquo;pen&amp;rdquo; color) to palette entry 1 (the second of four colors), in this case using the default palette&amp;rsquo;s color of white. (See the &lt;code&gt;PALETTE&lt;/code&gt; command for a way to change the palette colors.) Line 30 draws a line using the pen color from screen coordinate (25,25) to (295,175), a diagonal stripe.&lt;/p&gt;
&lt;p&gt;Line 40 pauses until the user presses a key, and line 50 closes the screen and returns to text mode. This is a useful recipe when you&amp;rsquo;re experimenting with graphics commands. If your program exits without closing the screen, the MEGA65 will stay in graphics mode and you won&amp;rsquo;t be able to see the &lt;code&gt;READY.&lt;/code&gt; prompt. This can happen if there is an error in your code that stops the program before it closes the screen. If your program appears to get stuck showing a graphics screen, hold &lt;kbd&gt;Run/Stop&lt;/kbd&gt; and press &lt;kbd&gt;Restore&lt;/kbd&gt; to reset the display to text mode and a fresh &lt;code&gt;READY.&lt;/code&gt; prompt.&lt;/p&gt;
&lt;p&gt;The graphics system supports widths of either 320 or 640 pixels, heights of either 200 or 400 pixels, and color bit depths from 1 (two colors on screen at a time) to 8 (256 colors). You can have up to 16 colors (bit depth 4) with a 640x400 screen, and up to 256 colors (bit depth 8) for the other possible resolutions. It is possible to allocate multiple screens and switch between them, though this limits the possible sizes and bit depths due to available memory. Each color palette entry can be any of 4,096 possible colors, with 16 possible values of each of the red, green, and blue components.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s worth noting that the MEGA65 video hardware is capable of 24-bit color. The BASIC 65 graphics system only uses a subset of the MEGA65&amp;rsquo;s graphics capability.&lt;/p&gt;
&lt;p&gt;As tempting as it is to tour all 31 commands of the graphics system in this Digest, for now I will leave it to you to discover them in your User&amp;rsquo;s Guide. Look for &lt;code&gt;SCREEN&lt;/code&gt;, &lt;code&gt;BOX&lt;/code&gt;, &lt;code&gt;CHAR&lt;/code&gt;, &lt;code&gt;CIRCLE&lt;/code&gt;, &lt;code&gt;DOT&lt;/code&gt;, &lt;code&gt;ELLIPSE&lt;/code&gt;, &lt;code&gt;LINE&lt;/code&gt;, &lt;code&gt;PAINT&lt;/code&gt;, &lt;code&gt;PALETTE&lt;/code&gt;, &lt;code&gt;PEN&lt;/code&gt;, &lt;code&gt;POLYGON&lt;/code&gt;, and &lt;code&gt;SCNCLR&lt;/code&gt;, for starters.&lt;/p&gt;
&lt;h2 id=&#34;saving-the-graphics-screen-to-disk&#34;&gt;Saving the graphics screen to disk&lt;/h2&gt;
&lt;p&gt;BASIC 65 includes a command for saving the currently active bitmap graphics screen to disk. The &lt;code&gt;SAVEIFF&lt;/code&gt; command takes a filename, and optional drive and unit numbers. It only works with a graphics screen active, so it&amp;rsquo;s best to make it part of the program.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;35 SAVEIFF &amp;#34;LINE-EXAMPLE&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The image is saved to disk in the &lt;a href=&#34;https://en.wikipedia.org/wiki/ILBM&#34;&gt;IFF-ILBM&lt;/a&gt; file format, a bitmap graphics file format common to Amiga computers. The file appears on the disk as a PRG file, but it&amp;rsquo;s actually just the IFF-ILBM data, without the two-byte address header of an actual PRG file.&lt;/p&gt;
&lt;p&gt;IFF-ILBM files use a simple form of data compression to reduce file sizes. The iamge produced by the program above of a single line on a blank screen at 320x200x2 occupies six blocks on disk to store 1,502 bytes. More complex images, or higher resolutions or color bit depths, will require more space.&lt;/p&gt;
&lt;h2 id=&#34;loading-the-graphics-screen-from-disk&#34;&gt;Loading the graphics screen from disk&lt;/h2&gt;
&lt;p&gt;A file saved with &lt;code&gt;SAVEIFF&lt;/code&gt; can be loaded back to the active graphics screen with another command: &lt;code&gt;LOADIFF&lt;/code&gt;. As before, the graphics screen must be active.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 SCREEN 320,200,2
20 LOADIFF &amp;#34;LINE-EXAMPLE&amp;#34;
30 GETKEY A$
40 SCREEN CLOSE&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Due to how multi-color bitmap graphics are stored, the color bit depth of the active screen must match the file. Loading an image that was saved from a smaller resolution than the active screen (for example, loading a 320x200 image onto a 640x400 screen) will simply load the image into the upper-left corner of the screen, leaving the rest of the screen intact.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SAVEIFF&lt;/code&gt; includes the current palette settings with the image data in the IFF-ILBM file. You do not need to restore the palette separately in your program. Notice that the current palette will be overwritten by &lt;code&gt;LOADIFF&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;exploring-the-iff-ilbm-file-format&#34;&gt;Exploring the IFF-ILBM file format&lt;/h2&gt;
&lt;p&gt;The IFF-ILBM file format is a standard format developed by Electronic Arts in cooperation with Commodore in 1985. &lt;a href=&#34;https://en.wikipedia.org/wiki/Interchange_File_Format&#34;&gt;IFF&lt;/a&gt;, or &amp;ldquo;Interchange File Format,&amp;rdquo; is what is known as a container (or &amp;ldquo;envelope&amp;rdquo;) format, capable of representing multiple chunks of data of many kinds. Amiga fans mostly know IFF files as still images of the inner format &lt;a href=&#34;https://en.wikipedia.org/wiki/ILBM&#34;&gt;ILBM&lt;/a&gt;, or &amp;ldquo;Interleaved Bitmap.&amp;rdquo; The &lt;a href=&#34;https://en.wikipedia.org/wiki/ANIM&#34;&gt;IFF-ANIM&lt;/a&gt; format was a variant for storing multiple ILBM images as an animation in a single IFF envelope, also popular on the Amiga. As a kid, I only knew that IFF files contained either stills or animations, and you could make them with &lt;a href=&#34;https://en.wikipedia.org/wiki/Deluxe_Paint&#34;&gt;Deluxe Paint&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is the beginning of the IFF-ILBM file created by the BASIC program above, as hexadecimal values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;00000000  46 4f 52 4d 00 00 05 de  49 4c 42 4d 42 4d 48 44  |FORM....ILBMBMHD|
00000010  00 00 00 14 01 40 00 c8  00 00 00 00 02 00 01 00  |.....@..........|
00000020  00 00 00 00 01 40 00 c8  43 4d 41 50 00 00 00 0c  |.....@..CMAP....|
00000030  00 00 00 ff ff ff ff 00  00 00 ff ff 42 4f 44 59  |............BODY|
00000040  00 00 05 9a d9 00 d9 00  d9 00 d9 00 d9 00 d9 00  |................|&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An IFF file contains one or more &lt;em&gt;chunks&lt;/em&gt;. Each chunk has a four-byte type ID and a four-byte size, followed by that many bytes of data. The &lt;code&gt;SAVEIFF&lt;/code&gt; command creates a single outer chunk of type &lt;code&gt;FORM&lt;/code&gt;, so it begins with those uppercase letters encoded as ASCII (&lt;code&gt;46 4f 52 4d&lt;/code&gt;). The size is a signed 32-bit integer in Big Endian format (largest digits first), so &lt;code&gt;00 00 05 de&lt;/code&gt; represents a size of hexadecimal &lt;code&gt;$05de&lt;/code&gt;, or 1,502 bytes. It&amp;rsquo;s not obvious from looking at it, but this is actually &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues/53&#34;&gt;a bug in SAVEIFF&lt;/a&gt;: the actual data size is 1,494 bytes, but it is erroneously including the eight bytes of the &lt;code&gt;FORM&lt;/code&gt; header in this size. Because of this bug, some tools will complain about an &amp;ldquo;unexpected end of input file&amp;rdquo; when reading this.&lt;/p&gt;
&lt;p&gt;According to the &lt;a href=&#34;https://en.wikipedia.org/wiki/Interchange_File_Format&#34;&gt;IFF specification&lt;/a&gt;, a &lt;code&gt;FORM&lt;/code&gt; chunk is a record with an inner type and one or more inner chunks. In this case, the inner type is &lt;code&gt;ILBM&lt;/code&gt;, so those are the next four bytes (&lt;code&gt;49 4c 42 4d&lt;/code&gt;). The inner chunks have types &lt;code&gt;BMHD&lt;/code&gt;, &lt;code&gt;CMAP&lt;/code&gt;, and &lt;code&gt;BODY&lt;/code&gt;, which are part of the ILBM specification for still images. You can see these identifiers in the hex dump, along with their four-byte sizes and data.&lt;/p&gt;
&lt;p&gt;Reading along with &lt;a href=&#34;https://en.wikipedia.org/wiki/ILBM&#34;&gt;the ILBM specification&lt;/a&gt; for the &lt;code&gt;$00000014&lt;/code&gt; (20) bytes of the &lt;code&gt;BMHD&lt;/code&gt; chunk, we can see the following properties of the image:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;01 40 00 c8&lt;/code&gt;: The image is &lt;code&gt;$0140&lt;/code&gt; = 320 pixels wide, and &lt;code&gt;$00c8&lt;/code&gt; = 200 pixels tall.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;00 00 00 00&lt;/code&gt;: The image starts at coordinate (0,0) on the screen.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;02&lt;/code&gt;: It has a color bit depth of 2.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;00&lt;/code&gt;: It does not use the mask feature of the ILBM format.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;01&lt;/code&gt;: The data uses &lt;a href=&#34;https://en.wikipedia.org/wiki/Run-length_encoding&#34;&gt;Run-Length Encoding&lt;/a&gt; for compression (type 1).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;00&lt;/code&gt;: This is unused.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;00 00&lt;/code&gt;: This is related to the mask feature, not used here.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;00 00&lt;/code&gt;: This file describes its aspect ratio as 0:0 (&lt;code&gt;$00&lt;/code&gt; &lt;code&gt;$00&lt;/code&gt;). This is &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues/54&#34;&gt;not actually a valid aspect ratio&lt;/a&gt;. Some tools will complain, and just assume a ratio of 1:1.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;01 40 00 c8&lt;/code&gt;: The intended screen size for the image is 320x200, the same size as the image.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;CMAP&lt;/code&gt; inner chunk describes the color palette. With a bit depth of 2, there are four possible colors in the image, each described as one byte for each of the red, green, and blue components, &lt;code&gt;$0000000c&lt;/code&gt; (12) bytes in total.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Color 0: red = &lt;code&gt;$00&lt;/code&gt;, green = &lt;code&gt;$00&lt;/code&gt;, blue = &lt;code&gt;$00&lt;/code&gt;, aka black&lt;/li&gt;
&lt;li&gt;Color 1: red = &lt;code&gt;$ff&lt;/code&gt;, green = &lt;code&gt;$ff&lt;/code&gt;, blue = &lt;code&gt;$ff&lt;/code&gt;, aka white&lt;/li&gt;
&lt;li&gt;Color 2: red = &lt;code&gt;$ff&lt;/code&gt;, green = &lt;code&gt;$00&lt;/code&gt;, blue = &lt;code&gt;$00&lt;/code&gt;, aka bright red&lt;/li&gt;
&lt;li&gt;Color 3: red = &lt;code&gt;$00&lt;/code&gt;, green = &lt;code&gt;$ff&lt;/code&gt;, blue = &lt;code&gt;$ff&lt;/code&gt;, aka cyan&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The IFF-ILBM format supports RGB component values from 0 to 255 (8 bits). The MEGA65 only supports component values from 0 to 15 (4 bits). &lt;code&gt;LOADIFF&lt;/code&gt; uses the most significant four bits of each RGB component value when setting the palette, effectively rounding each number down to the nearest 16.&lt;/p&gt;
&lt;p&gt;The spec describes the RLE algorithm that is used for the &lt;code&gt;BODY&lt;/code&gt; chunk. For example, &lt;code&gt;$d9 $00&lt;/code&gt; represents forty zeroes, and you can see this repeated in the excerpt above. The decoding algorithm will build out 320x200 bits for each of the four bitplanes. There&amp;rsquo;s a bit in each bitplane for each pixel of the image. Take the pixel&amp;rsquo;s bit from each of the bitplanes, starting with the lowest bit in the first bitplane, to get the pixel&amp;rsquo;s color number.&lt;/p&gt;
&lt;p&gt;ILBM is useful for Amiga and MEGA65 BASIC bitmap graphics because these systems represent the screen as bitplanes in memory, so it&amp;rsquo;s easy to save the image just by compressing memory, and load it again just by decompressing it. The MEGA65 has other graphics modes that don&amp;rsquo;t use bitplanes.&lt;/p&gt;
&lt;h2 id=&#34;do-you-believe-in-imagemagick&#34;&gt;Do you believe in ImageMagick?&lt;/h2&gt;
&lt;p&gt;Most modern graphics software does not support the vintage IFF-ILBM image format. To use an image saved with &lt;code&gt;SAVEIFF&lt;/code&gt;, it must be converted to a modern format, such as PNG.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://imagemagick.org/index.php&#34;&gt;ImageMagick&lt;/a&gt; is the ultimate software suite for converting and manipulating image data in a wide variety of formats. It&amp;rsquo;s free, packed with features, and runs on most operating systems. You typically use ImageMagick from the command line, which makes it great for automation scripts. See &lt;a href=&#34;https://imagemagick.org/script/download.php&#34;&gt;the ImageMagick Downloads page&lt;/a&gt; for installation instructions for your operating system. On a Mac using &lt;a href=&#34;https://brew.sh/&#34;&gt;Homebrew&lt;/a&gt;, install this with: &lt;code&gt;brew install imagemagick&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In most cases, you can convert images between formats using the &lt;code&gt;magick convert&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;magick convert line-example.iff line-example.png&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(If you have an older version of ImageMagick installed, this command is just &lt;code&gt;convert ...&lt;/code&gt;, without the &lt;code&gt;magick&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a slight problem when trying this with files made with the MEGA65&amp;rsquo;s &lt;code&gt;SAVEIFF&lt;/code&gt; command. Those &lt;code&gt;SAVEIFF&lt;/code&gt; bugs about the &lt;code&gt;FORM&lt;/code&gt; chunk length and 0:0 aspect ratio cause the inner workings of ImageMagick to believe that the conversion failed. When I run the &lt;code&gt;magick convert&lt;/code&gt; command on a &lt;code&gt;SAVEIFF&lt;/code&gt; file, I get these messages, and no PNG file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ilbmtoppm: warning - illegal aspect ratio 0:0, using 1:1
ilbmtoppm: input is a 2-plane ILBM
ilbmtoppm: Unexpected end of input file
convert: delegate failed `&amp;#39;ilbmtoppm&amp;#39; &amp;#39;%i&amp;#39; &amp;gt; &amp;#39;%o&amp;#39;&amp;#39; @ error/delegate.c/InvokeDelegate/1924.
convert: no decode delegate for this image format `ILBM&amp;#39; @ error/constitute.c/ReadImage/781.
convert: no images defined `line-example-test.png&amp;#39; @ error/convert.c/ConvertImageCommand/3342.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As shown in these messages, ImageMagick delegates IFF-ILBM conversion to a tool called &lt;code&gt;ilbmtoppm&lt;/code&gt;, part of another software suite called &lt;a href=&#34;https://netpbm.sourceforge.net/&#34;&gt;NetPBM&lt;/a&gt; that&amp;rsquo;s included with ImageMagick. When I run the &lt;code&gt;ilbmtoppm&lt;/code&gt; tool directly, it complains about the issues with the file, but successfully converts the IFF-ILBM file to the PPM format:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ilbmtoppm line-example.iff &amp;gt;line-example.ppm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The PPM format is supported by some modern software, and can be further converted to other formats by ImageMagick.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;magick convert line-example.ppm line-example.png&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The PPM file can also be converted back to IFF-ILBM format with the &lt;code&gt;SAVEIFF&lt;/code&gt; errors corrected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;magick convert line-example.ppm line-example-fixed.iff&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/line-example.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/line-example.png 320w, https://dansanderson.com/mega65/bitmap-bonanza/line-example_hu_49cb3f3a0b9b0b10.png 600w, https://dansanderson.com/mega65/bitmap-bonanza/line-example_hu_b92f4f56ed09987c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/line-example.png&#34;
        alt=&#34;The example program&amp;amp;#39;s output converted to PNG format, a white line on a black background&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The example program&#39;s output converted to PNG format
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;converting-images-to-be-displayed-on-a-mega65&#34;&gt;Converting images to be displayed on a MEGA65&lt;/h2&gt;
&lt;p&gt;You can reverse the conversion process to prepare any image, including high color photographs, as an IFF-ILBM file, so it can be displayed on your MEGA65 with the &lt;code&gt;LOADIFF&lt;/code&gt; command in a BASIC program.&lt;/p&gt;
&lt;p&gt;For this to work, it needs to not only be in IFF-ILBM format, but also be the right size and color depth for a BASIC 65 screen. You can try adjusting your image to 320x200 and 256 colors (8-bit color) using image editing software, or you can let ImageMagick do it for you.&lt;/p&gt;
&lt;p&gt;The latest version of ImageMagick as of this writing (7.1.1) does not appear to recognize the &lt;code&gt;.iff&lt;/code&gt; filename extension as IFF-ILBM. Instead, you can conver to IFF-ILBM in two steps, using NetPBM again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;magick convert photo.jpg -resize 320x200\! +dither -colors 256 -depth 8 photo.ppm
ppmtoilbm -maxplanes 8 photo.ppm &amp;gt;photo.iff&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;magick convert&lt;/code&gt; command converts &lt;code&gt;photo.jpg&lt;/code&gt; to &lt;code&gt;photo.ppm&lt;/code&gt; with the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-resize 320x200\!&lt;/code&gt; : Resize the image to 320 pixels wide and 200 pixels high. The &lt;code&gt;\!&lt;/code&gt; tells ImageMagick to stretch the original image to fit this aspect ratio, which may or may not be what you want. ImageMagick has other options for resizing that can crop or extend the image instead. See &lt;a href=&#34;https://legacy.imagemagick.org/Usage/resize/&#34;&gt;any ImageMagick tutorial&lt;/a&gt; for examples.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;+dither&lt;/code&gt; : Disable dithering. Dithering is a technique for representing color and value gradations in digital images, using noise patterns and just a few colors. In this case, we&amp;rsquo;re converting a JPEG, which may introduce compression artifacts. Disabling dithering prevents these artifacts from being preserved as dithered patterns in the final image. If you&amp;rsquo;re converting from another format, you may be able to leave dithering enabled.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-colors 256 -depth 8&lt;/code&gt; : Set the color depth to 8, with the maximum of 256 colors.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;ppmtoilbm&lt;/code&gt; command needs the &lt;code&gt;-maxplanes 8&lt;/code&gt; argument when the image uses a bit depth larger than 5. For some reason, the command defaults to generating a 24-bit image in these cases unless this argument is specified.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_huxley256.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_huxley256.jpeg 480w, https://dansanderson.com/mega65/bitmap-bonanza/mega65_huxley256_hu_783306ea3b7a8ac7.jpeg 600w, https://dansanderson.com/mega65/bitmap-bonanza/mega65_huxley256_hu_42d701893c7d43a.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_huxley256.jpeg&#34;
        alt=&#34;Photo of Huxley the cat, as a 256-color 320x200 IFF-ILBM file, displayed on a MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Photo of Huxley the cat, as a 256-color 320x200 IFF-ILBM file.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I had some issues with ImageMagick and NetPBM that were resolved by updating to the latest versions. If you already have these tools installed from a while ago, consider updating. With Homebrew: &lt;code&gt;brew update &amp;amp;&amp;amp; brew upgrade&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;four-byte-burger&#34;&gt;Four-Byte Burger&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_four_byte_burger_side.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_four_byte_burger_side.jpeg 480w, https://dansanderson.com/mega65/bitmap-bonanza/mega65_four_byte_burger_side_hu_325d1174d7465c9f.jpeg 600w, https://dansanderson.com/mega65/bitmap-bonanza/mega65_four_byte_burger_side_hu_d28f0dd9c4ee5f3f.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/mega65_four_byte_burger_side.jpeg&#34;
        alt=&#34;Four-Byte Burger (1985) by Jack Haeger, recreated by Stuart Brown aka Ahoy, displayed on a MEGA65 and rotated 90 degrees&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Four-Byte Burger (1985) by Jack Haeger, recreated by Stuart Brown aka Ahoy, displayed on a MEGA65 and rotated 90 degrees
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In 1985, &lt;a href=&#34;https://amiga.lychesis.net/artist/JackHaeger.html&#34;&gt;Jack Haeger&lt;/a&gt; created an illustration of a hamburger falling through the air, with a 3-1/2&amp;quot; floppy disk for the hamburger patty. Jack painted the image using an early version of the Graphicraft art software for the Commodore Amiga, one of the first works of art created on the machine. At the time, Graphicraft lacked any way to save an image to disk or export it to print, so Jack photographed the screen with a 35mm film camera. Presumably, Jack eventually turned off the machine, and the digital record of the work was lost forever. &lt;a href=&#34;https://amiga.lychesis.net/amiga/LJL/JackHaeger_FourByteBurger.jpg&#34;&gt;The photograph&lt;/a&gt; appeared in the Graphicraft manual and the first issue of Amiga World magazine.&lt;/p&gt;
&lt;p&gt;In 2023, YouTuber Stuart Brown aka Ahoy recreated &amp;ldquo;Four-Byte Burger&amp;rdquo; as digital art. Ahoy described his research and his process in &lt;a href=&#34;https://youtu.be/i4EFkspO5p4&#34;&gt;a 30-minute video&lt;/a&gt;, including the realization that Jack must have drawn the image sideways then rotated the photograph to give it more height, as shown by the CRT scan lines running up and down the photo. Ahoy concluded that Jack used just fewer than 32 colors, and the original image was 320x200 in size.&lt;/p&gt;
&lt;p&gt;Ahoy published &lt;a href=&#34;http://xboxahoy.com/images/four-byte-burger.png&#34;&gt;a PNG file of his recreation&lt;/a&gt;, and by popular demand also produced &lt;a href=&#34;http://xboxahoy.com/images/four-byte-burger.zip&#34;&gt;an IFF-ILBM file of the same image&lt;/a&gt; for potential display on an Amiga. Naturally, I wanted to display it on my MEGA65, so I loaded it onto a D81 disk image and wrote an appropriate &lt;code&gt;LOADIFF&lt;/code&gt; program, with a screen 320x200x5.&lt;/p&gt;
&lt;p&gt;I was a bit surprised that it rendered as mustard and ketchup colored garbage instead of the actual image. So I peeked into the hex dump as we did above. Everything looked as I expected it to, until I got to the compression type field of the &lt;code&gt;BMHD&lt;/code&gt; chunk, which was &lt;code&gt;$00&lt;/code&gt; instead of &lt;code&gt;$01&lt;/code&gt;. According to the ILBM spec, this indicates that the &lt;code&gt;BODY&lt;/code&gt; data uses no compression at all, and not Run-Length Encoding. So I looked at the ROM code for &lt;code&gt;LOADIFF&lt;/code&gt;, and sure enough, &lt;code&gt;LOADIFF&lt;/code&gt; always assumes the &lt;code&gt;BODY&lt;/code&gt; region uses RLE, and ignores the compression type field. (That should be another easy fix in a future version of the ROM.)&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s an easy workaround: use &lt;code&gt;ilbmtoppm&lt;/code&gt; to convert the IFF-ILBM file to PPM, then use &lt;code&gt;ppmtoilbm&lt;/code&gt; to convert it right back.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ilbmtoppm four-byte-burger.iff &amp;gt;four-byte-burger.ppm
ppmtoilbm four-byte-burger.ppm &amp;gt;four-byte-burger-fixed.iff&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With &amp;ldquo;Four-Byte Burger,&amp;rdquo; the resulting file was naturally smaller, and had the compression field set to &lt;code&gt;$01&lt;/code&gt;. It loaded fine on the MEGA65. If you have an IFF image file of a compatible size and color depth and it still isn&amp;rsquo;t loading correctly with &lt;code&gt;LOADIFF&lt;/code&gt;, this is an easy workaround to try.&lt;/p&gt;
&lt;p&gt;One more tip: If you find an IFF-ILBM file and want to know its dimensions and color depth, use the &lt;code&gt;magick identify&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;magick identify four-byte-burger.iff&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;iff-megashow65&#34;&gt;IFF MegaShow65&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/iff-megashow65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/iff-megashow65.png 705w, https://dansanderson.com/mega65/bitmap-bonanza/iff-megashow65_hu_419b0b4b06012f08.png 600w, https://dansanderson.com/mega65/bitmap-bonanza/iff-megashow65_hu_2e3a107066415479.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/iff-megashow65.png&#34;
        alt=&#34;IFF MegaShow 65, by Nobato&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
IFF MegaShow 65, by Nobato.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Want to display a set of IFF-ILBM images as a slideshow? Check out &lt;a href=&#34;https://files.mega65.org?id=54cfb354-c812-4b65-909b-7248523dc955&#34;&gt;IFF MegaShow65&lt;/a&gt; by Nobato. This clever program can browse and display multiple IFF image files on a disk. It uses BASIC 65&amp;rsquo;s graphics system and &lt;code&gt;LOADIFF&lt;/code&gt; command behind the scenes, reading the &lt;code&gt;BMHD&lt;/code&gt; section of the file to determine the resolution and color depth.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The BASIC graphics system originated at Commodore, and retains a vintage feel. Even though it doesn&amp;rsquo;t use the MEGA65&amp;rsquo;s capabilities to their fullest, it&amp;rsquo;s a ton of fun to play with and use from programs, much easier than using bitmap graphics on a Commodore 64.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/bitmap-bonanza/dirty-old-onion-cake.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/bitmap-bonanza/dirty-old-onion-cake.png 1019w, https://dansanderson.com/mega65/bitmap-bonanza/dirty-old-onion-cake_hu_4cf07a52f6c0933b.png 600w, https://dansanderson.com/mega65/bitmap-bonanza/dirty-old-onion-cake_hu_a9a95c860b437641.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/bitmap-bonanza/dirty-old-onion-cake.png&#34;
        alt=&#34;Screenshot of text from Escape from Onion Cake, by MrZaadii.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Dirty old Onion Cake has kidnapped you. You know that it is your own fault since you have not written enough MEGA65 software. Better get started!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/bitmap-bonanza/M65Digest_2023May.mp3" length="34765238" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1738</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/bitmap-bonanza/beaker.png"/>
      
    </item>
    
    <item>
      <title>Bard on Lotto</title>
      <link>https://dansanderson.com/articles/bard-on-lotto/</link>
      <pubDate>Wed, 19 Apr 2023 13:04:14 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/articles/bard-on-lotto/</guid>
      <description>&lt;p&gt;I asked &lt;a href=&#34;https://bard.google.com/&#34;&gt;Google Bard&lt;/a&gt;, &amp;ldquo;What are the odds of winning the Washington State Lotto jackpot?&amp;rdquo; Its reply began with two sentences:&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;I asked &lt;a href=&#34;https://bard.google.com/&#34;&gt;Google Bard&lt;/a&gt;, &amp;ldquo;What are the odds of winning the Washington State Lotto jackpot?&amp;rdquo; Its reply began with two sentences:&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/articles/bard-on-lotto/bard-on-lotto.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/articles/bard-on-lotto/bard-on-lotto.png&#34;
            width=&#34;453&#34;
            height=&#34;308&#34;
            alt=&#34;Google Bard atempting to answer the question, What are the odds of winning the Washington State Lotto?&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Google Bard attempting to answer a question on probability
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;ol&gt;
&lt;li&gt;The odds of winning the Washington State Lotto jackpot are 1 in 6.99 million.&lt;/li&gt;
&lt;li&gt;This means that for every 6.99 million tickets sold, one ticket will win the jackpot.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;#1 is correct and a useful parsing of information from &lt;a href=&#34;https://walottery.com/JackpotGames/Lotto.aspx&#34;&gt;the Lotto website&lt;/a&gt;. #2 is either false or misleading, depending on how you read it.&lt;/p&gt;
&lt;p&gt;The WA Lotto is a &lt;a href=&#34;https://en.wikipedia.org/wiki/Lottery_mathematics&#34;&gt;6-of-49 number picking game&lt;/a&gt;. The game will pick six numbers from 1 to 49 without replacement (no repeats) in any order, and you have to guess in advance which numbers will be picked. If you guess all six numbers, you win the jackpot. The odds of winning the jackpot in a single pick are 1 in 49!/(6! * 43!) = 13,983,816. You get two picks per $1 ticket, so the odds that a ticket will win the jackpot are 1 in 6.99 mil.&lt;/p&gt;
&lt;p&gt;$$\frac{n!}{r!(n-r)!} = \frac{49!}{6! \times 43!} = 13983816$$&lt;/p&gt;
&lt;p&gt;To guarantee a jackpot win for a single lottery, you can buy $7 mil worth of tickets and pick every of the 13,983,816 possible combinations. But that&amp;rsquo;s not what Bard said. Statement #2 suggests that 13.98 mil &lt;em&gt;random&lt;/em&gt; picks (as if 6.99 mil people bought a $1 ticket) would guarantee a jackpot win. This is false.&lt;/p&gt;
&lt;p&gt;What are the chances that given 13.98 mil random picks, at least one of them will win the jackpot? One way to figure this is to calculate the odds of each possible win pattern: pick #1 wins and all the others lose, pick #2 wins and all other lose, pick #1 and pick #2 both win, etc. Then add them up. But there&amp;rsquo;s an easier way.&lt;/p&gt;
&lt;p&gt;Given that either an event happens or it doesn&amp;rsquo;t happen, the odds of the event not happening is 1 minus the odds of it happening, because the total odds of all possibilities must add to 1. It is guaranteed (probability 1) that the odds that the coin will land either heads (1/2) or tails (1/2): $1/2 + 1/2 = 1$. If the odds that one pick gets the jackpot is $P(M) = $ 1 in 13,983,816, the odds that one pick &lt;em&gt;doesn&amp;rsquo;t&lt;/em&gt; get the jackpot is $1 - P(M)$.&lt;/p&gt;
&lt;p&gt;$$1 - P(M) = 1 - \frac{1}{13983816} = \frac{13983815}{13983816}$$&lt;/p&gt;
&lt;p&gt;To determine the odds of at least one of multiple picks winning the lottery, we consider its opposite: what are the odds that &lt;em&gt;nobody&lt;/em&gt; wins the jackpot? If the odds of one pick not matching are $1 - P(M)$, then the odds of &lt;em&gt;all&lt;/em&gt; 13,983,816 random picks not matching are $1 - P(M)$ multiplied by itself 13,983,816 times.&lt;/p&gt;
&lt;p&gt;$$(1 - P(M))^t = (1 - \frac{1}{13983816})^{13983816}$$&lt;/p&gt;
&lt;p&gt;So the odds of at least one pick out of 13.9 million picks matching are 1 minus this number, or about 63%. It&amp;rsquo;s likely, but not &amp;ldquo;guaranteed.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;$$1 - (1 - \frac{1}{13983816})^{13983816} = 0.63212057175$$&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/articles/bard-on-lotto/google-calc.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/articles/bard-on-lotto/google-calc.png 825w, https://dansanderson.com/articles/bard-on-lotto/google-calc_hu_1fe58d49f176b903.png 600w, https://dansanderson.com/articles/bard-on-lotto/google-calc_hu_261fd8674fd0d054.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/articles/bard-on-lotto/google-calc.png&#34;
        alt=&#34;Google Calculator figuring the odds that at least one of 13 million lottery picks wins the jackpot&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Google Calculator gets it right
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s always amusing to me to realize that this accounts for all of the possibilities of which picks are winners, including the possibility that everyone picked exactly the same numbers and they matched, or everyone won but you, etc. Importantly, these are the total odds of somebody out of millions of people winning, not the odds of you winning.&lt;/p&gt;
&lt;p&gt;Chatbots being wrong isn&amp;rsquo;t news. What I think is interesting here is that chatbots seem to be wrong about mathematics more often than with other subjects. &lt;strong&gt;Chatbots don&amp;rsquo;t understand anything.&lt;/strong&gt; They&amp;rsquo;re guessing at how someone might answer a question based on the text of billions of people discussing billions of things. This makes chatbots more likely to repeat common misconceptions when those misconceptions appear more often than their corrections in the training data.&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>Fun with PETSCII!</title>
      <link>https://dansanderson.com/mega65/petscii-codes/</link>
      <pubDate>Wed, 12 Apr 2023 08:33:11 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/petscii-codes/</guid>
      <description>&lt;p&gt;Fun with PETSCII! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for April 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Fun with PETSCII! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for April 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/petscii-codes/M65Digest_2023Apr.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/M65Digest_2023Apr.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Fun with PETSCII!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/digiloi.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/digiloi.png 956w, https://dansanderson.com/mega65/petscii-codes/digiloi_hu_bcca43c46c351368.png 600w, https://dansanderson.com/mega65/petscii-codes/digiloi_hu_3f31b39bae8c85c6.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/digiloi.png&#34;
        alt=&#34;Digiloi, for the C64, by Dr. TerrorZ&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Digiloi, for the C64, by Dr. TerrorZ.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/PETSCII&#34;&gt;PETSCII&lt;/a&gt; is a set of 256 values that can be printed to the screen of a Commodore computer. Most of these codes refer to &lt;em&gt;characters,&lt;/em&gt; such as letters, numbers, punctuation, and Commodore&amp;rsquo;s unique set of graphics glyphs that can be typed from the keyboard. Other codes are &lt;em&gt;control codes&lt;/em&gt; that manipulate the state of the screen and printing system, such as to change the color of subsequently printed text. The PETSCII character set is part of what gives Commodore computers their distinctive style. Drawing pictures by typing PETSCII characters and codes is one of the first things everyone does with a Commodore, and there is a long tradition of crafting murals of PETSCII art for demos, games, and computer bulletin boards.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re reading this, you&amp;rsquo;re probably pretty familiar with the capabilities of PETSCII on a Commodore 64. In this Digest, we&amp;rsquo;ll review the PETSCII character set, and see how the MEGA65 can learn a trick or two from Commodores that predate the 64. We&amp;rsquo;ll also take a look at PETSCII control codes that are newer than the C64, and see how we can make special use of PETSCII strings on the MEGA65.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s more stuff you can download and try on your MEGA65 today!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/solitaire.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/solitaire.png 705w, https://dansanderson.com/mega65/petscii-codes/solitaire_hu_e08f7a97f53c5b5f.png 600w, https://dansanderson.com/mega65/petscii-codes/solitaire_hu_87e599bd7e2e79db.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/solitaire.png&#34;
        alt=&#34;M3wP Solitaire, by M3wP&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;M3wP Solitaire, by M3wP.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=693fa82c-ef25-483d-a221-a303a6e6229f&#34;&gt;M3wP Solitaire&lt;/a&gt; by M3wP. Every computer needs some card game fun, and this Solitaire game has it in spades! Connect a mouse to port 1 and play the classic &lt;a href=&#34;https://en.wikipedia.org/wiki/Klondike_(solitaire)&#34;&gt;Klondike Solitaire&lt;/a&gt; with rich multi-color playing card graphics. You won&amp;rsquo;t be able to resist just one more hand.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t have a vintage &lt;a href=&#34;https://en.wikipedia.org/wiki/Commodore_1351&#34;&gt;Commodore 1351 mouse&lt;/a&gt; or Amiga mouse? Get the &lt;a href=&#34;https://retrohax.net/shop/modulesandparts/mouster/&#34;&gt;mouSTer adapter&lt;/a&gt; and connect a modern USB mouse. Make sure the mouse mode is set correctly in the MEGA65 Configuration menu (hold Alt while turning on the computer, then select 1) to match the mouSTer configuration. If you&amp;rsquo;re one of the lucky ones to receive a &lt;a href=&#34;https://www.kickstarter.com/projects/lukas-remis/tank-mouse-your-new-amiga-mouse&#34;&gt;modern Amiga Tank Mouse&lt;/a&gt; from their Kickstarter campaign, that also works with the MEGA65.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/lemonade.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/lemonade.jpg 1024w, https://dansanderson.com/mega65/petscii-codes/lemonade_hu_66120c9191af4a6f.jpg 600w, https://dansanderson.com/mega65/petscii-codes/lemonade_hu_ec4026e75ac8f78e.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/lemonade.jpg&#34;
        alt=&#34;Lemonade for two, by ubik&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Lemonade for two, by ubik.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=91f156a0-8d65-43ba-afd4-bf233c69676b&#34;&gt;Lemonade for two&lt;/a&gt; by ubik. An innovative two-player version of the microcomputer classic business strategy game. Use your limited funds to buy supplies based on the weather forecast, sell lemonade in your neighborhood, and leverage your profits into expanding your business. Out-match your opponent and win it all!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/galaxy.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/galaxy.png 698w, https://dansanderson.com/mega65/petscii-codes/galaxy_hu_93656486c80ab992.png 600w, https://dansanderson.com/mega65/petscii-codes/galaxy_hu_d6640e8708905bcd.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/galaxy.png&#34;
        alt=&#34;Procedurally Drawn Galaxy, by grim\_fandango&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Procedurally Drawn Galaxy, by grim_fandango.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=b938e9e8-20ea-43e4-bb57-fe8b02aa9289&#34;&gt;Procedurally Drawn Galaxy&lt;/a&gt; by grim_fandango. This high resolution graphics demo renders a gorgeous spiral galaxy. Once you&amp;rsquo;ve admired the image, check out the BASIC program listing to see how it&amp;rsquo;s done.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;the-lost-glyphs-of-the-pet&#34;&gt;The lost glyphs of the PET&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/698px-Pet4016.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/698px-Pet4016.png 698w, https://dansanderson.com/mega65/petscii-codes/698px-Pet4016_hu_200fc154126e54ce.png 600w, https://dansanderson.com/mega65/petscii-codes/698px-Pet4016_hu_68423f3e2ed218db.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/698px-Pet4016.png&#34;
        alt=&#34;The Commodore PET model 4016. Photo by Alex Lozupone, used via a CC BY-SA 3.0 license&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Commodore PET model 4016. Photo by Alex Lozupone, used via a CC BY-SA 3.0 license.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The PETSCII text encoding standard was originally invented for the &lt;a href=&#34;https://en.wikipedia.org/wiki/Commodore_PET&#34;&gt;Commodore PET&lt;/a&gt; computer in 1977. It uses 8-bit code points for 256 possible values, of which 192 represent typeable characters. Some characters are assigned to multiple code points; the actual number of distinct typeable characters is 128. The remaining 64 code points are used for control codes, or otherwise have no effect when printed to the screen.&lt;/p&gt;
&lt;p&gt;While PETSCII was based on the &lt;a href=&#34;https://en.wikipedia.org/wiki/ASCII&#34;&gt;ASCII&lt;/a&gt; code standard in use by most computers by that time, the Commodore PET had its own ideas about how to make the best use of the code space. An unexpanded PET did not have a bitmap graphics mode, so PETSCII extended the character set with graphics symbols that could be used to draw boxes, diagrams, and game images. PETSCII actually describes two character sets: one with mixed case letters and some graphics symbols (the &amp;ldquo;text&amp;rdquo; character set), and another with only uppercase letters and more graphics symbols (the &amp;ldquo;graphics&amp;rdquo; character set). On Commodore machines, the graphics character set is the default. This is why you sometimes see ASCII messages mis-printed on Commodore machines with lowercase letters as uppercase and uppercase letters as graphics symbols. The user can toggle between character sets as needed by pressing the &lt;kbd&gt;Commodore&lt;/kbd&gt; key and the &lt;kbd&gt;Shift&lt;/kbd&gt; key together. (This is &lt;kbd&gt;Mega&lt;/kbd&gt; + &lt;kbd&gt;Shift&lt;/kbd&gt; on the MEGA65.)&lt;/p&gt;
&lt;p&gt;The PETSCII codes for the 128 typeable characters map to &lt;em&gt;screen codes&lt;/em&gt; that describe what actually appears on a location on the screen. There&amp;rsquo;s a second set of screen codes that represent those characters in reverse video mode, for a total of 256 possible screen codes in a character set. With two character sets, the complete definition of a Commodore typeface has 512 possible glyphs, of which only the first 256 or second 256 can be on the screen at one time.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_pet.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_pet.png 532w, https://dansanderson.com/mega65/petscii-codes/petscii_pet_hu_6ad2021d45f8b1cf.png 600w, https://dansanderson.com/mega65/petscii-codes/petscii_pet_hu_c0013509385ed9f6.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_pet.png&#34;
        alt=&#34;PETSCII glyphs on the Commodore PET, in 80 columns&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
PETSCII glyphs on the Commodore PET, in 80 columns.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Fun fact: The PET adds a one-pixel vertical space between each line when the display switches to &amp;ldquo;text&amp;rdquo; mode, to give it more of an ASCII terminal feel. You can see this in the image above, which I produced in an emulator with a program that prints the PETSCII control code to switch to this mode. (It&amp;rsquo;s also possible to use the text character set on a PET without the vertical gaps.)&lt;/p&gt;
&lt;h3 id=&#34;the-c64-typeface&#34;&gt;The C64 typeface&lt;/h3&gt;
&lt;p&gt;The original Commodore PET typeface was designed with the PET&amp;rsquo;s built-in monochrome display in mind. These glyphs were used in 40-column and 80-column PET models. The same glyphs were also used in the VIC-20. To reduce costs, the VIC-20 did not have a built-in display and was designed to be connected to the color television set already in your living room. To make the text legible on blurry TVs, the VIC-20 only supported 22 columns of text and stretched the PET glyphs extra wide.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_vic20.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_vic20.png 591w, https://dansanderson.com/mega65/petscii-codes/petscii_vic20_hu_a6c16a565d3b8ee7.png 600w, https://dansanderson.com/mega65/petscii-codes/petscii_vic20_hu_e8e422722ccb56ea.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_vic20.png&#34;
        alt=&#34;PETSCII glyphs on the Commodore VIC-20, in 22 columns&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
PETSCII glyphs on the Commodore VIC-20, in 22 columns.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Commodore sought to return to a 40-column text display for the Commodore 64, but there was a problem: the PET glyphs were too thin and spindly to be readable on a TV at narrow character widths. So Commodore redesigned the character set with thicker vertical lines. Nearly every occurrence of a single pixel with space on either side was doubled in some form.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/letters_pet_vs_c64.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/letters_pet_vs_c64.png 527w, https://dansanderson.com/mega65/petscii-codes/letters_pet_vs_c64_hu_f3bd3b069460e601.png 600w, https://dansanderson.com/mega65/petscii-codes/letters_pet_vs_c64_hu_85987d860ba99ec9.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/letters_pet_vs_c64.png&#34;
        alt=&#34;The letter A glyph in the PET typeface and the C64 typeface&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The letter A glyph in the PET typeface and the C64 typeface.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The result is the Commodore typeface we know and love, used unchanged all the way up to the MEGA65. It looks pretty great in 80 columns on a modern display.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_mega65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_mega65.png 526w, https://dansanderson.com/mega65/petscii-codes/petscii_mega65_hu_cf84600888f13d3f.png 600w, https://dansanderson.com/mega65/petscii-codes/petscii_mega65_hu_d7e4bc2ffe725d08.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_mega65.png&#34;
        alt=&#34;PETSCII glyphs on the MEGA65, in 80 columns&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
PETSCII glyphs on the MEGA65, in 80 columns.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;the-missing-glyphs&#34;&gt;The missing glyphs&lt;/h3&gt;
&lt;p&gt;The redesign met its goal, but at a cost. Several PET glyphs simply did not survive being made thicker.&lt;/p&gt;
&lt;p&gt;For example, the glyph set includes vertical lines of every width on both the left and right side of the tile. Take a look at your MEGA65 keyboard and you can see a few of these are typeable by holding down &lt;kbd&gt;Mega&lt;/kbd&gt; and pressing keys like &lt;kbd&gt;L&lt;/kbd&gt;, &lt;kbd&gt;N&lt;/kbd&gt;, and &lt;kbd&gt;M&lt;/kbd&gt;. On the PET, &lt;kbd&gt;CBM&lt;/kbd&gt;+&lt;kbd&gt;G&lt;/kbd&gt; and &lt;kbd&gt;CBM&lt;/kbd&gt;+&lt;kbd&gt;M&lt;/kbd&gt; were vertical lines one pixel wide. Starting with the C64, they are now two pixels wide, redundant with &lt;kbd&gt;CBM&lt;/kbd&gt;+&lt;kbd&gt;H&lt;/kbd&gt; and &lt;kbd&gt;CBM&lt;/kbd&gt;+&lt;kbd&gt;N&lt;/kbd&gt;, respectively.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/redundant_lines.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/redundant_lines.png 142w, https://dansanderson.com/mega65/petscii-codes/redundant_lines_hu_f353ff227d3d8ea3.png 600w, https://dansanderson.com/mega65/petscii-codes/redundant_lines_hu_c98cca79773de2ed.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/redundant_lines.png&#34;
        alt=&#34;Redundant vertical line PETSCII glyphs on the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Redundant vertical line PETSCII glyphs on the MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Some PET glyphs have been deleted entirely. A fine-grained 1-pixel checkerboard pattern was replaced with a duplicate of the 2-pixel checkerboard pattern. Dotted and line pattern glyphs just became extra empty spaces.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/dots_and_lines.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/dots_and_lines.jpeg 640w, https://dansanderson.com/mega65/petscii-codes/dots_and_lines_hu_df35ce36d110e38f.jpeg 600w, https://dansanderson.com/mega65/petscii-codes/dots_and_lines_hu_43d64795bdfefe04.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/dots_and_lines.jpeg&#34;
        alt=&#34;PET dots and lines glyphs, on a MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
PET dots and lines glyphs, on a MEGA65 (photographed, with CRT emulation enabled).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Early MEGA65 contributor Markus Neeb (X2themax on the Discord, aka MPBBS) noticed the missing glyphs. At the MEGA eV open house of August 2022, he proposed a radical idea: restore the missing PET glyphs for the MEGA65. All of the restorations only replace glyphs that are redundant with others elsewhere in the typeface, and because they are both redundant and obscure, they likely haven&amp;rsquo;t even been used by MEGA65 software. The restored glyphs are authentic to Commodore history, and are demonstrably useful on modern displays in both 40-column and 80-column modes.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_dupes.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_dupes.png 1043w, https://dansanderson.com/mega65/petscii-codes/petscii_dupes_hu_d0bbe2a2bfdebd22.png 600w, https://dansanderson.com/mega65/petscii-codes/petscii_dupes_hu_4a358109b5099967.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_dupes.png&#34;
        alt=&#34;Duplicates in the C64 PETSCII glyph set (image by Markus)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Duplicates in the C64 PETSCII glyph set (image by Markus).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_fixes.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_fixes.png 1045w, https://dansanderson.com/mega65/petscii-codes/petscii_fixes_hu_1a7d8018416a5317.png 600w, https://dansanderson.com/mega65/petscii-codes/petscii_fixes_hu_7677a22943d21298.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_fixes.png&#34;
        alt=&#34;Markus&amp;amp;#39;s proposed replacements, restoring PET glyphs&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Markus&#39;s proposed replacements, restoring PET glyphs.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_fixed_demo.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_fixed_demo.png 949w, https://dansanderson.com/mega65/petscii-codes/petscii_fixed_demo_hu_e8d45a7e7cb4f6f9.png 600w, https://dansanderson.com/mega65/petscii-codes/petscii_fixed_demo_hu_e74d2db4f257814e.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/petscii_fixed_demo.png&#34;
        alt=&#34;Markus&amp;amp;#39;s demonstration of the restored glyphs, in C64 mode&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Markus&#39;s demonstration of the restored glyphs, in C64 mode.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s intriguing to imagine how re-introducing these glyphs enhances the character of the platform. I know I would have used the fine checker, dotted, and lined pattern tiles all the time if I had them—and a sharp enough display to support them—back in the day.&lt;/p&gt;
&lt;p&gt;The MEGA65 Steering Committee decided against modifying the default ROM with these changes, primarily because it&amp;rsquo;s actually quite easy for any program that wants to use these glyphs to install them. It&amp;rsquo;s even easier on the MEGA65 than on previous Commodore computers. BASIC programs can just use the &lt;code&gt;CHARDEF&lt;/code&gt; command, and machine code programs merely have to write the new glyphs to a memory location.&lt;/p&gt;
&lt;p&gt;The following are &lt;code&gt;CHARDEF&lt;/code&gt; statements that restore the missing PET glyphs. Feel free to use them in your programs, or in your &lt;code&gt;AUTOBOOT.C65&lt;/code&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 chardef $42,$10,$10,$10,$10,$10,$10,$10,$10
11 chardef $43,$00,$00,$00,$ff,$00,$00,$00,$00
12 chardef $60,$aa,$00,$aa,$00,$aa,$00,$aa,$00
13 chardef $65,$80,$80,$80,$80,$80,$80,$80,$80
14 chardef $67,$01,$01,$01,$01,$01,$01,$01,$01
15 chardef $c2,$ef,$ef,$ef,$ef,$ef,$ef,$ef,$ef
16 chardef $c3,$ff,$ff,$ff,$00,$ff,$ff,$ff,$ff
17 chardef $e0,$ff,$00,$ff,$00,$ff,$00,$ff,$00
18 chardef $e5,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f
19 chardef $e7,$fe,$fe,$fe,$fe,$fe,$fe,$fe,$fe
20 chardef $15e,$aa,$55,$aa,$55,$aa,$55,$aa,$55
21 chardef $160,$aa,$00,$aa,$00,$aa,$00,$aa,$00
22 chardef $165,$80,$80,$80,$80,$80,$80,$80,$80
23 chardef $167,$01,$01,$01,$01,$01,$01,$01,$01
24 chardef $1de,$55,$aa,$55,$aa,$55,$aa,$55,$aa
25 chardef $1e0,$ff,$00,$ff,$00,$ff,$00,$ff,$00
26 chardef $1e5,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f
27 chardef $1e7,$fe,$fe,$fe,$fe,$fe,$fe,$fe,$fe&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;petscii-control-codes&#34;&gt;PETSCII control codes&lt;/h2&gt;
&lt;p&gt;The ASCII standard includes codes that do something other than print a character when sent to a terminal or teletype. These codes cause the terminal device to perform some other action, such as to move the cursor (or print head) to the beginning of the next line, or signal the operator by ringing a bell.&lt;/p&gt;
&lt;p&gt;PETSCII also includes non-printing code points that, when printed, perform an effect, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change the color or style of subsequently printed characters&lt;/li&gt;
&lt;li&gt;Move the cursor position (potentially scrolling the terminal-like text display)&lt;/li&gt;
&lt;li&gt;Switch the display between the uppercase and lowercase character sets&lt;/li&gt;
&lt;li&gt;Enable or disable the ability for the user to switch between the uppercase and lowercase character sets&lt;/li&gt;
&lt;li&gt;Clear the screen&lt;/li&gt;
&lt;li&gt;Ring the terminal bell&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Control codes can be typed directly into the screen using a key sequence. This is a great way to experiment with control codes and see their effects immediately. For example, hold &lt;kbd&gt;Ctrl&lt;/kbd&gt; and press &lt;kbd&gt;3&lt;/kbd&gt; to change the printing color to red. &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;2&lt;/kbd&gt; changes it back to white. Printing is very similar to typing in this way: it causes the effect of typing each code to occur, in the order the codes appear in the string.&lt;/p&gt;
&lt;p&gt;Your User&amp;rsquo;s Guide has a good reference of PETSCII character and control codes, and their keyboard equivalents, in Appendix B.&lt;/p&gt;
&lt;h3 id=&#34;including-control-codes-in-strings&#34;&gt;Including control codes in strings&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;CHR$()&lt;/code&gt; function takes a PETSCII code as a number and evaluates to a one-character string for that code. You can concatenate this string with other strings.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT &amp;#34;IT&amp;#39;S &amp;#34;+CHR$(28)+&amp;#34;VERY&amp;#34;+CHR$(5)+&amp;#34; COOL&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;CHR$()&lt;/code&gt; function works for all 256 PETSCII codes, but it&amp;rsquo;s not especially convenient: you have to use a table to look up the control code numbers, and type quite a few characters to spell it all out.&lt;/p&gt;
&lt;p&gt;Thankfully, the Commodore screen editor has an alternate way to type control codes into strings just by typing the key sequences that cause their effect. The screen editor knows that you intend to include the code in the string, and not have it take effect immediately, when it is in &lt;em&gt;quote mode.&lt;/em&gt; The editor enables quote mode when you type the first double-quote (&lt;code&gt;&amp;quot;&lt;/code&gt;) character of a string, and disables it when you type the closing double-quote character.&lt;/p&gt;
&lt;p&gt;You may have seen vintage magazine program listings represent these typeable codes using labels, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT &amp;#34;IT&amp;#39;S {red}VERY{white} COOL&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Try typing this command, entering &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;3&lt;/kbd&gt; for &lt;code&gt;{red}&lt;/code&gt; and &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;2&lt;/kbd&gt; for &lt;code&gt;{white}&lt;/code&gt;. They appear as reversed characters inside the string.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/quoted_codes.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/quoted_codes.png 242w, https://dansanderson.com/mega65/petscii-codes/quoted_codes_hu_5466feb93c70dbbe.png 600w, https://dansanderson.com/mega65/petscii-codes/quoted_codes_hu_f3c01cbd1600e7cd.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/quoted_codes.png&#34;
        alt=&#34;How PETSCII codes appear quoted in strings&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
How PETSCII codes appear quoted in strings.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Quote mode takes some getting used to. It&amp;rsquo;s easy to forget that cursor movement keys get quoted, so if you try to cursor left while typing a string, it quotes the cursor-left PETSCII codes instead. A few codes intentionally do &lt;em&gt;not&lt;/em&gt; get quoted, such as pressing &lt;kbd&gt;Return&lt;/kbd&gt;. If you need such a code in a string, the only way is to use the &lt;code&gt;CHR$()&lt;/code&gt; function (&lt;code&gt;CHR$(13)&lt;/code&gt; for &lt;kbd&gt;Return&lt;/kbd&gt;).&lt;/p&gt;
&lt;p&gt;There is one other way to access quote mode. When you press &lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;INST/DEL&lt;/kbd&gt;, the editor inserts a space at the cursor location and does not move the cursor. It also enters quote mode &lt;em&gt;only for the inserted spaces,&lt;/em&gt; so you can type a control code if you need to. This quote mode effect happens even if the cursor is not located inside double-quotes! That&amp;rsquo;s not particularly useful, but it&amp;rsquo;s a tradeoff for the fact that the screen editor doesn&amp;rsquo;t try to understand what you are typing until you press &lt;kbd&gt;Return&lt;/kbd&gt;.&lt;/p&gt;
&lt;p&gt;If you find that you&amp;rsquo;re in quote mode and you don&amp;rsquo;t want to be, press &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;O&lt;/kbd&gt; (the letter O).&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s useful to know that the screen editor will interpret whatever is on the screen when you press &lt;kbd&gt;Return&lt;/kbd&gt;, including reversed characters inside double-quotes, &lt;em&gt;no matter how those characters were typed.&lt;/em&gt; Technically, you can type a quoted &lt;code&gt;{red}&lt;/code&gt; code while not in quote mode by turning on reverse mode and typing the &lt;kbd&gt;£&lt;/kbd&gt; (pound) symbol, which is what it would look like if you typed &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;3&lt;/kbd&gt; while in quote mode. I&amp;rsquo;ve never done this in regular practice—I typically use the insert method to type quoted codes when modifying an existing line—but it&amp;rsquo;s fun to know that it works.&lt;/p&gt;
&lt;p&gt;Try this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Type: &lt;code&gt;PRINT &amp;quot; HELLO{wht}&amp;quot;&lt;/code&gt;, without pressing &lt;kbd&gt;Return&lt;/kbd&gt;.&lt;/li&gt;
&lt;li&gt;Cursor back to the space before &lt;code&gt;HELLO&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enter &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;9&lt;/kbd&gt; to enter reverse mode, then type &lt;kbd&gt;£&lt;/kbd&gt;.&lt;/li&gt;
&lt;li&gt;Press &lt;kbd&gt;Return&lt;/kbd&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;print-modes-and-colors&#34;&gt;Print modes and colors&lt;/h3&gt;
&lt;p&gt;The Commodore 65 supports text modes for underlining, flashing text, and reverse text. These modes can be combined.&lt;/p&gt;
&lt;p&gt;To enable underlining, press &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;B&lt;/kbd&gt;. To enable flashing text, press &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;O&lt;/kbd&gt;. One way to enable reverse text is &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;R&lt;/kbd&gt;, though as we just saw, this is also available as &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;9&lt;/kbd&gt; aka &amp;ldquo;Rvs on.&amp;rdquo; There are PETSCII codes to disable each of these individually, and if you&amp;rsquo;re just typing them onto the screen you can press &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;O&lt;/kbd&gt; to disable all three modes. Reverse can also be disabled with &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;0&lt;/kbd&gt; (zero) aka &amp;ldquo;Rvs off.&amp;rdquo;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Underline on: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;B&lt;/kbd&gt;, &lt;code&gt;CHR$(2)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Underline off: &lt;code&gt;CHR$(130)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Flashing on: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;O&lt;/kbd&gt;, &lt;code&gt;CHR$(15)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Flashing off: &lt;code&gt;CHR$(143)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Reverse on: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;R&lt;/kbd&gt; or &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;9&lt;/kbd&gt; aka &amp;ldquo;Rvs on&amp;rdquo;, &lt;code&gt;CHR$(18)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Reverse off: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;0&lt;/kbd&gt; aka &amp;ldquo;Rvs off&amp;rdquo;, &lt;code&gt;CHR$(146)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The printing system keeps track of the text color as its own mode, using that color for printing characters. The blinking cursor is drawn in the current text color. C64 fans know the color changing keys quite well: &lt;kbd&gt;Ctrl&lt;/kbd&gt; or &lt;kbd&gt;Mega&lt;/kbd&gt; plus a number key 1 through 8 accesses sixteen colors, as labeled on the number keys themselves. The corresponding PETSCII codes are scattered a bit (white is 5, red is 28, green is 30, etc.), so you&amp;rsquo;ll just want to look those numbers up in the User&amp;rsquo;s Guide if you need them.&lt;/p&gt;
&lt;p&gt;On the MEGA65, you can access a system palette of 32 colors for text printing. All 32 colors can be used on the same screen simultaneously. To access them using PETSCII control codes, there is a print mode for that: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;D&lt;/kbd&gt; causes the 16 color codes to refer to colors 0-15, and &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;A&lt;/kbd&gt; causes them to refer to colors 16-31.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Access colors 0-15: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;D&lt;/kbd&gt;, &lt;code&gt;CHR$(4)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Access colors 16-31: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;A&lt;/kbd&gt;, &lt;code&gt;CHR$(1)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Don&amp;rsquo;t forget that you can change an entry in the 32-color system palette to any of 4,096 colors using the &lt;code&gt;PALETTE COLOR&lt;/code&gt; command. You can also change which color is used for printing with the &lt;code&gt;FOREGROUND&lt;/code&gt; command (or the &lt;code&gt;COLOR&lt;/code&gt; command). See the User&amp;rsquo;s Guide for more information.&lt;/p&gt;
&lt;h3 id=&#34;moving-the-cursor&#34;&gt;Moving the cursor&lt;/h3&gt;
&lt;p&gt;It was very common for Commodore 64 BASIC programs to position text on the screen using PETSCII control codes that move the cursor. To print the message &lt;code&gt;&amp;quot;HELLO WORLD&amp;quot;&lt;/code&gt; in the center of the 40x25 screen, a program might print the &lt;kbd&gt;Home&lt;/kbd&gt; code to move the cursor to the top left corner, followed by 12 cursor-down codes and 14 cursor-left codes, then the message.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Home cursor: &lt;kbd&gt;Home&lt;/kbd&gt;, &lt;code&gt;CHR$(19)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cursor down: &lt;kbd&gt;Cursor down&lt;/kbd&gt;, &lt;code&gt;CHR$(17)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cursor right: &lt;kbd&gt;Cursor right&lt;/kbd&gt;, &lt;code&gt;CHR$(29)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cursor up: &lt;kbd&gt;Cursor up&lt;/kbd&gt;, &lt;code&gt;CHR$(145)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cursor left: &lt;kbd&gt;Cursor left&lt;/kbd&gt;, &lt;code&gt;CHR$(157)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;BASIC 65 has a dedicated command for positioning the cursor: &lt;code&gt;CURSOR col,row&lt;/code&gt; This may be more useful for positioning text on the screen, depending on what you are trying to print.&lt;/p&gt;
&lt;p&gt;The terminal display supports tab column positions, similar to ASCII teletypes (and old typewriters). I won&amp;rsquo;t describe the whole system here. You can experiment with the &lt;kbd&gt;Tab&lt;/kbd&gt; key (9) and &amp;ldquo;tab set/clear&amp;rdquo; (24) code to see what they do.&lt;/p&gt;
&lt;h3 id=&#34;screen-effects&#34;&gt;Screen effects&lt;/h3&gt;
&lt;p&gt;Pretty much every Commodore 64 BASIC program I ever wrote started by clearing the screen. This felt so powerful, the first step in my program taking control of the machine. The reversed heart character of the quoted clear-screen PETSCII code resonates as nostalgically for me as the blue-bordered home screen.&lt;/p&gt;
&lt;p&gt;Press &lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;Clr/Home&lt;/kbd&gt; to clear the screen. Press it in quote mode to insert the PETSCII control code into a string, such that it clears the screen when that part of the string is printed.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clear screen: &lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;Clr/Home&lt;/kbd&gt;, &lt;code&gt;CHR$(147)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As we mentioned last month, the text screen can display either the uppercase character set or the lowercase character set. Each set can have 256 unique glyphs, but only one set can appear on the screen at one time. The default character set keeps uppercase letters and graphics characters in the first set, and lowercase and uppercase letters in the second set.&lt;/p&gt;
&lt;p&gt;You can toggle between the two character sets interactively by pressing the &lt;kbd&gt;Mega&lt;/kbd&gt; and &lt;kbd&gt;Shift&lt;/kbd&gt; keys together. (Try it!) This toggle effect is not a PETSCII code, and in fact supersedes many program functions so you can do this while a program is running. If your program intentionally uses one set or the other, you can print PETSCII codes to select the set, as well as to disable the &lt;kbd&gt;Mega&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt; behavior.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Select uppercase: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;N&lt;/kbd&gt;, &lt;code&gt;CHR$(15)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select lowercase: &lt;code&gt;CHR$(142)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Enable &lt;kbd&gt;Mega&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt;: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;K&lt;/kbd&gt;, &lt;code&gt;CHR$(11)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Disable &lt;kbd&gt;Mega&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt;: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;L&lt;/kbd&gt;, &lt;code&gt;CHR$(12)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Old terminals had a special code that caused a bell to ring, such as to alert an operator at the end of a long job, possibly on a printer in another room. Newer screen terminals support the bell code, mostly using it to indicate an error. The Commodore 65 also has a bell! Press &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;G&lt;/kbd&gt; to hear it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ring the bell: &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;G&lt;/kbd&gt;, &lt;code&gt;CHR$(7)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;patterns-in-control-codes&#34;&gt;Patterns in control codes&lt;/h3&gt;
&lt;p&gt;PETSCII codes 1 through 26 are typeable as &lt;kbd&gt;Ctrl&lt;/kbd&gt; plus a letter of the alphabet &lt;kbd&gt;A&lt;/kbd&gt; through &lt;kbd&gt;Z&lt;/kbd&gt;. &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;S&lt;/kbd&gt; is overridden as an equivalent to &lt;kbd&gt;No Scroll&lt;/kbd&gt;; code 19 can be entered with the &lt;kbd&gt;Home&lt;/kbd&gt; key. &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;M&lt;/kbd&gt; is &lt;kbd&gt;Return&lt;/kbd&gt;, and &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;T&lt;/kbd&gt; is &lt;kbd&gt;Delete&lt;/kbd&gt;, so these can&amp;rsquo;t be quoted; use &lt;code&gt;CHR$()&lt;/code&gt; for these. As quote mode characters, these codes appear as reversed versions of their corresponding letters. (This pattern extends to other codes and PETSCII characters, though they&amp;rsquo;re less easy to remember.)&lt;/p&gt;
&lt;p&gt;In most cases where a code is usefully paired with another, one code is in the range 0-32 and the other is the same code plus 128 ($80), similar to shifted characters. For example, code 2 enables underlining, and code 130 ($82) disables it. Not every code has a useful pair, and for whatever reason the shift enable and disable codes are simply 11 and 12.&lt;/p&gt;
&lt;p&gt;The Commodore 65 assigns several PETSCII codes to keys that have no behavior when printed, such as the function keys. These codes are only useful when reading a keypress with the BASIC &lt;code&gt;GETKEY&lt;/code&gt; command. In some of these cases, the corresponding &lt;kbd&gt;Ctrl&lt;/kbd&gt; keys perform behaviors in the screen editor that do not occur when the code is printed. For example, there is no way to print a PETSCII code with the same effect as typing &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;P&lt;/kbd&gt;.&lt;/p&gt;
&lt;h2 id=&#34;escape-codes&#34;&gt;Escape codes&lt;/h2&gt;
&lt;p&gt;The screen editor has some advanced features that go beyond the available PETSCII control codes. This extended set is accessible by pressing &lt;kbd&gt;Esc&lt;/kbd&gt; followed by another key. See the appendix in your User&amp;rsquo;s Guide for a complete list. (Be sure to &lt;a href=&#34;https://mega65.org/docs&#34;&gt;download the latest PDFs&lt;/a&gt;, which include minor updates to this appendix specifically.)&lt;/p&gt;
&lt;p&gt;Only a few escape codes are useful from &lt;code&gt;PRINT&lt;/code&gt;. You activate them by printing the PETSCII code for &lt;kbd&gt;Esc&lt;/kbd&gt;, which is &lt;code&gt;CHR$(27)&lt;/code&gt;, followed by the appropriate character. As we saw last month, &lt;kbd&gt;Esc&lt;/kbd&gt; followed by the character &lt;code&gt;5&lt;/code&gt; switches to 80x50 mode in the latest version of the ROM. You can activate this mode from a BASIC program by printing these codes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT CHR$(27)+&amp;#34;5&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;M&lt;/kbd&gt; disables scrolling of the text display. This can be useful within a program to &lt;code&gt;PRINT&lt;/code&gt; on the bottommost line of the screen. &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;kbd&gt;L&lt;/kbd&gt; re-enables scrolling.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT CHR$(27)+&amp;#34;M{home}{24 down}YOUR SCORE: &amp;#34;,SC&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;programmable-function-keys&#34;&gt;Programmable function keys&lt;/h2&gt;
&lt;p&gt;Your MEGA65 includes a row of function keys, numbered F1 through F14. The seven keys act as the odd numbers; hold &lt;kbd&gt;Shift&lt;/kbd&gt; and press one to access the even numbers. Technically, there are &lt;em&gt;sixteen&lt;/em&gt; function keys, with the last two being the &lt;kbd&gt;Help&lt;/kbd&gt; key and the &lt;kbd&gt;Run&lt;/kbd&gt; key, respectively. (Press &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Run/Stop&lt;/kbd&gt; to act as &lt;kbd&gt;Run&lt;/kbd&gt;.)&lt;/p&gt;
&lt;p&gt;By now, you or your cat may have pressed these keys in the BASIC editor and noticed that they do various things. Some are super useful, and others are not obviously helpful. I know I&amp;rsquo;ve tried pressing the &lt;kbd&gt;Help&lt;/kbd&gt; key on a Commodore 128, only to be disappointed that it just shouts &lt;code&gt;HELP&lt;/code&gt; back at me and doesn&amp;rsquo;t appear to do anything else.&lt;/p&gt;
&lt;p&gt;In the BASIC editor, the purpose of the function keys is to type strings of PETSCII codes. These strings are programmable! When you press a function key, it types its string as if you typed it out manually. For example, the default definition of the &lt;kbd&gt;Help&lt;/kbd&gt; key is a string of five codes: &lt;code&gt;HELP&lt;/code&gt; followed by the &lt;kbd&gt;Return&lt;/kbd&gt; key. On a blank line, this enters the BASIC command &lt;code&gt;HELP&lt;/code&gt;, which displays information about the most recent error encountered by your BASIC program. (If your program didn&amp;rsquo;t recently encounter an error, the &lt;code&gt;HELP&lt;/code&gt; command prints nothing.)&lt;/p&gt;
&lt;p&gt;To see a list of all of the function key definitions, type the &lt;code&gt;KEY&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;KEY&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/petscii-codes/default_keys.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/petscii-codes/default_keys.png 415w, https://dansanderson.com/mega65/petscii-codes/default_keys_hu_587b6ce8aedf33ce.png 600w, https://dansanderson.com/mega65/petscii-codes/default_keys_hu_745948b5146a9215.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/petscii-codes/default_keys.png&#34;
        alt=&#34;The default function key definitions (ROM 920383)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The default function key definitions (ROM 920383)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Knowing what we know about PETSCII codes, we can see how the default definitions of the function keys work. Several definitions use &lt;code&gt;CHR$(27)&lt;/code&gt; to refer to the &lt;kbd&gt;Esc&lt;/kbd&gt; key, entering escape codes. Others use &lt;code&gt;CHR$(13)&lt;/code&gt; to type the &lt;kbd&gt;Return&lt;/kbd&gt; key to enter commands. Some definitions use quoted control codes to type the equivalent key sequences.&lt;/p&gt;
&lt;p&gt;Notice that key sequences that control the BASIC editor don&amp;rsquo;t work with the &lt;code&gt;PRINT&lt;/code&gt; command, but they do work in function key definitions. For example, function key F9 is defined as a synonym for &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;P&lt;/kbd&gt;, which scrolls a line of a BASIC program listing onto the screen from the bottom. Paired with the default definition of F11, &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;V&lt;/kbd&gt;, these keys are a handy way to browse a BASIC program listing, and more convenient than using the control sequences directly.&lt;/p&gt;
&lt;p&gt;To redefine a function key, use the &lt;code&gt;KEY&lt;/code&gt; command with arguments: the function key number, a comma, and the string definition. For your convenience, this is how the &lt;code&gt;KEY&lt;/code&gt; command displays the current definitions, so you can cursor up to one of those lines, make a change, and press &lt;kbd&gt;Return&lt;/kbd&gt; to register the new definition.&lt;/p&gt;
&lt;p&gt;It can be really handy to define function keys for project-specific tasks. For example, say you&amp;rsquo;re troubleshooting a subroutine on line 3500 that has different behaviors depending on the value of the &lt;code&gt;X&lt;/code&gt; variable, and you want to try it with different values. You can define the function keys F1 and F3 as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;KEY 1,&amp;#34;X=&amp;#34;
KEY 3,&amp;#34;:GOSUB 3500&amp;#34;+CHR$(13)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can test the subroutine quickly: press F1, enter a value for &lt;code&gt;X&lt;/code&gt;, then press F3.&lt;/p&gt;
&lt;p&gt;Once you have function key settings that you like, you can save them to a file on disk, then load them again later. These commands are &lt;code&gt;KEY SAVE &amp;quot;filename&amp;quot;&lt;/code&gt; and &lt;code&gt;KEY LOAD &amp;quot;filename&amp;quot;&lt;/code&gt;, respectively. Save your project-specific definitions on disk with your other project files. You can even have multiple definition files and load them as needed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;KEY SAVE &amp;#34;MYPROJ-KEYS&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;control-codes-in-petcat&#34;&gt;Control codes in petcat&lt;/h2&gt;
&lt;p&gt;In &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/&#34;&gt;the December 2022 issue of the Digest&lt;/a&gt;, I mentioned a handy tool for developing MEGA65 BASIC programs on your PC called &lt;code&gt;petcat&lt;/code&gt;. This tool is distributed with the &lt;a href=&#34;https://sourceforge.net/projects/vice-emu/&#34;&gt;VICE suite of Commodore emulators&lt;/a&gt;. It converts between PETSCII characters and an ASCII text-based syntax, so your programs can include all of the possible characters even though your PC doesn&amp;rsquo;t have a Commodore keyboard.&lt;/p&gt;
&lt;p&gt;For the more unusual PETSCII characters and control codes, petcat has a label syntax using curly brackets, similar to what we used earlier for codes like &lt;code&gt;{red}&lt;/code&gt;. You can type these labels directly into your text file, and &lt;code&gt;petcat&lt;/code&gt; will generate the equivalent PETSCII code when it makes the PRG file.&lt;/p&gt;
&lt;p&gt;To my knowledge, there isn&amp;rsquo;t an existing prose document that describes all of the &lt;code&gt;petcat&lt;/code&gt; syntax. So I wrote one. See my new &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/27492353/Using+petcat+for+cross-developing+BASIC+programs&#34;&gt;petcat syntax reference&lt;/a&gt; in the MEGA65 Wiki. Feedback welcome!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;PETSCII is a defining feature of Commodore computers, providing a ton of display power that&amp;rsquo;s easy to use in BASIC programs. I hope it inspires you to do something great!&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/petscii-codes/M65Digest_2023Apr.mp3" length="32903753" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1645</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/petscii-codes/digiloi.png"/>
      
    </item>
    
    <item>
      <title>A Rorschach Test on Fire</title>
      <link>https://dansanderson.com/mega65/rorschach-test-on-fire/</link>
      <pubDate>Tue, 14 Mar 2023 17:43:14 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/rorschach-test-on-fire/</guid>
      <description>&lt;p&gt;A Rorschach Test on Fire. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for March 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;A Rorschach Test on Fire. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for March 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/M65Digest_2023Mar.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/M65Digest_2023Mar.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
A Rorschach Test on Fire.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/Mandelbrot_set_image.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/Mandelbrot_set_image.png 1280w, https://dansanderson.com/mega65/rorschach-test-on-fire/Mandelbrot_set_image_hu_f5a5abb3ed04d90.png 600w, https://dansanderson.com/mega65/rorschach-test-on-fire/Mandelbrot_set_image_hu_e1d535b35f208ad1.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/Mandelbrot_set_image.png&#34;
        alt=&#34;A section of a graph of the Mandelbrot set. Image from Wikipedia, used under a Creative Commons license.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A section of a graph of the Mandelbrot set. (Image from Wikipedia.)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This month, we have featured files, featured features, new hardware, and a classic programming exercise to play with. Let&amp;rsquo;s get started!&lt;/p&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;Get this month&amp;rsquo;s Featured Files from &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt; and keep them on your SD card for showing off to your friends!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/luma.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/luma.png 966w, https://dansanderson.com/mega65/rorschach-test-on-fire/luma_hu_6b166147df54d63.png 600w, https://dansanderson.com/mega65/rorschach-test-on-fire/luma_hu_74582bfd643d93f9.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/luma.png&#34;
        alt=&#34;LUMA, by Shallan50k&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
LUMA, by Shallan50k
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=818034ec-a857-4fed-893a-99f836c63c1b&#34;&gt;LUMA&lt;/a&gt; by Shallan50k. Shift the components around on a playfield to fire lasers at targets. Use a joystick in port 2: select a piece, hold the button, then push it in a direction. Try to solve each puzzle in as few moves as possible.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/wavehero.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/wavehero.png 705w, https://dansanderson.com/mega65/rorschach-test-on-fire/wavehero_hu_516ad41bc724656a.png 600w, https://dansanderson.com/mega65/rorschach-test-on-fire/wavehero_hu_e45e52838b0b7b6.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/wavehero.png&#34;
        alt=&#34;Wave Hero, by GeirS&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Wave Hero, by GeirS
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=efa2b304-afa5-4b8f-85fa-f38d05b34d76&#34;&gt;Wave Hero&lt;/a&gt; by GeirS. A watersports-themed one-button runner with smooth gameplay, a gorgeous color palette, and authentic SID sounds. Use just the button of a joystick in port 2. This adaptation of a C64 game includes source code written in &lt;a href=&#34;https://millfork.readthedocs.io/en/latest/&#34;&gt;Millfork&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/mandelbrot.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/mandelbrot.png 705w, https://dansanderson.com/mega65/rorschach-test-on-fire/mandelbrot_hu_23bcdac7a24ef9c.png 600w, https://dansanderson.com/mega65/rorschach-test-on-fire/mandelbrot_hu_6b8689807c5d8730.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/mandelbrot.png&#34;
        alt=&#34;Mandelbrot Explorer 65, by lydon&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Mandelbrot Explorer 65, by lydon
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=eedd4a5d-2862-4c80-8038-addbfceb7dad&#34;&gt;Mandelbrot Explorer 65&lt;/a&gt; by lydon, with &lt;a href=&#34;https://github.com/lydon42/mandelbrot-explorer65&#34;&gt;assembly source&lt;/a&gt;. The fractal so famous there&amp;rsquo;s &lt;a href=&#34;https://www.youtube.com/watch?v=ZDU40eUcTj0&#34;&gt;a song about it&lt;/a&gt;. See also &lt;a href=&#34;https://files.mega65.org?id=6db07e80-1b74-4867-bed1-484f8f9df808&#34;&gt;Mega-Mandelbrot&lt;/a&gt; by Liquidream, in BASIC.&lt;/p&gt;
&lt;h2 id=&#34;an-external-floppy-disk-drive-for-the-mega65&#34;&gt;An external floppy disk drive for the MEGA65&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/FNX1591.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/FNX1591.png 980w, https://dansanderson.com/mega65/rorschach-test-on-fire/FNX1591_hu_60922441f908ccef.png 600w, https://dansanderson.com/mega65/rorschach-test-on-fire/FNX1591_hu_a13f4581e209f384.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/FNX1591.png&#34;
        alt=&#34;The Foenix FNX1591 IEC-compatible floppy disk drive&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Foenix FNX1591 IEC-compatible floppy disk drive
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In addition to the 3-1/2&amp;quot; floppy disk drive built into the MEGA65, the computer supports connecting a vintage Commodore 1581 external floppy drive to the IEC port. These drives are difficult to obtain, with working units listing for upwards of $400 USD on eBay. If you want a second drive for your MEGA65, there&amp;rsquo;s a new option!&lt;/p&gt;
&lt;p&gt;Foenix Retro Systems is taking pre-orders for a new Commodore-compatible 3-1/2&amp;quot; floppy drive, the &lt;a href=&#34;https://c256foenix.com/accessories/?v=7516fd43adaa&#34;&gt;FNX1591&lt;/a&gt;. Like the 1581, it supports double-density (DD) disks, for 720KB of storage per disk. The FNX&amp;rsquo;s firmware can be updated over USB, and it can store multiple firmware options that can be selected by a switch. Another switch can set the IEC unit number. The drive uses a modern power supply and power switch, and sports two IEC connectors for daisy-chaining devices.&lt;/p&gt;
&lt;p&gt;The FNX1591 is intended to be compatible with all computers that work with the 1581, including the MEGA65. You can &lt;a href=&#34;https://c256foenix.com/product/fnx1591/?v=7516fd43adaa&#34;&gt;preorder one today&lt;/a&gt; for $275 USD + $45 USD flat rate shipping. Delivery is estimated for April 2023.&lt;/p&gt;
&lt;p&gt;The drive&amp;rsquo;s resin-printed case is designed to match the &lt;a href=&#34;https://c256foenix.com/f256k/?v=7516fd43adaa&#34;&gt;Foenix F256K&lt;/a&gt;, an all-new 65C02-based wedge-style computer. The F256K is not currently open for orders, but the &lt;a href=&#34;https://c256foenix.com/f256-jr/?v=7516fd43adaa&#34;&gt;F256 Jr&lt;/a&gt;, a low-cost bare-board version, is &lt;a href=&#34;https://c256foenix.com/product/f256-junior-mini-itx/?v=7516fd43adaa&#34;&gt;for sale&lt;/a&gt; for only $199 USD. If your MEGA65 needs a friend, you can&amp;rsquo;t go wrong with an F256 Jr.&lt;/p&gt;
&lt;h2 id=&#34;an-embroidered-dust-cover-for-the-mega65&#34;&gt;An embroidered dust cover for the MEGA65&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/sewready65.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/sewready65.jpg 1600w, https://dansanderson.com/mega65/rorschach-test-on-fire/sewready65_hu_24fe4d7302be72d9.jpg 600w, https://dansanderson.com/mega65/rorschach-test-on-fire/sewready65_hu_26da1ac17fa31015.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/rorschach-test-on-fire/sewready65.jpg&#34;
        alt=&#34;An embroidered dust cover for the MEGA65, by Sew Ready&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An embroidered dust cover for the MEGA65, by Sew Ready
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Sew Ready, a maker of boutique dust covers for vintage Commodore equipment out of Norfolk, United Kingdom, now offers &lt;a href=&#34;https://www.ebay.co.uk/itm/185798516548&#34;&gt;an embroidered dust cover for the MEGA65&lt;/a&gt;! Grey with stylish red piping and a rainbow &amp;ldquo;65&amp;rdquo; logo, this cover protects your MEGA65 (or your Commodore 65, if you have one) while leaving the ports exposed, so you can keep it connected and covered at the same time. £22.99 plus shipping. While you&amp;rsquo;re there, get &lt;a href=&#34;https://www.ebay.co.uk/str/sewready&#34;&gt;matching covers&lt;/a&gt; for all your Commodore gear.&lt;/p&gt;
&lt;p&gt;Looking for other dust cover options? Some large-size keyboard covers like &lt;a href=&#34;https://www.amazon.nl/gp/product/B07NH31NL6/&#34;&gt;this one&lt;/a&gt; tend to fit the MEGA65, and the cheap ones are practical. I found &lt;a href=&#34;https://www.amazon.com/gp/product/B07TNJ9FL5/&#34;&gt;a generic stretchy keyboard cover&lt;/a&gt; that just fits, though it won&amp;rsquo;t protect it from things set on top of it or cats walking across it. For something more durable, lydon found &lt;a href=&#34;https://www.amazon.de/dp/B01N7AM6ZY&#34;&gt;this acrylic keyboard cover&lt;/a&gt; that is sized correctly, and works well with &lt;a href=&#34;https://www.amazon.de/dp/B08GY61GQW&#34;&gt;these clear elastic buffers&lt;/a&gt;. Others have found acrylic display stands that, with the right dimensions, can do the trick and look pretty stylish.&lt;/p&gt;
&lt;p&gt;Want to mount your MEGA65 to the wall? 8-Bit Resurgence (COREi64 in the Discord) made &lt;a href=&#34;https://www.youtube.com/watch?v=BixCBqSX03c&#34;&gt;a video on making 3D-printed presentation brackets&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;recently-added-features-of-the-rom&#34;&gt;Recently added features of the ROM&lt;/h2&gt;
&lt;p&gt;As I mentioned last month, the MEGA65 ROM is getting new updates. February saw a series of updates that promoted features that were contributed over the last year, using a new testing process to eliminate bugs and confirm backwards compatibility with existing MEGA65 software. See the &lt;a href=&#34;https://files.mega65.org?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;ROM FAQ&lt;/a&gt; for a reminder on how to obtain and install the latest beta release.&lt;/p&gt;
&lt;p&gt;The following new features have been added to beta releases since the last release package, up to the most recent ROM version as of this writing, ROM 920383. Many thanks to Bit Shifter for these contributions, and for all of his work on the ROM over the years!&lt;/p&gt;
&lt;h3 id=&#34;80x50-text-mode&#34;&gt;80x50 text mode&lt;/h3&gt;
&lt;p&gt;The MEGA65 operating environment starts up in a text mode with 80 columns and 25 rows. You can change the environment&amp;rsquo;s display mode to 40 columns and 25 rows by pressing the &lt;kbd&gt;Esc&lt;/kbd&gt; key followed by the &lt;code&gt;4&lt;/code&gt; key. To switch back to 80x25, press &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;code&gt;8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Starting with ROM 920382, you can switch the operating environment to 80 columns and &lt;em&gt;50&lt;/em&gt; rows, plenty of screen space for BASIC program code and directory listings. To switch to this mode, press &lt;kbd&gt;Esc&lt;/kbd&gt; then &lt;code&gt;5&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Be advised that some software might not run correctly if started with the computer in a state other than the default boot state. Technically, this is true for anything you can change about the state of the computer, and is not particular to the new 80x50 mode. Some programs would also be confused if you start them in 40x25 mode. When writing a program, it&amp;rsquo;s best to not assume any undocumented default state: either test the state, or set it to be as you need it.&lt;/p&gt;
&lt;p&gt;To set the text screen mode from a BASIC program, use the &lt;code&gt;PRINT&lt;/code&gt; command to emit the PETSCII codes for &lt;kbd&gt;Esc&lt;/kbd&gt; (27) and the appropriate number character. You&amp;rsquo;ll probably want to also emit the code to clear the screen (147).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT CHR$(27)+&amp;#34;5&amp;#34;+CHR$(147)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;mouse-on-default-sprite&#34;&gt;MOUSE ON default sprite&lt;/h3&gt;
&lt;p&gt;BASIC 65 has built-in support for the mouse. When you enable the mouse with &lt;code&gt;MOUSE ON&lt;/code&gt;, BASIC 65 uses the first sprite of its sprite system (sprite 0) as a mouse cursor. In previous versions of the ROM, the BASIC program had to provide its own sprite image for the cursor. You can still provide a custom image, but now you don&amp;rsquo;t have to: the default image for sprite 0 is an arrow-shaped mouse cursor.&lt;/p&gt;
&lt;p&gt;If you have a compatible mouse (or a modern USB mouse and the amazing &lt;a href=&#34;https://retrohax.net/shop/amiga/mouster/&#34;&gt;mouSTer adapter&lt;/a&gt;), try this command to see the BASIC mouse pointer in action:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MOUSE ON&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In a BASIC program, you can read the position and button state of the mouse into variables using the &lt;code&gt;RMOUSE&lt;/code&gt; command. See your User&amp;rsquo;s Guide for more information.&lt;/p&gt;
&lt;p&gt;In addition to the mouse sprite, the other seven sprites are now set a simple default pattern, so you can experiment with the BASIC sprite system without first loading image data.&lt;/p&gt;
&lt;h3 id=&#34;chardef-512&#34;&gt;CHARDEF 512&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;CHARDEF&lt;/code&gt; command in BASIC 65 can replace the glyph of a screen code with a custom pattern. (We played with &lt;code&gt;CHARDEF&lt;/code&gt; a bit in &lt;a href=&#34;https://dansanderson.com/mega65/the-next-batch/&#34;&gt;the September 2022 issue of the Digest&lt;/a&gt;.) In previous versions of the ROM, &lt;code&gt;CHARDEF&lt;/code&gt; could only modify the first 256 screen codes in the uppercase character set. Now you can use &lt;code&gt;CHARDEF&lt;/code&gt; with all 512 screen codes, numbered 0 through 511.&lt;/p&gt;
&lt;p&gt;Remember that your program can only display either the uppercase character set or the lowercase character set on the screen at one time. To switch to the lowercase set, &lt;code&gt;PRINT&lt;/code&gt; PETSCII code 14:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT CHR$(14)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;s&gt;Surprisingly, there is no PETSCII code to switch back to the uppercase character set.&lt;/s&gt; [Update: Thanks to Rhialto for the correction:] To switch back to the uppercase (“graphics”) set:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT CHR$(142)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also use the VIC register at $D018 (53272) to switch between uppercase and lowercase. For the default character set on the Commodore 65, the lower four bits should be 4 for uppercase, or 6 for lowercase.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POKE $D018,PEEK($D018) AND $F0 OR $04

POKE $D018,PEEK($D018) AND $F0 OR $06&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If your program depends on the character set not changing, you may want to disable the ability for the user to toggle between the two sets by pressing &lt;kbd&gt;Mega&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt;. Print PETSCII code 8 to disable it (and PETSCII code 9 to re-enable).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT CHR$(8)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;monitor-pc-handling-and-the-brk-instruction&#34;&gt;MONITOR PC handling and the BRK instruction&lt;/h3&gt;
&lt;p&gt;In &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/&#34;&gt;last month&amp;rsquo;s Digest&lt;/a&gt; we explored the MEGA65 Monitor as an essential tool for learning machine language, understanding how the computer works, and troubleshooting machine language programs. With the latest ROM, the Monitor just got even more useful.&lt;/p&gt;
&lt;p&gt;We saw how you can start the Monitor by typing the &lt;code&gt;MONITOR&lt;/code&gt; command at the &lt;code&gt;READY.&lt;/code&gt; prompt. The MEGA65 will also activate the Monitor when a machine language program executes the &lt;code&gt;BRK&lt;/code&gt; instruction. This is super handy for investigating a problem with the state of the computer from inside your program: just add a &lt;code&gt;BRK&lt;/code&gt; instruction and run your program, and it&amp;rsquo;ll stop at exactly that spot and open the Monitor so you can inspect registers and memory.&lt;/p&gt;
&lt;p&gt;With the latest ROM, the Monitor has been improved so it knows exactly where the &lt;code&gt;BRK&lt;/code&gt; instruction left off. You can now continue your program from the Monitor using the &lt;code&gt;G&lt;/code&gt; command without arguments, assuming you did not modify the program counter while you were in the Monitor.&lt;/p&gt;
&lt;h3 id=&#34;runstoprestore-enters-the-monitor&#34;&gt;Run/Stop+Restore enters the Monitor&lt;/h3&gt;
&lt;p&gt;Anyone who has written a machine language program knows how it feels when a bug in the program causes it to get stuck, ignoring all input, appearing to do nothing—or worse. For these cases, Commodore provided us an escape hatch: hold &lt;kbd&gt;Run/Stop&lt;/kbd&gt; and press &lt;kbd&gt;Restore&lt;/kbd&gt;. This triggers an &lt;em&gt;interrupt&lt;/em&gt; that tells the CPU to stop what it&amp;rsquo;s doing and hand control to the kernel.&lt;/p&gt;
&lt;p&gt;Traditionally, the kernel would handle this interrupt by clearing the screen and displaying a &lt;code&gt;READY.&lt;/code&gt; prompt. This isn&amp;rsquo;t particularly useful when troubleshooting a machine language program. The latest ROM does something a bit smarter: it opens the Monitor, with the program counter set to wherever you interrupted it, as if there had been a &lt;code&gt;BRK&lt;/code&gt; instruction at that location. In many cases, you can even resume your ML program after interruption, using the &lt;code&gt;G&lt;/code&gt; command!&lt;/p&gt;
&lt;p&gt;With the new ROM installed, try assembling the infinite border color program from last month&amp;rsquo;s Digest, then execute it to enter an infinite loop. Press &lt;kbd&gt;Run/Stop&lt;/kbd&gt;+&lt;kbd&gt;Restore&lt;/kbd&gt; to break into the Monitor. Then enter the &lt;code&gt;G&lt;/code&gt; command to resume the fireworks.&lt;/p&gt;
&lt;h2 id=&#34;an-80x50-mandelbrot-set&#34;&gt;An 80x50 Mandelbrot Set&lt;/h2&gt;
&lt;p&gt;Rendering &lt;a href=&#34;https://en.wikipedia.org/wiki/Mandelbrot_set&#34;&gt;the Mandelbrot set&lt;/a&gt; is a rite of passage coding exercise, similar to implementing &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-game-of-life/&#34;&gt;Conway&amp;rsquo;s Game of Life&lt;/a&gt;. lydon&amp;rsquo;s Mandelbrot Explorer 65 and Liquidream&amp;rsquo;s Mega-Mandelbrot show off the MEGA65&amp;rsquo;s color bitmap graphics capabilities. To celebrate the launch of 80x50 BASIC text mode, let&amp;rsquo;s try a low-res version!&lt;/p&gt;
&lt;p&gt;The Mandelbrot set is the set of complex numbers &lt;code&gt;c&lt;/code&gt; for which the function &lt;code&gt;f(z+1) = f(z)^2 + c&lt;/code&gt; does not diverge to infinity when iterated from &lt;code&gt;z = 0&lt;/code&gt;. In other words, take a complex number &lt;code&gt;c&lt;/code&gt;, then starting from zero, repeatedly add the complex number and square the result. If the results run off to infinity, the number &lt;code&gt;c&lt;/code&gt; is not in the set. If the results never run off—maybe they bounce around locally or converge toward zero—then &lt;code&gt;c&lt;/code&gt; is in the set.&lt;/p&gt;
&lt;p&gt;The most famous image of the Mandelbrot set represents the points on the complex plane where &lt;code&gt;c = x + iy&lt;/code&gt;, where &lt;code&gt;i&lt;/code&gt; is the imaginary constant defined as &lt;code&gt;i^2 = -1&lt;/code&gt;, centered on the origin &lt;code&gt;(0, 0)&lt;/code&gt; and zoomed in fairly close. Points that are in the set appear in the image as black, forming bulbous round shapes.&lt;/p&gt;
&lt;p&gt;A simple computer program can draw the image as a bitmap by testing every pixel &lt;code&gt;(x, y)&lt;/code&gt; as a coordinate on the complex plane, starting the function at the point and iterating until either it starts to look like the value is diverging, or a maximum number of iterations is reached. If the value is still near the starting point after the maximum iterations, the program concludes it is in the set. Traditionally, the program assigns diverging (non-member) points a color based on the number of iterations it took to detect divergence, giving the figure a glowing effect that shows how points near members of the set take longer to diverge than those farther away.&lt;/p&gt;
&lt;p&gt;(See also Dr. Holly Krieger&amp;rsquo;s excellent explanation in &lt;a href=&#34;https://www.youtube.com/watch?v=NGMRB4O922I&#34;&gt;The Mandelbrot Set episode of Numberphile&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s write a BASIC program to draw this using 80x50 text mode. First, adjust the color palette to provide a gradient of colors for the non-set points. You can experiment with different values to adjust the colors to your taste.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 PALETTE COLOR 0,0,0,0
20 FOR N=1 TO 15:PALETTE COLOR N,N,0,4-(N-4):NEXT N&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A BASIC program can set the screen mode by printing the PETSCII code for the &lt;kbd&gt;ESC&lt;/kbd&gt; key (27) then the character for &lt;code&gt;5&lt;/code&gt;, similar to if you typed it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 PRINT CHR$(27)+&amp;#34;5&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To draw the pattern, the program visits each character position once, using a nested &lt;code&gt;FOR&lt;/code&gt; loop. For this program, we&amp;rsquo;ll set every character on the screen to a solid rectangle, then set the color based on our calculations. The BASIC 65 special array &lt;code&gt;T@&amp;amp;()&lt;/code&gt; gives us access to the characters on the screen, and the special array &lt;code&gt;C@&amp;amp;()&lt;/code&gt; gives us access to the colors. These arrays are indexed with a row and column number, and you can read or assign to these values, similar to other arrays.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;110 FOR K=0 TO 79
120 FOR R=0 TO 49
130 T@&amp;amp;(K,R)=160&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The program fills the screen with solid rectangles (screen code 160). The rest of the code will test the point for set membership and set its color accordingly.&lt;/p&gt;
&lt;p&gt;The first thing we need to do is determine the actual x/y coordinates on the complex plane for each position on the screen. The y-axis should be in the center, so the x coordinate is 0 when the column number &lt;code&gt;K&lt;/code&gt; is 40. Similarly, the x-axis should also be centered, so the y coordinate is 0 when the row number &lt;code&gt;R&lt;/code&gt; is 25. We also need to scale down the coordinate ranges to be much smaller, so we can see something interesting. These calculations for &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Y&lt;/code&gt; should produce interesting results:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;140 X=(K-40)*0.06
150 Y=(R-25)*0.06&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These variables represent the complex number &lt;code&gt;c = x + iy&lt;/code&gt; that corresponds with the coordinate on the screen. We need to keep track of the iteration value, a complex value stored in the variables &lt;code&gt;ZX&lt;/code&gt; and &lt;code&gt;ZY&lt;/code&gt;. We also need to keep track of the number of iterations, in variable &lt;code&gt;N&lt;/code&gt;. Initialize these variables to zero.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;160 ZX=0:ZY=0:N=0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;BASIC 65 does not have built-in support for complex numbers or the imaginary constant &lt;code&gt;i&lt;/code&gt;, but it turns out we don&amp;rsquo;t need it. We can calculate the new values of &lt;code&gt;ZX&lt;/code&gt; and &lt;code&gt;ZY&lt;/code&gt; using separate equations for the real and imaginary parts. Remembering that &lt;code&gt;i&lt;/code&gt; squared is -1, the square of a complex number can be figured as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(x + iy)^2

x^2 + ixy + ixy + (iy)^2

x^2 + 2ixy + (-1)y^2

(x^2 - y^2) + i(2xy)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To complete the equation, add the components of the original complex value, &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Y&lt;/code&gt;. The complete BASIC code for updating the &lt;code&gt;ZX&lt;/code&gt; and &lt;code&gt;ZY&lt;/code&gt; variables is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;170 ZX=ZX*ZX-ZY*ZY+X
180 ZY=2*ZX*ZY+Y&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each time we iterate this function, we can determine whether the function is diverging by testing whether the updated point is far away from where it started. We&amp;rsquo;re using starting points that are very close to the origin, so to keep the math simple, we can take the distance of the new point from the origin. This distance, known as the &lt;em&gt;magnitude&lt;/em&gt; of the complex number &lt;code&gt;c = x + iy&lt;/code&gt;, can be found using the Pythagorean Theorem, the square root of the quantity &lt;code&gt;x^2 + y^2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In BASIC 65, the square root function is spelled &lt;code&gt;SQR()&lt;/code&gt;, so we get our magnitude like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;190 A=SQR(ZX*ZX+ZY*ZY)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;ve just completed an iteration, so we need to increment the iteration counter &lt;code&gt;N&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;200 N=N+1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can test whether we&amp;rsquo;re done iterating. If the magnitude of the value hasn&amp;rsquo;t gotten large enough to conclude that the function is diverging, and we haven&amp;rsquo;t yet reached the maximum number of iterations, we continue iterating.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;210 IF A&amp;lt;=2 AND N&amp;lt;80 THEN 170&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After iteration is complete, we determine the color of the screen location based on the number of iterations. If we hit the maximum, we conclude that the point is in the Mandelbrot set, so the square should be black. Otherwise it is some other color based on the number of iterations. With a maximum iteration count of 80, one way to convert this to a color value between 0 and 15 is to divide it by 5.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;220 C=0:IF N=80 THEN 240
230 C=N/5+1
240 C@&amp;amp;(K,R)=C
250 NEXT R
260 NEXT K&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;rsquo;s it! &lt;code&gt;RUN&lt;/code&gt; this program and watch it draw a pattern that roughly resembles the Mandelbrot Set image. 80x50 is a low resolution, but it&amp;rsquo;s close to &lt;a href=&#34;https://commons.wikimedia.org/wiki/File:Mandel.png#/media/File:Mandel.png&#34;&gt;the first picture of the Mandelbrot Set&lt;/a&gt;, published by Robert W. Brooks and Peter Matelski in 1978.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;Mandelbrot Set, you&amp;rsquo;re a Rorschach Test on fire&lt;br&gt;
You&amp;rsquo;re a day-glo pterodactyl&lt;br&gt;
You&amp;rsquo;re a heart-shaped box of springs and wire&lt;br&gt;
You&amp;rsquo;re one badass fucking fractal&lt;br&gt;
And you&amp;rsquo;re just in time to save the day&lt;br&gt;
Sweeping all our fears away&lt;br&gt;
You can change the world in a tiny way&lt;br&gt;
&lt;br&gt;
— &amp;ldquo;&lt;a href=&#34;https://wiki.jonathancoulton.com/Mandelbrot_Set&#34;&gt;Mandelbrot Set&lt;/a&gt;,&amp;rdquo; by &lt;a href=&#34;https://www.jonathancoulton.com/&#34;&gt;Jonathan Coulton&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Peace and love,&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/rorschach-test-on-fire/M65Digest_2023Mar.mp3" length="32254349" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1613</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/rorschach-test-on-fire/mandelbrot.png"/>
      
    </item>
    
    <item>
      <title>What I Wish I Knew About Machine Language</title>
      <link>https://dansanderson.com/mega65/what-i-wish-i-knew/</link>
      <pubDate>Tue, 14 Feb 2023 09:30:14 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/what-i-wish-i-knew/</guid>
      <description>&lt;p&gt;What I Wish I Knew About Machine Language. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for February 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;What I Wish I Knew About Machine Language. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for February 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/M65Digest_2023Feb.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/M65Digest_2023Feb.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
What I Wish I Knew About Machine Language.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/scootercomputer.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/scootercomputer.png 473w, https://dansanderson.com/mega65/what-i-wish-i-knew/scootercomputer_hu_b9db16f6737d0ed.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/scootercomputer_hu_79f931faa596a1bb.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/scootercomputer.png&#34;
        alt=&#34;Scooter Computer &amp;amp;amp; Mr. Chips, from the Schoolhouse Rock television series&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Scooter Computer &amp; Mr. Chips, from the Schoolhouse Rock television series.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I spent six years of my early childhood on my Commodore 64, between ages 6 and 12. I wrote many programs, all using the built-in BASIC language, learning everything I could from reading the &lt;a href=&#34;https://archive.org/details/c64-programmer-ref&#34;&gt;&lt;em&gt;Commodore 64 Programmer&amp;rsquo;s Reference Guide&lt;/em&gt;&lt;/a&gt; and typing in program listings from &lt;a href=&#34;https://archive.org/details/computes.gazette/Compute_Gazette_Issue_01_1983_Jul/&#34;&gt;&lt;em&gt;Compute!&amp;rsquo;s Gazette&lt;/em&gt; magazine&lt;/a&gt;. I learned a lot from writing BASIC programs, but the one lesson I took away over and over again was this: to make anything &lt;em&gt;really&lt;/em&gt; cool, like &lt;a href=&#34;https://www.c64-wiki.com/wiki/Marble_Madness&#34;&gt;Marble Madness&lt;/a&gt; or &lt;a href=&#34;https://en.wikipedia.org/wiki/Skyfox_%281984_video_game%29&#34;&gt;Skyfox&lt;/a&gt;, I&amp;rsquo;d need to know machine language.&lt;/p&gt;
&lt;p&gt;Machine language felt like dark magic. In &lt;em&gt;Compute!&amp;rsquo;s Gazette&lt;/em&gt;, all the games with the cool graphics and high speed action were printed as columns of numbers, a pages-long incantation that if you typed it correctly would conjure a video game. The &lt;em&gt;Programmer&amp;rsquo;s Reference&lt;/em&gt; had a chapter on machine language that I stared at endlessly trying to make sense of it, but it only made a passing reference to the fact that I needed additional software to write it. If I were older or had a friend with more experience, I would have known what utility cartridge to ask my parents for as a birthday gift, but it was too much for my kid self to figure out all by myself in a basement.&lt;/p&gt;
&lt;p&gt;In fairness, &lt;em&gt;Compute!&amp;rsquo;s Gazette&lt;/em&gt; did publish the occasional machine language coding tool, like &lt;em&gt;Fast Assembler&lt;/em&gt; in &lt;a href=&#34;https://archive.org/details/1986-01-computegazette&#34;&gt;the January 1986 issue&lt;/a&gt;. The companion disk to the issue even included the source code for &lt;em&gt;Fast Assembler&lt;/em&gt; itself, the first time I had ever seen a complete machine language program listing. I remember making a small change and running the assembler on its own code, which produced a new version of the assembler that printed my name instead of its own. But that&amp;rsquo;s as far as I got.&lt;/p&gt;
&lt;p&gt;In this issue of the Digest, we&amp;rsquo;re going to answer the questions I had when I was a kid. What is machine language? What is an assembler? And what in the name of &lt;a href=&#34;https://en.wikipedia.org/wiki/Chuck_E._Cheese&#34;&gt;Chuck E. Cheese&lt;/a&gt; is hexadecimal? We&amp;rsquo;ll also look at ways you can start learning machine language right now with your MEGA65.&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s time once again for Featured Files, where we highlight stuff you can download from the &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt; and try with your MEGA65 today!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/megawizards.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/megawizards.png 1024w, https://dansanderson.com/mega65/what-i-wish-i-knew/megawizards_hu_6de1bab94d44c92e.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/megawizards_hu_3c9dfda4b1fb20fc.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/megawizards.png&#34;
        alt=&#34;Mega Wizards, by RBJeffrey&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Mega Wizards, by RBJeffrey.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=bda43d38-ec0a-4200-9111-cf5670e2cb64&#34;&gt;Mega Wizards&lt;/a&gt;, by RBJeffrey. A game for one to four players, using the joysticks. Use your wizardly wiles to bounce the magic ball, take out your enemies, and defend your crystal. Three and four players require &lt;a href=&#34;https://www.c64-wiki.com/wiki/Multiplayer_Interface&#34;&gt;a four-player joystick interface&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/wordup.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/wordup.jpg 800w, https://dansanderson.com/mega65/what-i-wish-i-knew/wordup_hu_cd19f2f9229c0f30.jpg 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/wordup_hu_5fcf7504bd245011.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/wordup.jpg&#34;
        alt=&#34;WORDUP, by geehaf&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;WORDUP, by geehaf&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=eeaa396f-e345-48bc-9ac1-578da4c8b42c&#34;&gt;WORDUP&lt;/a&gt; by geehaf. A faithful variant of the popular daily word game Wordle, playable on your MEGA65. Guess the secret five-letter word in six or fewer tries, using hints produced by each guess.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/xmas65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/xmas65.png 705w, https://dansanderson.com/mega65/what-i-wish-i-knew/xmas65_hu_f069ef80517ae698.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/xmas65_hu_72180fbbbce1e2ca.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/xmas65.png&#34;
        alt=&#34;xmas65, by MirageBD&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;xmas65, by MirageBD&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=cdc73698-2332-4fc8-921a-6d50cb067160&#34;&gt;xmas65&lt;/a&gt; by MirageBD. A holiday greeting for the MEGA65 community with an impressive graphical effect and a rockin&amp;rsquo; MOD-style backing track.&lt;/p&gt;
&lt;h2 id=&#34;new-intro-disk&#34;&gt;New Intro Disk!&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/intro2.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/intro2.png 667w, https://dansanderson.com/mega65/what-i-wish-i-knew/intro2_hu_38831d41659767f7.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/intro2_hu_b41b061ad4b15f55.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/intro2.png&#34;
        alt=&#34;Intro Disk #02, a collection of software for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Intro Disk #02, a collection of software for the MEGA65.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The intro disk is the first thing you see when you turn on the MEGA65 for the first time, a bundle of games, demos, and music ready to play and show off your new computer to your friends. Thanks to Gurce, there&amp;rsquo;s now a second intro collection for your enjoyment!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=02fa62d9-82ac-4762-8f00-c84064058ee4&#34;&gt;Intro Disk #02&lt;/a&gt; goes beyond the bounds of a single D81 disk image with dozens of titles and music files, all browsable from a colorful menu. Unpack the zip file and copy the files to your SD card, then boot the &lt;code&gt;INTRO2.D81&lt;/code&gt; disk image.&lt;/p&gt;
&lt;p&gt;There are a lot of files for this one. I had success keeping the files in a subfolder on the SD card. You may want to move the &lt;code&gt;MODS/&lt;/code&gt; subfolder to the root to make these music files easier to play with the new version of the Manche MOD player, included on the intro disk.&lt;/p&gt;
&lt;h2 id=&#34;whats-new-with-the-rom&#34;&gt;What&amp;rsquo;s new with the ROM&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/mega65rom_chip.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/mega65rom_chip.png 752w, https://dansanderson.com/mega65/what-i-wish-i-knew/mega65rom_chip_hu_87677a32d983b4fb.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/mega65rom_chip_hu_4d02627efb48211c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/mega65rom_chip.png&#34;
        alt=&#34;The original C65 prototype ROM chip&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The original C65 prototype ROM chip.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 ROM is the built-in program code that powers the kernel, the BASIC programming language, and the operating environment. It&amp;rsquo;s what Commodore would have burned into a physical ROM chip had they released the Commodore 65 as a product. In the case of the MEGA65, the ROM is actually a file on the SD card, loaded during boot by the firmware.&lt;/p&gt;
&lt;p&gt;Commodore canceled the C65 project before finishing the original C65 ROM. The MEGA65 team has made significant investments into finishing planned features, fixing bugs, and generally making improvements in the spirit of the original Commodore design. The latest MEGA65 ROM is much more useful thanks to these efforts. Release package version 0.9, which shipped with the first batch of MEGA65s in May of last year, bundled the ROM with the version ID of 920287. The most recent release package as of this writing is version 0.95, which shipped with the second batch last October, with ROM 920377.&lt;/p&gt;
&lt;p&gt;The work continues on improving all aspects of the MEGA65 platform, including the ROM. You are invited to help test new &amp;ldquo;beta&amp;rdquo; releases of the ROM, starting with version 920378, now available. If you own a MEGA65 and are signed in to &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt; with your account, you can &lt;a href=&#34;https://files.mega65.org?id=d4f6ef89-6dbf-4e5b-b23f-7822fc12ff24&#34;&gt;download the latest beta ROM&lt;/a&gt; and install it on your SD card. If you do not own a MEGA65, you can put the ROM together for use with the Xemu MEGA65 emulator, using the original C65 ROM, the &lt;a href=&#34;https://files.mega65.org?id=22f1eb6c-3df5-43c4-a584-e8212fc80b9d&#34;&gt;MEGA65 ROM patch file&lt;/a&gt;, and the M65Connect app (also available on Filehost). (The C65 ROM is available for free for personal use as part of &lt;a href=&#34;https://www.c64forever.com/&#34;&gt;C64 Forever Free Express Edition&lt;/a&gt; from Cloanto.)&lt;/p&gt;
&lt;p&gt;If you discover an issue with any version of the ROM, please report it using &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues&#34;&gt;the Issues tab of the mega65-rom-public Github repo&lt;/a&gt;. Check out the new &lt;a href=&#34;https://files.mega65.org?ar=145591dd-deb6-4bd0-aa89-8e39cd021470&#34;&gt;MEGA65 ROM FAQ&lt;/a&gt; article with answers to common questions and instructions on how to download and use the latest ROM. Also, be sure to join the &lt;code&gt;#closed-roms&lt;/code&gt; channel on the Discord for updates.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;addressing-the-computer&#34;&gt;Addressing the computer&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/stiv_scotty.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/stiv_scotty.png 1353w, https://dansanderson.com/mega65/what-i-wish-i-knew/stiv_scotty_hu_e22839bede0afd9f.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/stiv_scotty_hu_1684c4110f2fc156.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/stiv_scotty.png&#34;
        alt=&#34;Still from the movie Star Trek IV: The Voyage Home (1986)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Montgomery Scott tries to wake Siri, 25 years too early.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One of the first things I learned to do with the Commodore 64 was this command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POKE 53280,4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command still works today on your MEGA65. (Try it!) If you haven&amp;rsquo;t memorized what these numbers mean, it&amp;rsquo;s difficult to tell what this command does just from looking at it. Newer Commodores added an equivalent BASIC command that better describes its function, also available on the MEGA65:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BORDER 4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;POKE&lt;/code&gt; command takes two numbers: an &lt;em&gt;address&lt;/em&gt; and a &lt;em&gt;value&lt;/em&gt;. It instructs the CPU to send the value to whatever device inside the computer is wired to that address. The effect this has depends entirely on what&amp;rsquo;s there. In the case of 53280, the address is connected to the VIC video chip, specifically the part that controls the color of the screen border. The different values represent different colors.&lt;/p&gt;
&lt;p&gt;In many cases, the device at an address remembers the last sent value, and the CPU can retrieve it with another command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT PEEK(53280)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;POKE&lt;/code&gt; command and &lt;code&gt;PEEK()&lt;/code&gt; function are most often associated with computer &lt;em&gt;memory&lt;/em&gt;, a device whose sole purpose is to remember the most recent value sent to an address for as long as the computer is powered on. Here&amp;rsquo;s an address on the MEGA65 connected to memory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POKE 6144,255

PRINT PEEK(6144)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most addresses are connected to memory chips. Some are connected to other devices, like video and sound generators, disk drives, the keyboard, joysticks, and so on. Non-memory addresses are known as &lt;em&gt;registers&lt;/em&gt;, or more specifically &lt;em&gt;I/O registers&lt;/em&gt; for their purpose of reading input from and writing output to the devices that live there. Not all registers accept new values. For example, the CPU can read a register connected to a joystick port to see which way the joystick is being pushed, but there is no way to send a value to the joystick.&lt;/p&gt;
&lt;p&gt;There are 256 possible values you can send to or read from an address, numbered 0 to 255. The meaning of the value depends entirely on how it is used. It can be a color, a character of text, a set of pixels on the screen, the pitch or volume of a sound, a piece of a larger number, or anything else that can be represented by a value.&lt;/p&gt;
&lt;h2 id=&#34;bits-bytes-and-binary&#34;&gt;Bits, bytes, and binary&lt;/h2&gt;
&lt;p&gt;Internally, the computer represents a value as one or more digital electronic signals. This fundamental unit of digital data is known as a &lt;em&gt;bit&lt;/em&gt;, with two possible values, typically represented by the numbers &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;. Bits can be combined to represent more possible values: two bits can represent four values, &lt;code&gt;00&lt;/code&gt;, &lt;code&gt;01&lt;/code&gt;, &lt;code&gt;10&lt;/code&gt;, or &lt;code&gt;11&lt;/code&gt;; three bits can represent eight values. The value you send to or read from an address is eight bits, also known as a &lt;em&gt;byte&lt;/em&gt;, with 256 possible values. The MEGA65 CPU mostly deals with byte-sized values, which is why it&amp;rsquo;s called an &amp;ldquo;8-bit computer.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s very common to describe bit patterns as numbers—specifically, integers counting up from 0—even when they don&amp;rsquo;t represent numbers in the data. The &lt;em&gt;binary&lt;/em&gt; number system puts these bit patterns in order. The first six binary numbers are &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;10&lt;/code&gt;, &lt;code&gt;11&lt;/code&gt;, &lt;code&gt;100&lt;/code&gt;, and &lt;code&gt;101&lt;/code&gt;, equal to the decimal numbers 0 through 5.&lt;/p&gt;
&lt;p&gt;Just as decimal place values are powers of ten (1, 10, 100, 1000), each binary place value is a power of two (1, 2, 4, 8). You can convert a decimal number to its binary equivalent by setting the bits whose place values add to the number to &lt;code&gt;1&lt;/code&gt;. To convert from binary to decimal, add the place values where bits are set.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/binary.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/binary.png 552w, https://dansanderson.com/mega65/what-i-wish-i-knew/binary_hu_97a870e489e63550.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/binary_hu_a13b2c7d53be99b0.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/binary.png&#34;
        alt=&#34;Converting an eight-bit value to decimal notation&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Converting an eight-bit value to decimal notation.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Addresses are numbered starting from 0 and counting up, and it should be no surprise that the computer uses bits to represent addresses. A Commodore 64 uses 16 bits (two bytes) for addresses, for 65,536 possible addresses. The MEGA65 uses 28 bits for addresses.&lt;/p&gt;
&lt;p&gt;Because the MEGA65’s 45GS02 CPU is an evolution of the Commodore 64’s 6510 CPU, MEGA65 machine language programs mostly work with 16 address bits, and use other features of the 45GS02 CPU to complete the address. It’s kind of like telling a taxi driver where to go using just the house number and street name, and assuming the driver knows the city, state, and country. See the chapter on memory in the manual for more information about how this works.&lt;/p&gt;
&lt;h2 id=&#34;hexadecimal-to-the-rescue&#34;&gt;Hexadecimal to the rescue!&lt;/h2&gt;
&lt;p&gt;We use decimal numbers in our daily lives, but it gets unwieldy when working with computer programs. Computers are designed around binary, so all of the useful value ranges are convenient in binary—and confusing in decimal. 255 feels like a weird stopping point for a byte, but in binary it&amp;rsquo;s just the largest eight-digit value: &lt;code&gt;11111111&lt;/code&gt;. As more bits get involved, the possibilities get even more difficult to track. Why is 65,536 an important number? How much is 1,048,576? What is at address 268,251,168?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POKE 268251168,3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Writing programs using binary numbers would quickly drive us mad. A 28-bit address would literally be twenty-eight 1&amp;rsquo;s and 0&amp;rsquo;s. We need a concise way to represent these numbers that doesn&amp;rsquo;t make them more confusing. That&amp;rsquo;s where hexadecimal comes in.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/02%20CHARDEF%20hex.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/02%20CHARDEF%20hex.png 445w, https://dansanderson.com/mega65/what-i-wish-i-knew/02%20CHARDEF%20hex_hu_5cdd8a2e23aafb61.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/02%20CHARDEF%20hex_hu_f1cb94a5caef3517.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/02%20CHARDEF%20hex.png&#34;
        alt=&#34;The sixteen hexadecimal digits, and their bits&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The sixteen hexadecimal digits, and their bits.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Hexadecimal is a numbering system that uses sixteen possible values per digit, so a single hex digit completely represents all possible values of four bits. A byte value can be represented by two hex digits instead of eight binary digits.&lt;/p&gt;
&lt;p&gt;Earlier we saw that the border color address is &lt;code&gt;53280&lt;/code&gt; in decimal. It looks like a random number, if you haven&amp;rsquo;t memorized it. In binary, a hint of a pattern emerges, but it&amp;rsquo;s still difficult to manage: &lt;code&gt;1101000000100000&lt;/code&gt; To convert this to hexadecimal, split the bits into four-bit groups, then find the hex digit that represents each group. 53,280 in hexadecimal is D020.&lt;/p&gt;
&lt;p&gt;To avoid confusing a hex number with a decimal number, it is often written with a dollar sign in front: $D020. This convention is common to microcomputer programming. (Modern languages use different conventions for hex numbers, such as &lt;code&gt;0xd020&lt;/code&gt; in Python.)&lt;/p&gt;
&lt;p&gt;Commodore 64 BASIC only knows decimal notation for numbers, so C64 programmers are well practiced at converting between bit values and decimal notation. MEGA65 BASIC can handle hexadecimal numbers directly, so you don&amp;rsquo;t need to bother. Just use the dollar sign notation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POKE $D020,$04&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes it easy to use MEGA65 BASIC as a hexadecimal calculator. To convert a hexadecimal number to decimal, simply print the value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT $D020&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To see the hexadecimal representation of any number or expression, use the &lt;code&gt;HEX$()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRINT HEX$(53280)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The MEGA65 I/O registers are in the address range $D000 &amp;ndash; $DFFF. In hexadecimal, all of these addresses start with a &lt;code&gt;D&lt;/code&gt;. This is easier to understand than using decimal notation for the range: 53248 &amp;ndash; 57343.&lt;/p&gt;
&lt;p&gt;Most books on this subject discuss at length how to convert between hexadecimal and decimal. This is fine for getting accustomed to the idea. In practice, as long as your programming tools support hexadecimal notation, you rarely need to convert between hexadecimal and decimal. It&amp;rsquo;s more convenient to leave addresses and values in hexadecimal, and understand how hex digits represent bit patterns in groups of four. Adding one hexadecimal number to another takes some practice—but you always have your handy MEGA65 to help you.&lt;/p&gt;
&lt;h2 id=&#34;the-cpu-always-follows-instructions&#34;&gt;The CPU always follows instructions&lt;/h2&gt;
&lt;p&gt;The CPU&amp;rsquo;s job is to perform the instructions of a machine language program. When it&amp;rsquo;s not running the instructions of your program, it is running the instructions of the MEGA65 kernel to blink the cursor, perform BASIC commands, access disk drives, and so forth. If it doesn&amp;rsquo;t look busy, it&amp;rsquo;s busy waiting.&lt;/p&gt;
&lt;p&gt;Machine language instructions manipulate memory, interact with I/O registers, perform simple calculations, and make decisions about what instructions to perform next. There are surprisingly few things the CPU knows how to do. Most of its power comes from being able to perform very many instructions very quickly.&lt;/p&gt;
&lt;p&gt;The CPU reads its instructions from bytes in memory. It keeps track of which address has its next instruction using an internal register called the &lt;em&gt;program counter&lt;/em&gt; (PC). The CPU reads the instruction from the address stored in the program counter, then does it. By the end of the instruction, the program counter contains the address of the next instruction to perform, and the process repeats.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/fastassembler.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/fastassembler.png 949w, https://dansanderson.com/mega65/what-i-wish-i-knew/fastassembler_hu_4f663155d43a9ff.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/fastassembler_hu_66a044d9f903c760.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/fastassembler.png&#34;
        alt=&#34;Fast Assembler, by Yves Han, published in Compute!&amp;amp;#39;s Gazette magazine, January 1986, as an inscrutable list of numbers&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Fast Assembler, by Yves Han, published in Compute!&#39;s Gazette magazine, January 1986, as an inscrutable list of numbers. This is the complete program.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Those columns of numbers in a &lt;em&gt;Compute!&amp;rsquo;s Gazette&lt;/em&gt; magazine program listing are machine language instructions (and data) for the program. As you type them in, Compute!&amp;rsquo;s &amp;ldquo;MLX&amp;rdquo; data entry program stores those values at their corresponding addresses. (MLX magazine listings also include a checksum value as the last number in the line, so it can catch your typing mistakes.)&lt;/p&gt;
&lt;p&gt;To start a typical &lt;em&gt;Compute!&amp;rsquo;s Gazette&lt;/em&gt; program, you use the BASIC &lt;code&gt;SYS&lt;/code&gt; command with the address of the first instruction. &lt;code&gt;SYS&lt;/code&gt; sets the CPU&amp;rsquo;s program counter to that address, and the program takes it from there.&lt;/p&gt;
&lt;p&gt;You can write your own machine language routine in a similar way, setting values in memory that represent instructions then calling the routine with &lt;code&gt;SYS&lt;/code&gt;. Try entering these commands on your MEGA65:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POKE $1800,$EE
POKE $1801,$20
POKE $1802,$D0
POKE $1803,$60
SYS $1800&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you mis-type any of these numbers, your computer might do something strange. You can always restart the computer and try again.&lt;/p&gt;
&lt;h2 id=&#34;a-human-friendly-machine-language&#34;&gt;A human-friendly machine language&lt;/h2&gt;
&lt;p&gt;Yes, &lt;code&gt;EE 20 D0 60&lt;/code&gt; is a machine language program. You&amp;rsquo;re not expected to know what it means, nor are you expected to write programs that way. It’s possible to do so, in the same way that I used to sit in that basement drawing pixel art on graph paper and converting it to byte values for my &lt;code&gt;DATA&lt;/code&gt; statements, but it’s slow going. (I &lt;a href=&#34;https://dansanderson.com/lab-notes/it-s-a-lovely-saturday-which/&#34;&gt;tried this recently&lt;/a&gt; as an exercise for a different microcomputer. It&amp;rsquo;s fun, the first time.)&lt;/p&gt;
&lt;p&gt;When most people say they&amp;rsquo;re writing a machine language program, most often they’re actually using &lt;em&gt;assembly language&lt;/em&gt;, a programming language that is roughly similar to the computer&amp;rsquo;s machine language, along with a tool that converts it to machine code called an &lt;em&gt;assembler&lt;/em&gt;. Assembly language consists of the same instructions that the CPU knows how to perform, just spelled out in a way that&amp;rsquo;s easier to read and write.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s that short machine language routine again, this time written as assembly language instructions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INC $D020
RTS&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first instruction tells the CPU to increase the value at address $D020 by one. The second instruction returns from the subroutine. As we&amp;rsquo;ve seen, address $D020 controls the border color. Each time you &lt;code&gt;SYS&lt;/code&gt; to the first instruction, the border color changes, and control returns back to BASIC.&lt;/p&gt;
&lt;h2 id=&#34;registers-instructions-and-addressing-modes&#34;&gt;Registers, instructions, and addressing modes&lt;/h2&gt;
&lt;p&gt;The CPU contains a little bit of memory of its own to use as scratch paper while performing computations. The MEGA65&amp;rsquo;s 45GS02 CPU has four general purpose registers, each the size of a byte: an &lt;em&gt;accumulator&lt;/em&gt; (often referred to as just A), and registers X, Y, and Z. The program counter (PC) is an example of a special purpose register, holding the address of the current instruction.&lt;/p&gt;
&lt;p&gt;The CPU maintains eight one-bit registers, called &lt;em&gt;flags&lt;/em&gt; or just &lt;em&gt;status registers&lt;/em&gt; (SR), that indicate useful aspects of the machine&amp;rsquo;s operation. For example, the Zero flag is set after a math operation results in zero, which is useful for countdowns or comparing whether two numbers are equal.&lt;/p&gt;
&lt;p&gt;The CPU reserves a small area of memory to use as a data structure called a &lt;em&gt;stack&lt;/em&gt;. Much like a stack of cards, you can push new values onto the stack, and pull the last pushed value off of it. The CPU uses the stack to remember its place when calling a subroutine, like the &lt;code&gt;SYS&lt;/code&gt; command does, so it can return to that place when the subroutine performs the &lt;code&gt;RTS&lt;/code&gt; instruction.&lt;/p&gt;
&lt;p&gt;The CPU gives special treatment to a single &lt;em&gt;page&lt;/em&gt; of memory, 256 bytes starting at an address that ends in &lt;code&gt;$00&lt;/code&gt;. It can access this memory faster than other locations, so it&amp;rsquo;s useful for storing variables that change frequently. In the Commodore 64 (and the 6502/6510 CPU), this is known as the &lt;em&gt;zero page&lt;/em&gt; because it is always located at address $0000. In the MEGA65, the 45GS02 CPU can change which page it uses for this purpose, so it is known as the &lt;em&gt;base page&lt;/em&gt;. The location of the base page is stored in a register (B).&lt;/p&gt;
&lt;p&gt;Nearly all CPU instructions manipulate a value in working memory, a value at an address, or both. Here are just a few examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;LDA $1900&lt;/code&gt; : load the value from address $1900 into the accumulator&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LDX #$FF&lt;/code&gt; : load the value $FF into the X register&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STA $D020&lt;/code&gt; : store the value in the accumulator to address $D020&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ADC #$1A&lt;/code&gt; : add the value &lt;code&gt;$1A&lt;/code&gt; to the value in the accumulator&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AND $C901&lt;/code&gt; : set the accumulator to just the &lt;code&gt;1&lt;/code&gt; bits that are present in both the accumulator and the value at address $C901&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BNE $180C&lt;/code&gt; : set the program counter to $180C (&amp;ldquo;branch to&amp;rdquo;) if the last math operation resulted in something other than zero&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JMP $18FF&lt;/code&gt; : set the program counter to $18FF (&amp;ldquo;jump to&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JSR $1900&lt;/code&gt; : remember the address of the next instruction, start executing the subroutine at address $1900, then return to this location when the subroutine performs &lt;code&gt;RTS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PHA&lt;/code&gt; : push the accumulator value onto the stack&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PLA&lt;/code&gt; : pull the most recently pushed value from the stack, and set the accumulator to that value&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TXA&lt;/code&gt; : swap the values in the accumulator and X register&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Instructions that access addresses often have variants for different &lt;em&gt;addressing modes&lt;/em&gt; that describe how the address is calculated. As shown in the examples above, some instructions can read a value from an address provided with the instruction, or it can read the value provided with the instruction itself (which is just reading it from the memory that contains the program code).&lt;/p&gt;
&lt;p&gt;Addressing modes are a powerful concept, and understanding them is critical for performing certain tasks effectively. The MEGA65 45GS02 CPU has many addressing modes. I recommend learning a few common ones to get started, then read about the rest once you&amp;rsquo;ve tried writing a few short programs.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://mega65.org/docs&#34;&gt;MEGA65 manuals&lt;/a&gt; describe the 45GS02 instruction set and addressing modes in detail. The 45GS02 supports all of the instructions of the 6502, so descriptions of &lt;a href=&#34;http://www.6502.org/tutorials/6502opcodes.html&#34;&gt;the 6502 instruction set&lt;/a&gt; (&lt;a href=&#34;https://www.masswerk.at/6502/6502_instruction_set.html&#34;&gt;another good one&lt;/a&gt;) that you can find online and in books also apply to the MEGA65.&lt;/p&gt;
&lt;h2 id=&#34;the-mega65-machine-language-monitor&#34;&gt;The MEGA65 machine language monitor&lt;/h2&gt;
&lt;p&gt;The chapter on machine language in &lt;em&gt;The Commodore 64 Programmer&amp;rsquo;s Guide&lt;/em&gt; makes a brief mention of a software tool called &amp;ldquo;64MON,&amp;rdquo; and uses it to introduce machine language concepts. I know they did not intend this to be cruel, but it was an insurmountable hurdle for me as a kid that Commodore did not include 64MON or anything like it with the computer.&lt;/p&gt;
&lt;p&gt;64MON was a &lt;em&gt;machine language monitor&lt;/em&gt;, a tool for examining and interacting directly with the CPU and memory of a microcomputer. An ML monitor is a gateway to accessing the raw power of a machine, so useful that many microcomputers had one built in. The earliest models of the Apple II even booted directly into an ML monitor, instead of BASIC. Commodore added a built-in monitor to their computers starting with the C16. The MEGA65 includes an all-new monitor, written by Bit Shifter.&lt;/p&gt;
&lt;p&gt;To start the MEGA65 ML monitor from the &lt;code&gt;READY.&lt;/code&gt; prompt, type the &lt;code&gt;MONITOR&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MONITOR&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/m65mon-start.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/m65mon-start.png 720w, https://dansanderson.com/mega65/what-i-wish-i-knew/m65mon-start_hu_1bc768981fc16dec.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/m65mon-start_hu_76e239eb95383b66.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/m65mon-start.png&#34;
        alt=&#34;The MEGA65 machine language monitor.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 machine language monitor.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The monitor accepts commands similar to the BASIC environment. For example, to exit back to BASIC, type &lt;code&gt;X&lt;/code&gt; then press &lt;kbd&gt;Return&lt;/kbd&gt;. The monitor uses the BASIC screen editor, so you can cursor up to previous lines to repeat or modify commands.&lt;/p&gt;
&lt;p&gt;The first thing the monitor displays is the contents of the CPU&amp;rsquo;s working memory: the program counter, the status register, the accumulator, and so on. These values aren&amp;rsquo;t useful when the monitor first starts with the &lt;code&gt;MONITOR&lt;/code&gt; command, but you can examine them at any time with the &lt;code&gt;R&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;I won&amp;rsquo;t describe all of the monitor&amp;rsquo;s uses and features here, but I do want to mention two of its primary functions: examining and changing memory values, and assembling and disassembling machine language instructions.&lt;/p&gt;
&lt;p&gt;Try this command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;M1800&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;M&lt;/code&gt; command takes an address in hexadecimal (with or without the &lt;code&gt;$&lt;/code&gt;), then displays a block of memory values in hexadecimal. If you POKE&amp;rsquo;d that short program into memory earlier, you&amp;rsquo;ll see the byte values at the beginning of this list, along with a bunch of junk values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;1800 EE 20 D0 60 8D 41 6A A9 01 8D 40 6A 20 32 52 20 ................
&amp;gt;1810 ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The command to change values in memory is the &lt;code&gt;&amp;gt;&lt;/code&gt; that appears at the beginning of one of these lines. This is not a coincidence: you can move the cursor up to any line printed by the &lt;code&gt;M&lt;/code&gt; command, change a value, then press &lt;kbd&gt;Return&lt;/kbd&gt; to modify the memory.&lt;/p&gt;
&lt;p&gt;The monitor knows how to assemble instructions directly into memory, using their assembly language mnemonics. To start the assembly process, use the &lt;code&gt;A&lt;/code&gt; command followed by a starting address and the first instruction, then press &lt;kbd&gt;Return&lt;/kbd&gt;. It converts the assembly instruction to machine code, stores it in memory, then prompts for the next instruction. Press &lt;kbd&gt;Return&lt;/kbd&gt; without an instruction to end assembly.&lt;/p&gt;
&lt;p&gt;Try typing &lt;code&gt;A 1800 INC $D020&lt;/code&gt;, followed by &lt;kbd&gt;Return&lt;/kbd&gt;. Then enter &lt;code&gt;RTS&lt;/code&gt; on the next line, and finally enter a blank line. Notice that the assembler displays the machine code byte values that it came up with as you type: &lt;code&gt;EE 20 D0&lt;/code&gt; are the bytes for &lt;code&gt;INC $D020&lt;/code&gt;, and the &lt;code&gt;60&lt;/code&gt; byte means &lt;code&gt;RTS&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To see the assembly instructions stored at an address, use the &lt;code&gt;D&lt;/code&gt; command (for &amp;ldquo;disassembly&amp;rdquo;) followed by the address. Try this now: &lt;code&gt;D 1800&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;. 1800  EE 20 D0 INC  $D020
. 1803  60       RTS
. 1804  8D 41 6A STA  $6A41
. 1807  A9 01    LDA  #$01
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The instructions you entered appear at the top. Notice that the disassembly continues into the junk data region. The disassembler doesn&amp;rsquo;t know that those values are meaningless, so it just displays what those bytes would be as assembly instructions, even though it&amp;rsquo;s nonsense.&lt;/p&gt;
&lt;p&gt;To execute a subroutine from the monitor, use the &lt;code&gt;J&lt;/code&gt; command (for &amp;ldquo;jump&amp;rdquo;) followed by an address. When the CPU encounters the &lt;code&gt;RTS&lt;/code&gt; instruction, it returns control back to the monitor, just as it does with &lt;code&gt;SYS&lt;/code&gt; in BASIC. Note that if you write a subroutine that never reaches the &lt;code&gt;RTS&lt;/code&gt; instruction, control will never return to the monitor. In most cases, you can hold &lt;kbd&gt;Run/Stop&lt;/kbd&gt; and press &lt;kbd&gt;Restore&lt;/kbd&gt; to return to the &lt;code&gt;READY.&lt;/code&gt; prompt without losing your program in memory.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a variation of the border color subroutine without an &lt;code&gt;RTS&lt;/code&gt; instruction. Use the monitor to assemble it at address $1800, then run it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INC $D020
JMP $1800&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For more information on the ML monitor&amp;rsquo;s features, see the manual. I also wrote &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-monitor/&#34;&gt;a tutorial on the MEGA65 Monitor&lt;/a&gt; as part of a series on introductory assembly language.&lt;/p&gt;
&lt;h2 id=&#34;mega-assembler&#34;&gt;Mega Assembler&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/megaassembler.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/megaassembler.png 705w, https://dansanderson.com/mega65/what-i-wish-i-knew/megaassembler_hu_2fd48631682353d8.png 600w, https://dansanderson.com/mega65/what-i-wish-i-knew/megaassembler_hu_838f21c51128e003.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/what-i-wish-i-knew/megaassembler.png&#34;
        alt=&#34;Mega Assembler, by grubi, for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Mega Assembler, by grubi, for the MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The machine language monitor is super useful for understanding how machine language programs work, and for troubleshooting programs and examining memory. Even so, you would not write large programs this way. A full-fledged assembler application gives you essential tools for managing large amounts of code.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=3b101d41-5128-4a21-879c-0cf7988edfec&#34;&gt;Mega Assembler&lt;/a&gt; by grubi is an assembler for the MEGA65. It includes a source code editor with built-in help features, and can assemble and run your programs, and save them to disk. Check out the example programs included on the disk image to get a feel for how it works.&lt;/p&gt;
&lt;p&gt;One of the most useful features of an assembler is its ability to assign labels to the many numbers that appear in a machine language program. Here&amp;rsquo;s a version of the border color program for Mega Assembler that is easier to read than the raw instructions you entered into the monitor. (Mega Assembler needs the lines indented as shown.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BORDER=$D020

  *=$1800

START
  INC BORDER
  JMP START&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://mega65.org/docs&#34;&gt;The MEGA65 manuals&lt;/a&gt; are the best and most complete reference for the MEGA65, but they do not yet contain introductory material for machine language programming. Thankfully, many books about machine language programming for the 6502/6510 CPU and the Commodore 64 apply to the MEGA65. The memory locations are different, and the MEGA65&amp;rsquo;s 45GS02 has more advanced features, but C64 programming books are still a valuable resource.&lt;/p&gt;
&lt;p&gt;Check &lt;a href=&#34;https://archive.org/&#34;&gt;Archive.org&lt;/a&gt; for scans of popular assembly language books, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://archive.org/details/cbpmlfb&#34;&gt;Machine Language for Beginners&lt;/a&gt; by Richard Mansfield&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://archive.org/details/Machine_Language_for_the_Commodore_64_and_Other_Commodore_Computers_1984_Brady_Communications/mode/2up&#34;&gt;Machine Language for the Commodore 64 and Other Commodore Computers&lt;/a&gt; by Jim Butterfield&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://archive.org/details/Compute_s_Machine_Language_Routines_for_the_Commodore_64&#34;&gt;Compute!&amp;rsquo;s Machine Language Routines for the Commodore 64&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Despite my struggles with it as a small child without the benefit of the Internet, the chapter of the &lt;a href=&#34;https://archive.org/details/c64-programmer-ref/page/n251/mode/2up&#34;&gt;Commodore 64 Programmer&amp;rsquo;s Guide&lt;/a&gt; on machine language is a good introduction to the topic.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;With a built-in machine language monitor, a freely available assembler, and access to hundreds of websites and PDFs, it&amp;rsquo;s so much easier to learn how to write machine language programs for the MEGA65 today than it was for the Commodore 64 in 1986. I hope you give it a try, if only to get a sense of how the computer works, on its own terms.&lt;/p&gt;
&lt;p&gt;See you next month!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/what-i-wish-i-knew/M65Digest_2023Feb.mp3" length="41805238" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>2090</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/what-i-wish-i-knew/scootercomputer.png"/>
      
    </item>
    
    <item>
      <title>Exploring MEGA65 hardware</title>
      <link>https://dansanderson.com/mega65/exploring-hardware/</link>
      <pubDate>Mon, 16 Jan 2023 00:43:47 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/exploring-hardware/</guid>
      <description>&lt;p&gt;Exploring MEGA65 hardware. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for January 2023.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Exploring MEGA65 hardware. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for January 2023.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/exploring-hardware/M65Digest_2023Jan.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/M65Digest_2023Jan.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Exploring MEGA65 hardware.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/MEGA65_te_shop_01.jpg&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/MEGA65_te_shop_01.jpg 1920w, https://dansanderson.com/mega65/exploring-hardware/MEGA65_te_shop_01_hu_447c08ce8462f97f.jpg 600w, https://dansanderson.com/mega65/exploring-hardware/MEGA65_te_shop_01_hu_1947ce869e79082b.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/MEGA65_te_shop_01.jpg&#34;
        alt=&#34;The MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I think many of us were first attracted to the MEGA65 project for its hardware: the Cherry MX keyswitches in an authentic Commodore layout, the precision recreation of the Commodore 65 injection molded case, the 3-1/2&amp;quot; floppy drive—not to mention modern conveniences like HDMI video out and an SD card slot. It has taken nine years of hard work and persistence of vision to bring this project to the point of being something everyone can purchase and enjoy.&lt;/p&gt;
&lt;p&gt;In this Digest, we&amp;rsquo;ll look at the recent history of the MEGA65 hardware, including the Nexys FPGA development board on which most of the firmware was written. We&amp;rsquo;ll take a tour of peripherals that work with the MEGA65, both vintage and new. And we&amp;rsquo;ll look at hardware experiments in progress that may provide a glimpse of the MEGA65&amp;rsquo;s future.&lt;/p&gt;
&lt;p&gt;But first!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;resources-for-new-owners&#34;&gt;Resources for new owners&lt;/h2&gt;
&lt;p&gt;The latest batch of MEGA65s is being delivered, and it&amp;rsquo;s been super exciting to see all of the messages and photos from proud new owners in the Discord. If you&amp;rsquo;re a new owner, welcome to the world of personal computing!&lt;/p&gt;
&lt;p&gt;We have many more resources for getting started with your MEGA65 than we did a year ago. There&amp;rsquo;s &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/21331992/Documentation+-+Landing+Page&#34;&gt;a new documentation landing page&lt;/a&gt;, which has links to the latest version of the User&amp;rsquo;s Guide.&lt;/p&gt;
&lt;p&gt;Last year I wrote a &lt;a href=&#34;https://dansanderson.com/mega65/welcome/&#34;&gt;MEGA65 Welcome Guide&lt;/a&gt; intended to help new owners get up and running. I&amp;rsquo;ve been keeping it up to date to be useful whether you received your MEGA65 last May or this January.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ve already found &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;this Digest&lt;/a&gt;. You might also enjoy the back issues, available on the website.&lt;/p&gt;
&lt;p&gt;That documentation landing page is part of the &lt;a href=&#34;https://mega65.atlassian.net/&#34;&gt;MEGA65 Wiki&lt;/a&gt;, a relatively new resource that we&amp;rsquo;re still building. If you&amp;rsquo;d like to contribute to the wiki, reach out to Gurce on &lt;a href=&#34;https://mega65.org/chat&#34;&gt;the Discord chat server&lt;/a&gt;. You can also read and post articles on &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt;, another great resource.&lt;/p&gt;
&lt;h2 id=&#34;featured-files&#34;&gt;Featured Files&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s the Digest&amp;rsquo;s first recurring segment! Here at Featured Files, we look at cool stuff that has been posted to the &lt;a href=&#34;https://files.mega65.org/&#34;&gt;MEGA65 Filehost&lt;/a&gt;. Download and try these on your MEGA65 today!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/mega-sisters.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/mega-sisters.png 705w, https://dansanderson.com/mega65/exploring-hardware/mega-sisters_hu_e326fb3887323dc9.png 600w, https://dansanderson.com/mega65/exploring-hardware/mega-sisters_hu_154601db43f29020.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/mega-sisters.png&#34;
        alt=&#34;Mega Sisters, by Endurion&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Mega Sisters, by Endurion&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=a8f318a0-afa5-45d2-9543-59bc6d7b2550&#34;&gt;Mega Sisters&lt;/a&gt;, by Endurion. A version of the 1987 Commodore 64 classic &lt;a href=&#34;https://en.wikipedia.org/wiki/The_Great_Giana_Sisters&#34;&gt;The Great Giana Sisters&lt;/a&gt;, this multi-stage adventure pays homage to familiar side-scrolling platformers while adding a few twists of its own. Endurion, aka Georg Rottensteiner, is the author of &lt;a href=&#34;https://georg-rottensteiner.de/en/index.html&#34;&gt;C64 Studio&lt;/a&gt;, a Commodore cross-development IDE for Windows. You can &lt;a href=&#34;https://github.com/GeorgRottensteiner/MegaSisters/tree/master/game&#34;&gt;download the source code&lt;/a&gt; for this MEGA65 game. Use a joystick in port 2; move up to jump.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/battle-sparrow.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/battle-sparrow.png 489w, https://dansanderson.com/mega65/exploring-hardware/battle-sparrow_hu_74592865d9a47811.png 600w, https://dansanderson.com/mega65/exploring-hardware/battle-sparrow_hu_bfdd3875c642f0bd.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/battle-sparrow.png&#34;
        alt=&#34;Battle Sparrow, by gurce&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Battle Sparrow, by gurce&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=a890b935-d6c6-4159-b00f-16841b129c6a&#34;&gt;Battle Sparrow&lt;/a&gt;, by gurce. A vertical scrolling space shooter in the vein of &lt;a href=&#34;https://www.c64-wiki.com/wiki/Warhawk&#34;&gt;Warhawk&lt;/a&gt; for the C64 (1986), this action game was written entirely in MEGA65 BASIC with PETSCII graphics, vibrant colors, and a rockin&amp;rsquo; soundtrack. Use a joystick in port 2.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/barnsley-fern.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/barnsley-fern.png 982w, https://dansanderson.com/mega65/exploring-hardware/barnsley-fern_hu_c1fd1d6f71f0c65.png 600w, https://dansanderson.com/mega65/exploring-hardware/barnsley-fern_hu_490b1d70576dc52.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/barnsley-fern.png&#34;
        alt=&#34;Barnsley Fern Fractal, by heath8041&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;Barnsley Fern Fractal, by heath8041&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=eed83965-5a4b-4ada-892e-3840007c671e&#34;&gt;Barnsley Fern Fractal&lt;/a&gt;, by heath8041. This elegant BASIC program renders the &lt;a href=&#34;https://en.wikipedia.org/wiki/Barnsley_fern&#34;&gt;Barnsley fern&lt;/a&gt; at a resolution of 640x400. The disk image includes several programs to render the fractal in different ways. Run it yourself, or &lt;a href=&#34;https://www.youtube.com/watch?v=MryRMRm-Yh4&#34;&gt;watch Heath-man&amp;rsquo;s video&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;the-mega65-hardware&#34;&gt;The MEGA65 hardware&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/mega65-box.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/mega65-box.jpeg 2048w, https://dansanderson.com/mega65/exploring-hardware/mega65-box_hu_27d8efb8f403f939.jpeg 600w, https://dansanderson.com/mega65/exploring-hardware/mega65-box_hu_e0d75c1d7d8d7b75.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/mega65-box.jpeg&#34;
        alt=&#34;Retail packaging for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The &#34;retail&#34; box for the MEGA65, like you would find in a department store
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When you &lt;a href=&#34;https://shop.trenz-electronic.de/en/Products/MEGA65/&#34;&gt;pre-order a MEGA65 from Trenz Electronic&lt;/a&gt;, you can expect to receive a faithful recreation of the unreleased Commodore 65 personal computer, with a few modern improvements. The first step of this experience is opening the rainbow-colored &amp;ldquo;retail&amp;rdquo; cardboard packing box. Inside the box is the MEGA65 computer, with its authentic injection-molded plastic case, keyboard with authentic layout and keycap designs using modern mechanical keyboard switches, and a refurbished 3-1/2&amp;quot; floppy drive.&lt;/p&gt;
&lt;p&gt;The ports on the back and side of the computer are a mix of modern and familiar: a barrel-jack power connector, a C64-style cartridge port, an IEC serial port, VGA and HDMI video output, an ethernet jack, a microSD card slot, stereo audio output, and two DE-9 ports for joysticks, paddles, and mice.&lt;/p&gt;
&lt;p&gt;Inside the MEGA65 is a circuit board populated with chips and connectors. Compared to its vintage ancestors, the MEGA65&amp;rsquo;s board is surprisingly spare, with less than a handful of devices that you might call chips and lots of empty green space. Also surprising are what appear to be extra unused connectors for diagnostic devices, additional stereo audio outputs, and unspecified peripherals. The keyboard is a separate device connected to the main board with a ribbon cable, as is the floppy drive. The main board also sports a removable full-size SD card pre-populated at the factory with software, and a CR1220 battery holder for the Real-Time Clock.&lt;/p&gt;
&lt;p&gt;At the center of the MEGA65 is the Xilinx Artix-7 FPGA chip, a modern device that can be programmed to behave like other digital logic devices. Importantly, the FPGA replicates these behaviors electronically, as if these digital designs were etched in silicon. The MEGA65 firmware (or &lt;em&gt;core&lt;/em&gt;) describes a complete chipset that in 1991 would have been a dozen permanently-etched chips arrayed across the board.&lt;/p&gt;
&lt;p&gt;The MEGA65 has two smaller FPGA devices on the board, an Altera MAX10 for various electronic functions, and a Lattice device for the keyboard. There are three FPGA devices in total in the MEGA65.&lt;/p&gt;
&lt;p&gt;This is the MEGA65 in its official form. It&amp;rsquo;s what you buy from Trenz Electronic, and it&amp;rsquo;s what the MEGA65 team does its best to support with regular testing and improvement of the firmware and system software. The MEGA65 has taken other forms in the past, and the expandability of the machine and open licenses of the designs are meant to encourage experimentation. Naturally, you install such expansions at your own risk.&lt;/p&gt;
&lt;h2 id=&#34;from-nexys-to-mega&#34;&gt;From Nexys to MEGA&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/nexysa7.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/nexysa7.jpg 500w, https://dansanderson.com/mega65/exploring-hardware/nexysa7_hu_3c83548d46be1e4a.jpg 600w, https://dansanderson.com/mega65/exploring-hardware/nexysa7_hu_1670712d6b061213.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/nexysa7.jpg&#34;
        alt=&#34;The Digilent Nexys A7-100T FPGA trainer board&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Digilent Nexys A7-100T FPGA trainer board
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 as we know it went through multiple stages of hardware development over the years. Most of the MEGA65 core was built on the &lt;a href=&#34;https://digilent.com/shop/nexys-a7-fpga-trainer-board-recommended-for-ece-curriculum/&#34;&gt;Digilent Nexys A7-100T FPGA trainer board&lt;/a&gt;, a bare circuit board that electronics designers use to evaluate the Artix-7&amp;rsquo;s capabilities and learn how to use it. The circuit board is &amp;ldquo;bare&amp;rdquo; in the sense that it doesn&amp;rsquo;t come with its own plastic case, but it is actually quite crowded with features, with connectors and hardware interfaces of various kinds, push-buttons, and a set of seven-segment LED numeric displays. Important to the MEGA65 project, the trainer board includes VGA video output, monaural audio output, a USB port for a PC keyboard, and a microSD card connector.&lt;/p&gt;
&lt;p&gt;While the Nexys board is not an officially supported configuration, the MEGA65 team still provides downloads of &lt;a href=&#34;https://files.mega65.org?id=a2b3c6a2-be4c-4b98-9df4-2bc14df0f222&#34;&gt;the MEGA65 core for the Nexys A7&lt;/a&gt;. You can buy a Nexys board for &lt;a href=&#34;https://www.amazon.com/Digilent-Nexys-DDR-Artix-7-FPGA/dp/B0714MKJ4H&#34;&gt;$350 on Amazon&lt;/a&gt;, install the MEGA65 core, set up the microSD card, and put together a capable MEGA65 rig. This configuration lacks the eight megabyte RAM expansion of the MEGA65, but this is a documented variation, and many software titles can run without it.&lt;/p&gt;
&lt;p&gt;Note that the Nexus A7 board is also known as the &amp;ldquo;Nexys4DDR,&amp;rdquo; which is the name you will see in some documentation. This is not the same as the older board known as the &amp;ldquo;Nexys 4,&amp;rdquo; which was also used for MEGA65 development at one point.&lt;/p&gt;
&lt;p&gt;You can program the Artix-7 FPGA using the &lt;a href=&#34;https://github.com/mega65/mega65-tools&#34;&gt;m65 command-line tool&lt;/a&gt; provided by the MEGA65 project, or with &lt;a href=&#34;https://www.xilinx.com/products/design-tools/vivado/vivado-ml.html&#34;&gt;Vivado ML: Standard Edition&lt;/a&gt;, the free version of the official professional FPGA development suite from Xilinx. Connect your PC to the &amp;ldquo;PROG UART&amp;rdquo; microUSB port on the board.&lt;/p&gt;
&lt;p&gt;Support for the USB host port is limited and doesn&amp;rsquo;t work with USB hubs. You can connect a standard USB PC keyboard to this port, though be warned that fancier keyboards tend to act like USB hubs, so be sure to look for something cheap. A PC keyboard does not have the MEGA65 key layout, but all of the MEGA65 keys are mapped to PC equivalents.&lt;/p&gt;
&lt;p&gt;For serious tinkerers, you can enhance your Nexys board with the &lt;a href=&#34;https://github.com/sy2002/DM65PIC&#34;&gt;DM65PIC MEGA65 widget board&lt;/a&gt;, designed by Dieter Penner. The widget board connects to the Nexys&amp;rsquo;s PMOD ports and provides connectors for an authentic Commodore 64 keyboard, a Commodore 65 keyboard (if you&amp;rsquo;re lucky enough to have one), and two DE-9 ports for joysticks, paddles, or mice. You&amp;rsquo;ll have to get a board fabrication shop to make it from the Eagle design files, and depending on which shop you use you may need to solder some or all of the surface mount components. You&amp;rsquo;ll also have to program the microcontroller using the software in the repo. It&amp;rsquo;s a significant project, but can make for a satisfying build. See &lt;a href=&#34;https://www.youtube.com/watch?v=5PpsEw80j3M&#34;&gt;sy2002&amp;rsquo;s demo video&lt;/a&gt; to see the widget board in action.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/nexys-case-thingiverse.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/nexys-case-thingiverse.png 739w, https://dansanderson.com/mega65/exploring-hardware/nexys-case-thingiverse_hu_f3278c2cefb757da.png 600w, https://dansanderson.com/mega65/exploring-hardware/nexys-case-thingiverse_hu_d14f98cbc9f23d92.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/nexys-case-thingiverse.png&#34;
        alt=&#34;A 3D printed case design for the Nexys trainer board&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A 3D printed case design for the Nexys trainer board, rendered by Thingiverse
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;While you&amp;rsquo;re at it, whip up a 3D-printed case for the Nexys using &lt;a href=&#34;https://www.thingiverse.com/thing:4071990&#34;&gt;community-provided design files&lt;/a&gt;. I don&amp;rsquo;t have my own 3D printer, so I use 3D printing services like &lt;a href=&#34;https://www.shapeways.com/&#34;&gt;ShapeWays&lt;/a&gt;. It&amp;rsquo;s pretty amazing how we can send homemade design files for things like plastic shapes and circuit boards to fabrication services, and have them in our hands weeks later, for not much money.&lt;/p&gt;
&lt;p&gt;Because the Nexys board was the only way to develop for the MEGA65 project for so long, there are excellent set-up instructions in the &lt;a href=&#34;https://builder.mega65.org/job/mega65-user-guide/job/master/lastSuccessfulBuild/artifact/mega65-developer-guide.pdf&#34;&gt;Developer Guide&lt;/a&gt;. Also check out the article and video by RetroCombs: &lt;a href=&#34;https://retrocombs.com/mega65-nexys4&#34;&gt;Install the MEGA65 on a Nexys4 or A7 FPGA&lt;/a&gt; (2021).&lt;/p&gt;
&lt;h2 id=&#34;board-revisions&#34;&gt;Board revisions&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/devkit.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/devkit.jpg 960w, https://dansanderson.com/mega65/exploring-hardware/devkit_hu_483f19492dd5b170.jpg 600w, https://dansanderson.com/mega65/exploring-hardware/devkit_hu_1ea7c08255656c4c.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/devkit.jpg&#34;
        alt=&#34;The MEGA65 DevKit&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 DevKit
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Between the Nexys trainer board and the MEGA65, there were two revisions of the main board. It is occasionally useful to understand the board revision identifiers, especially when locating the firmware release for your computer.&lt;/p&gt;
&lt;p&gt;There were early main board designs known as &amp;ldquo;R1&amp;rdquo; and &amp;ldquo;R2.&amp;rdquo; These were not distributed, so you won&amp;rsquo;t see these in the wild.&lt;/p&gt;
&lt;p&gt;In the year 2020, the MEGA65 project produced and sold 100 &amp;ldquo;DevKit&amp;rdquo; units, with cases made from laser cut acrylic. The DevKit main board is revision &amp;ldquo;R3.&amp;rdquo; It has four slots for firmware cores, and includes eight megabytes of additional RAM (known as &amp;ldquo;attic RAM&amp;rdquo; or &amp;ldquo;HyperRAM&amp;rdquo;). DevKits came bundled with USB JTAG hardware for testing new cores and doing cross-development of software. You can only flash a new core to slot 0 of a DevKit using the Vivado software.&lt;/p&gt;
&lt;p&gt;The latest main board in today&amp;rsquo;s MEGA65 is known as revision &amp;ldquo;R3A.&amp;rdquo; The differences from the R3 board are minor: there are eight core slots instead of four, and there are some minor electrical changes. The R3A board can only be flashed by the &lt;code&gt;m65&lt;/code&gt; tool and not the Vivado software suite, but you can flash a new core to slot 0 without Vivado.&lt;/p&gt;
&lt;p&gt;From an architecture standpoint, the Nexys, R2, R3, and R3A boards only differ with regards to the Attic RAM: whether it&amp;rsquo;s present or absent, how much there is, and how fast it performs. The core and system software intend to continue supporting these differences, and software that uses Attic RAM can test for its presence to run cleanly on all boards.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll see these board revision identifiers in the names of the different versions of the MEGA65 Core Release Package on Filehost:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nexys4ddr-widget&lt;/code&gt; is the latest firmware for Nexys boards, with widget board support.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mega65r2&lt;/code&gt; is for the unreleased R2 board.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mega65r3&lt;/code&gt; is for the DevKit (R3) and retail (R3A) MEGA65. You probably want this one.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;peripherals&#34;&gt;Peripherals&lt;/h2&gt;
&lt;p&gt;The MEGA65 tries to be compatible with some vintage Commodore peripherals and their modern counterparts. Here&amp;rsquo;s a quick rundown of a few that I&amp;rsquo;ve tried. If you have your own experiences or recommendations, be sure to post them to the &lt;code&gt;#peripherals&lt;/code&gt; channel in the Discord.&lt;/p&gt;
&lt;h3 id=&#34;joysticks-gamepads-and-paddles&#34;&gt;Joysticks, gamepads, and paddles&lt;/h3&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/joysticks.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/joysticks.jpeg 1280w, https://dansanderson.com/mega65/exploring-hardware/joysticks_hu_e929c16938a4ff.jpeg 600w, https://dansanderson.com/mega65/exploring-hardware/joysticks_hu_91bb15b43942d28b.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/joysticks.jpeg&#34;
        alt=&#34;Modern retro joysticks. Clockwise from top left: generic Commodore 64 gamepad, Hyperkin Trooper, Hyperkin Ranger, ArcadeR.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Modern retro joysticks. Clockwise from top left: generic Commodore 64 gamepad, Hyperkin Trooper, Hyperkin Ranger, ArcadeR.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Vintage joysticks meant for Commodore and Atari computers work well with the MEGA65. They connect to the DE-9 ports on the left side of the computer.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like to use a Sega Genesis gamepad controller, be sure to use &lt;a href=&#34;https://retrorewind.ca/64-amiga-genesis-adapter&#34;&gt;a C64 Genesis adapter&lt;/a&gt;. Sega Genesis controllers use DE-9 connectors, but use different wiring that can damage a Commodore. It&amp;rsquo;s not obvious how much damage it might do to a MEGA65, but it&amp;rsquo;s mis-wired regardless and I&amp;rsquo;m not willing to try it to find out.&lt;/p&gt;
&lt;p&gt;I prefer &lt;a href=&#34;https://www.ebay.com/itm/264360844552&#34;&gt;a modern gamepad controller wired for the C64&lt;/a&gt;. They look and feel like Nintendo controllers, and they wire the second button to &amp;ldquo;up,&amp;rdquo; which is used to jump in platform games.&lt;/p&gt;
&lt;p&gt;For a modern joystick, I like the &lt;a href=&#34;https://retroradionics.co.uk/#!/ArcadeR-9-pin-ATARI-standard-Joystick/p/168982750/category=0&#34;&gt;ArcadeR&lt;/a&gt;. It puts an arcade-quality stick and buttons in a featureful, mod-able case, and has options like auto-fire and two-button support. Another option is the &lt;a href=&#34;https://www.amazon.com/Hyperkin-Trooper-Controller-not-machine-specific/dp/B07M5HYTZL&#34;&gt;Hyperkin Trooper&lt;/a&gt;, a good choice if you&amp;rsquo;re looking for the vintage shape without roughing up vintage equipment.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.amazon.com/Hyperkin-Premium-Gamepad-not-machine-specific/dp/B08227NQ3Z&#34;&gt;Hyperkin Ranger&lt;/a&gt; has a gamepad form factor, and also includes a single wheel for paddle games. Specifically for paddles, I recommend looking for vintage Atari paddles on eBay. They appear to be plentiful, inexpensive, and in good condition, at least for now.&lt;/p&gt;
&lt;h3 id=&#34;mice&#34;&gt;Mice&lt;/h3&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/mice.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/mice.jpeg 1280w, https://dansanderson.com/mega65/exploring-hardware/mice_hu_77e16e3e51cfdef.jpeg 600w, https://dansanderson.com/mega65/exploring-hardware/mice_hu_ed8192998eaaeb07.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/mice.jpeg&#34;
        alt=&#34;A vintage Commodore 1351 mouse, and a mouSTer USB mouse converter with a modern wireless Logitech M185.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A vintage Commodore 1351 mouse, and a mouSTer USB mouse converter with a modern wireless Logitech M185.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 supports the Commodore 1351 mouse, the Amiga mouse, and anything that can act like either of these. The 1351 tends to be more reliable.&lt;/p&gt;
&lt;p&gt;The MEGA65 must be configured to recognize either the 1351 or the Amiga mouse. Hold the Alt key while turning on your MEGA65 to start the Configuration tool, then set each port to the desired mouse type under the &amp;ldquo;Input&amp;rdquo; tab. Connecting an Amiga mouse while in 1351 mode may interfere with the behavior of the keyboard, so if you&amp;rsquo;re having difficulty, just unplug the mouse and check your settings.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://retrohax.net/shop/amiga/mouster/&#34;&gt;mouSTer&lt;/a&gt; is a clever modern device that lets you connect a USB mouse to a DE-9 Commodore port. It&amp;rsquo;s quite versatile, and you can set a variety of options by connecting a USB drive containing a config file. The mouSTer can be configured to emulate either a 1351 or an Amiga mouse, so make sure it matches your MEGA65&amp;rsquo;s settings. I use my mouSTer with an inexpensive &lt;a href=&#34;https://www.amazon.com/Logitech-M185-Swift-Wireless-Mouse/dp/B00O3TIZXS/&#34;&gt;Logitech M185 wireless mouse&lt;/a&gt;. If I&amp;rsquo;m not desperate for the Commodore tank mouse look and feel, I prefer my Logitech.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m looking forward to trying modern retro mice recreations like the &lt;a href=&#34;https://www.kickstarter.com/projects/lukas-remis/tank-mouse-your-new-amiga-mouse&#34;&gt;Tank Mouse&lt;/a&gt; when I get one.&lt;/p&gt;
&lt;h3 id=&#34;other-peripherals&#34;&gt;Other peripherals&lt;/h3&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/jtag_miniusb_mount_installed.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/jtag_miniusb_mount_installed.jpeg 640w, https://dansanderson.com/mega65/exploring-hardware/jtag_miniusb_mount_installed_hu_9205b98eadfe1af6.jpeg 600w, https://dansanderson.com/mega65/exploring-hardware/jtag_miniusb_mount_installed_hu_103db025530ed100.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/jtag_miniusb_mount_installed.jpeg&#34;
        alt=&#34;My FTDI JTAG adapter, installed with a mini-USB panel mount&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
My FTDI JTAG adapter, installed with a mini-USB panel mount
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 has an IEC serial port, most often used on Commodores with external disk drives. You can use a vintage external 1581 drive with the MEGA65 in C65 mode. Other IEC devices don&amp;rsquo;t work so well with C65 mode at the moment due to known timing issues inherited from the Commodore 65 ROM. C64 mode (type &lt;code&gt;GO64&lt;/code&gt;) does better in some cases. I was able to get my Blue Chip D12 daisy wheel serial printer to work in C64 mode. Improving IEC device support in C65 mode is on the to-do list for the ROM.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://dansanderson.com/mega65/welcome/using-jtag.html&#34;&gt;FTDI JTAG adapter&lt;/a&gt; is a peripheral that mounts to the primary JTAG port on the main board. With your PC connected to it with a mini-USB cable, you can install bitstreams, send programs, transfer files, and debug issues. If you don&amp;rsquo;t need to install bitstreams, you can use a cheaper and easier-to-find USB serial device connected to the UART pins of the JTAG connector. USB serial communication is &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/&#34;&gt;great for cross-development and debugging&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Work is in progress to make it possible to transfer files and programs, and perform other cross-development tasks like debugging, using the MEGA65&amp;rsquo;s ethernet port, with no need for a separate adapter. If you&amp;rsquo;re interested in helping test this feature, inquire on the Discord. There&amp;rsquo;s a test core and new versions of &lt;a href=&#34;https://github.com/mega65/mega65-tools&#34;&gt;the command-line tools&lt;/a&gt; that demonstrate this capability.&lt;/p&gt;
&lt;p&gt;To round out this discussion of peripherals, we might as well mention the &lt;a href=&#34;https://files.mega65.org?ar=ff484da0-d942-4e9b-adf1-3b5a77acaa25&#34;&gt;Real-Time Clock replacement&lt;/a&gt;. This is a peripheral that uses the Grove connector on the main board. The replacement RTC was our workaround solution for the small percentage MEGA65s that shipped with faulty real-time clock chips. The latest firmware detects when the replacement RTC is connected and communicates with it over the Grove connector.&lt;/p&gt;
&lt;h2 id=&#34;pauls-prototypes&#34;&gt;Paul&amp;rsquo;s prototypes&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/mpryon_nexys.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/mpryon_nexys.jpg 4080w, https://dansanderson.com/mega65/exploring-hardware/mpryon_nexys_hu_4328e46afce9f75b.jpg 600w, https://dansanderson.com/mega65/exploring-hardware/mpryon_nexys_hu_e63bcb0bd2009ab9.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/mpryon_nexys.jpg&#34;
        alt=&#34;MEGA65 Nexys A7 build with DIY keyboard, by mpryon&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGA65 Nexys A7 build with DIY keyboard, by mpryon
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One of the biggest hardware challenges for the MEGA65 project is the limited availability of FPGA chips. Trenz Electronic can only acquire so many of the FPGAs at time, which limits their ability to build and deliver computers. Even the price of a Nexys trainer board has gone up $80 in the last year. We all hope this shortage is temporary, but it may be a few years before we see supply return to previous levels.&lt;/p&gt;
&lt;p&gt;MEGA65 founder and hardware designer Paul Gardner-Stephen is experimenting with a prototype for a lower cost keyboard that doesn&amp;rsquo;t need its own FPGA. The &amp;ldquo;DIY keyboard&amp;rdquo; project intends to be a drop-in replacement for the current MEGA65 keyboard, using the same Cherry MX switches and keycaps, and fitting perfectly in its case with no noticeable difference to the user. It can also be a standalone C65 keyboard for the Nexys board, connected to a PMOD port. You can use the open hardware design files to send away for a bare board, and install your own switches and keycaps. As pictured above, MEGA65 owner mpryon completed his Nexys rig with a DIY keyboard based on Paul&amp;rsquo;s prototype design.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s too early to say whether the DIY keyboard will become a more polished product for sale. It&amp;rsquo;s easy to imagine it being sold as a kit with a set of official MEGA65 keycaps, or adapted via microcontroller to be a USB keyboard with a C65 layout for use with the Xemu emulator. You can follow Paul&amp;rsquo;s progress on the DIY keyboard on his developer blog: &lt;a href=&#34;https://c65gs.blogspot.com/2022/10/mega65-mk-ii-keyboard-pcb-design.html&#34;&gt;October 2022&lt;/a&gt;, &lt;a href=&#34;https://c65gs.blogspot.com/2022/11/progress-on-diy-keyboard.html&#34;&gt;November 2022&lt;/a&gt;, &lt;a href=&#34;https://c65gs.blogspot.com/2022/12/diy-keyboard-revb-works.html&#34;&gt;December 2022&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/mega65-r3-expansion-board.front.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/mega65-r3-expansion-board.front.png 1302w, https://dansanderson.com/mega65/exploring-hardware/mega65-r3-expansion-board.front_hu_b00d9366a4be7ad7.png 600w, https://dansanderson.com/mega65/exploring-hardware/mega65-r3-expansion-board.front_hu_27a7423a4744ec06.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/mega65-r3-expansion-board.front.png&#34;
        alt=&#34;Design render for a MEGA65 port expansion board, by Paul Gardner-Stephen&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Design render for a MEGA65 port expansion board, by Paul Gardner-Stephen
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Paul is also working on a prototype for a port expansion board that adds component video output, a Commodore user port, a tape port, and a port for the unreleased C1565 external floppy disk drive. The board would mount inside the MEGA65, and place the new ports through the punch-outs already prepared in the back of the plastic case.&lt;/p&gt;
&lt;p&gt;Why add a port for an unreleased Commodore peripheral? So you can recreate the peripheral, of course! It&amp;rsquo;s just an idea for now, but the 8-pin mini-DIN connector for the C1565 external floppy drive could support an actual vintage prototype drive, or an all-new project to recreate the drive with a case that matches the MEGA65. At the very least, the port would make the MEGA65 more authentic, matching the similar port on the Commodore 65.&lt;/p&gt;
&lt;p&gt;As with the DIY keyboard, there are not yet plans to produce the expansion board in quantity. You may be able to make your own from open designs at some point. Paul is also dev-blogging progress on the expansion board: &lt;a href=&#34;https://c65gs.blogspot.com/2022/10/lets-start-doing-something-about-those.html&#34;&gt;October 2022&lt;/a&gt;, &lt;a href=&#34;https://c65gs.blogspot.com/2023/01/working-on-composite-video-output-for.html&#34;&gt;January 1, 2023&lt;/a&gt;, &lt;a href=&#34;https://c65gs.blogspot.com/2023/01/adding-colour-to-mega65s-composite.html&#34;&gt;January 6, 2023&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/exploring-hardware/megaphone_proto.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/exploring-hardware/megaphone_proto.jpg 4160w, https://dansanderson.com/mega65/exploring-hardware/megaphone_proto_hu_fa974704880f2e90.jpg 600w, https://dansanderson.com/mega65/exploring-hardware/megaphone_proto_hu_63eeff34e1ed685.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/exploring-hardware/megaphone_proto.jpg&#34;
        alt=&#34;A prototype of the MEGAphone, a mobile telephony device based on the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A prototype of the MEGAphone, a mobile telephony device based on the MEGA65
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For several years, the MEGA65 website advertised not only an upcoming reproduction of the Commodore 65, but also a mobile phone based on the same technology. Today, the website focuses on the first project, which, obviously, is now in full swing and in the hands of hundreds of happy owners. Is the mobile phone project still a thing?&lt;/p&gt;
&lt;p&gt;Let this be a lesson: never bet against a project with strong principles. The MEGAphone is still in active development, and making good progress. With a grant from &lt;a href=&#34;https://nlnet.nl/project/Mega65/&#34;&gt;the NLNet Foundation&lt;/a&gt;, the MEGAphone seeks to reclaim one of the most important technological spaces in the daily lives of billions of people.&lt;/p&gt;
&lt;p&gt;The idea is this: The sheer complexity of modern computers alienates us from the technology upon which our digital lives depend. It&amp;rsquo;s not enough for a smartphone operating system to be open source in theory, as Android claims to be. To achieve the benefits of this transparency—security, privacy, control in the hands of the user—the technology has to be strictly modular, and simple enough for a computer hobbyist to understand. The Commodore 65 is one of the last practical computers to fit this description. What if there were a smartphone based on the Commodore 65?&lt;/p&gt;
&lt;p&gt;The MEGAphone is a proof-of-concept portable device with mobile telephony, Internet, and a touch screen interface. It uses the MEGA65 core and ROM, and can run MEGA65 software, including software written by the phone&amp;rsquo;s owner. Everything is open source, and any owner can replace any component on their phone as easily as they can on the MEGA65.&lt;/p&gt;
&lt;p&gt;To learn more about the project&amp;rsquo;s goals, watch video of Paul&amp;rsquo;s 2019 talk, &lt;a href=&#34;https://media.ccc.de/v/36c3-10800-creating_resilient_and_sustainable_mobile_phones&#34;&gt;Creating Resilient and Sustainable Mobile Phones&lt;/a&gt;. For a glimpse of recent progress, see his recent dev-blog entries about the MEGAphone: &lt;a href=&#34;https://c65gs.blogspot.com/2022/09/megaphone-r4-pcb-bring-up-part-1.html&#34;&gt;September 7, 2022&lt;/a&gt;, &lt;a href=&#34;https://c65gs.blogspot.com/2022/09/megaphone-r4-pcb-bring-up-part-2.html&#34;&gt;September 14, 2022&lt;/a&gt;, &lt;a href=&#34;https://c65gs.blogspot.com/2022/09/megaphone-r4-pcb-bring-up-part-3.html&#34;&gt;September 20, 2022&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The MEGA65 hardware released in 2022 is a huge milestone for the project and for vintage computer preservation in general, the culmination of nine years of work to realize the vision of Commodore&amp;rsquo;s designers and engineers with modern components and techniques. The result is a multi-layered hobbyist platform that will continue to see revisions, adaptations, and expansions into the future.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like more information on any of these projects, or if you discover something interesting or build something cool, be sure to let the community know in the Discord.&lt;/p&gt;
&lt;p&gt;Until next time!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/exploring-hardware/M65Digest_2023Jan.mp3" length="27485434" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1374</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/exploring-hardware/nexysa7.jpg"/>
      
    </item>
    
    <item>
      <title>Back to BASICs</title>
      <link>https://dansanderson.com/mega65/back-to-basics/</link>
      <pubDate>Fri, 23 Dec 2022 12:09:22 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/back-to-basics/</guid>
      <description>&lt;p&gt;Back to BASICs. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for December 2022.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Back to BASICs. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for December 2022.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/back-to-basics/M65Digest_2022Dec.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/M65Digest_2022Dec.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Back to BASICs.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/image1.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/back-to-basics/image1.jpg 1086w, https://dansanderson.com/mega65/back-to-basics/image1_hu_7d3bb9e3d106f4d4.jpg 600w, https://dansanderson.com/mega65/back-to-basics/image1_hu_2e8eb95bcb8d0c4b.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/back-to-basics/image1.jpg&#34;
        alt=&#34;MEGA65 at the READY. prompt&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGA65 at the READY.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One of the most satisfying things you can do with a vintage computer is to turn it on and start writing a program. With nothing but your curiosity, a little persistence, and maybe a book and a pad of scratch paper, you can craft a program that solves a problem, performs a task, produces a work of art, tells a story, or generates an interactive experience.&lt;/p&gt;
&lt;p&gt;In this Digest, we&amp;rsquo;ll look at a few ways to get starting writing programs for the MEGA65 using the built-in BASIC 65 programming language. This won&amp;rsquo;t be a BASIC tutorial—there are &lt;a href=&#34;https://archive.org/search.php?query=commodore+basic&#34;&gt;hundreds of vintage books on that subject&lt;/a&gt;, and you already have the &lt;a href=&#34;https://files.mega65.org/manuals-upload/mega65-userguide.pdf&#34;&gt;MEGA65 User&amp;rsquo;s Guide&lt;/a&gt;. There are additional chapters for beginners in the &lt;a href=&#34;https://files.mega65.org/manuals-upload/mega65-book.pdf&#34;&gt;MEGA65 Complete Compendium&lt;/a&gt;. Instead, we’ll focus on several ways to create and run BASIC programs with your MEGA65, and with your PC.&lt;/p&gt;
&lt;p&gt;But first!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;batch-2-shipments-have-begun&#34;&gt;Batch 2 shipments have begun!&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.trenz-electronic.de/en/News/It-s-shipping-time-MEGA65-Batch-2-shipping&#34;&gt;Trenz Electronic has announced&lt;/a&gt; that batch 2 shipping has begun, and some have already received their MEGAs! The next 400 recipients should receive shipping notices in the next few weeks, followed soon after by receipt of your very own MEGA65.&lt;/p&gt;
&lt;p&gt;Batch #3 is expected to deliver in the third quarter (July-September) of 2023. It&amp;rsquo;s too early to say how many units will ship in the next batch. Here&amp;rsquo;s hoping that FPGA supply will be flowing more freely next year.&lt;/p&gt;
&lt;h2 id=&#34;has-your-shipping-address-changed&#34;&gt;Has your shipping address changed?&lt;/h2&gt;
&lt;p&gt;For those of us awaiting delivery of a pre-ordered MEGA65: If your shipping address has changed since you placed the pre-order, send an email to: &lt;a href=&#34;mailto:sales@trenz-electronic.de&#34;&gt;sales@trenz-electronic.de&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Changing the shipping address in your Trenz Electronic website account settings will &lt;em&gt;not&lt;/em&gt; update shipping addresses on pending orders. You must send them email to update the address on a pre-order.&lt;/p&gt;
&lt;p&gt;I know many of us have been waiting a long time for our MEGA65s. If your address needs updating, take care of it soon to ensure smooth delivery.&lt;/p&gt;
&lt;h2 id=&#34;digest-feeds&#34;&gt;Digest feeds&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;re probably reading this Digest delivered as email via Substack. If you clicked through to the audio version with the play icon at the top of the email, you&amp;rsquo;re probably listening to it using a web browser on your desktop computer, tablet, or smartphone. You can read past and current issues, as well as manage your email subscription, on my website: &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;dansanderson.com/mega65/&lt;/a&gt; Substack has a phone app, and it includes a built-in audio player.&lt;/p&gt;
&lt;p&gt;Alternatively, you can follow the Digest using your favorite feed reader. You can usually just copy the website address into your feed reader to subscribe. If your reader needs the exact feed URL, it&amp;rsquo;s just this: &lt;a href=&#34;https://dansanderson.com/mega65/index.xml&#34;&gt;dansanderson.com/mega65/index.xml&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m pleased to announce that the audio version of the Digest is now available in your podcast player! Search for &amp;ldquo;Dan&amp;rsquo;s MEGA65 Digest&amp;rdquo; in &lt;a href=&#34;https://podcasts.apple.com/us/podcast/dans-mega65-digest-podcast/id1656654132&#34;&gt;Apple Podcasts&lt;/a&gt; or the Pocket Casts directory. Some (but not all) podcast players can subscribe directly to the website feed as if it&amp;rsquo;s a podcast.&lt;/p&gt;
&lt;p&gt;Regardless of how you follow the Digest, thanks for being here!&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;entering-commands-and-programs&#34;&gt;Entering commands and programs&lt;/h2&gt;
&lt;p&gt;Like the Commodores that precede it, the MEGA65 starts up with a blinking cursor at the &lt;code&gt;READY.&lt;/code&gt; prompt. You can enter a command by typing the name of the command followed by arguments, and execute the command immediately by pressing the &lt;kbd&gt;Return&lt;/kbd&gt; key. For example, here&amp;rsquo;s a command to turn the color of the screen border to black:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BORDER 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use the same blinking cursor to write a program, a collection of commands on numbered lines. If you type the &lt;code&gt;BORDER&lt;/code&gt; command after a line number then press &lt;kbd&gt;Return&lt;/kbd&gt;, it does not change the border color, but instead stores the command to be run as part of the program.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 BORDER 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&amp;rsquo;s a short program that prompts for a temperature in degrees Fahrenheit, then displays the equivalent temperature in degrees Celsius. Try typing these lines into your MEGA65:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 PRINT &amp;#34;ENTER A TEMPERATURE IN DEGREES FAHRENHEIT:&amp;#34;
110 INPUT F
120 C=(F-32)*5/9
130 PRINT
140 PRINT F;&amp;#34; DEGREES FAHRENHEIT IS &amp;#34;;C;&amp;#34; DEGREES CELSIUS.&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&amp;rsquo;ve written a program on a Commodore before, this should feel familiar. The BASIC screen editor allows you to type whatever you want anywhere on the screen. When you press &lt;kbd&gt;Return&lt;/kbd&gt;, it checks whether the line with the cursor on it begins with a line number, and if so, it stores the contents of that line in BASIC program memory. If there&amp;rsquo;s already a line in memory with that line number, BASIC replaces the old line with the new one.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important to remember that what&amp;rsquo;s on the screen does not necessarily represent the program stored in memory. You can think of the screen as a sort of scratch pad on which you can type whatever you like. Only when you press &lt;kbd&gt;Return&lt;/kbd&gt; on a line will BASIC try to do something with what you typed.&lt;/p&gt;
&lt;p&gt;To see the lines of the actual program stored in memory, use the &lt;code&gt;LIST&lt;/code&gt; command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LIST&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you notice a mistake or something you&amp;rsquo;d like to change, you can move the cursor up to the line displayed on the screen, type new text over the old text, then press &lt;kbd&gt;Return&lt;/kbd&gt; to replace the line in memory.&lt;/p&gt;
&lt;p&gt;BASIC keeps the program in line number order, but you can enter the lines in any order you like. This is handy for inserting a line between two other lines: pick a number between the numbers of the existing lines, and enter the new line with that number. This is why BASIC programmers tend to number their lines by tens (10, 20, 30&amp;hellip;), to make it easy to insert a line in the middle of the program (15).&lt;/p&gt;
&lt;p&gt;To delete a line, enter the line number with no text after it. To delete a range of numbered lines, use the &lt;code&gt;DELETE&lt;/code&gt; command followed by the range:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DELETE 1000-1500&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To erase the entire program from memory, use the &lt;code&gt;NEW&lt;/code&gt; command. If you do this accidentally and want to bring the deleted program back, don&amp;rsquo;t panic, just type: &lt;code&gt;NEW RESTORE&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;saving-programs-to-disk&#34;&gt;Saving programs to disk&lt;/h2&gt;
&lt;p&gt;Your program is in the computer&amp;rsquo;s memory, but it is not saved to permanent storage automatically. (Maybe that&amp;rsquo;s obvious in the context of vintage computers, but we get accustomed to modern conveniences sometimes.) If you turned off the MEGA65 now, the program would be forgotten.&lt;/p&gt;
&lt;p&gt;Hopefully by now you&amp;rsquo;ve had a chance to mount a D81 disk image and load a program from it. You can also use the Freeze menu to create an empty disk image on your SD card. Try this now: hold &lt;kbd&gt;Restore&lt;/kbd&gt; for a second then release to open the Freeze menu. Press &lt;kbd&gt;0&lt;/kbd&gt; to mount a disk to device 0 (unit 8). At the top of the list of disk images is the option to create a &amp;ldquo;NEW D81 DD IMAGE.&amp;rdquo; Select this, then give the disk a name. I like to call my work disks &amp;ldquo;WORK&amp;rdquo; to make it seem like I&amp;rsquo;m doing something important.&lt;/p&gt;
&lt;p&gt;The new disk image is now mounted. Press &lt;kbd&gt;F3&lt;/kbd&gt; to resume to BASIC. (Be careful not to press &lt;kbd&gt;F5&lt;/kbd&gt; to reset if you have a program in memory!)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/freeze-newd81.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/back-to-basics/freeze-newd81.png 720w, https://dansanderson.com/mega65/back-to-basics/freeze-newd81_hu_719506442d39e02b.png 600w, https://dansanderson.com/mega65/back-to-basics/freeze-newd81_hu_24024d3637da1064.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/back-to-basics/freeze-newd81.png&#34;
        alt=&#34;The Freeze menu, with NEW D81 DD IMAGE selected&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Freeze menu, with NEW D81 DD IMAGE selected
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;With a BASIC program in memory, save it to your disk with the &lt;code&gt;DSAVE&lt;/code&gt; command. Put the filename in double-quotes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DSAVE &amp;#34;TEMPCONV&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Confirm that your program is on the disk by listing the disk directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DIR&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As written, the &lt;code&gt;DSAVE&lt;/code&gt; command will fail if there is already a file with that name on the disk. It&amp;rsquo;s a common practice to save your work periodically with different filenames suffixed with increasing numbers, so you can revert back to an older version if necessary. (Commodores don&amp;rsquo;t have built-in revision control systems!) Over a few days, you might end up with &lt;code&gt;&amp;quot;TEMPCONV2&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;TEMPCONV3&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;TEMPCONV17&amp;quot;&lt;/code&gt; on your disk, until you&amp;rsquo;ve decided which version is the final version.&lt;/p&gt;
&lt;p&gt;Alternatively, you can live dangerously and overwrite the same file each time you save. To do this, prepend the filename with an &amp;ldquo;at&amp;rdquo; symbol (&lt;code&gt;@&lt;/code&gt;). (The symbol is not considered part of the filename.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DSAVE &amp;#34;@TEMPCONV&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can now turn off your MEGA65. The next time you turn it on, you can use the &lt;code&gt;MOUNT&lt;/code&gt; command with your work disk name followed by &lt;code&gt;.D81&lt;/code&gt; to mount it, then the &lt;code&gt;DLOAD&lt;/code&gt; command to load your program back into memory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MOUNT &amp;#34;WORK.D81&amp;#34;
DLOAD &amp;#34;TEMPCONV&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;listing-long-programs&#34;&gt;Listing long programs&lt;/h2&gt;
&lt;p&gt;Eventually your program will be many lines long. The &lt;code&gt;LIST&lt;/code&gt; command will try to list your entire program, and only the bottommost 25 rows will be on the screen at the end. How can we navigate a long program listing?&lt;/p&gt;
&lt;p&gt;(If you want to experiment with this without writing a long program, &lt;code&gt;MOUNT &amp;quot;MEGA65.D81&amp;quot;&lt;/code&gt; then &lt;code&gt;DLOAD &amp;quot;AUTOBOOT.C65&amp;quot;&lt;/code&gt; to load the demo disk&amp;rsquo;s menu program, which is written in BASIC. If you disabled opening the menu on start-up, this file has been renamed: use &lt;code&gt;DLOAD &amp;quot;MENU&amp;quot;&lt;/code&gt; instead.)&lt;/p&gt;
&lt;p&gt;As with previous Commodore BASICs, the &lt;code&gt;LIST&lt;/code&gt; command accepts a range of line numbers. This is a slightly cumbersome but precise way to look at a few lines at a time, if you know their numbers.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LIST 100-300   : rem List lines 100 through 300
LIST -300      : rem List all lines up to 300
LIST 1000-     : rem List all lines starting from 1000
LIST 250       : rem List only line 250&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When listing many lines, you can tap the &lt;kbd&gt;No Scroll&lt;/kbd&gt; key to pause the listing. You can press &lt;kbd&gt;Run Stop&lt;/kbd&gt; to terminate a paused listing, or &lt;kbd&gt;No Scroll&lt;/kbd&gt; again to resume. The MEGA65 is so fast in its default 40 MHz mode that this isn&amp;rsquo;t a practical way to peruse a listing. You could use the &lt;code&gt;SPEED 1&lt;/code&gt; command to set it to 1 MHz and slow it down, but be warned: &lt;a href=&#34;https://github.com/MEGA65/mega65-rom-public/issues/25&#34;&gt;there&amp;rsquo;s a bug&lt;/a&gt; where the MEGA65 &lt;em&gt;crashes&lt;/em&gt; when you &lt;kbd&gt;Run Stop&lt;/kbd&gt; in slow mode! I don&amp;rsquo;t recommend this method at all for this reason—but I mention it because it&amp;rsquo;s interesting.&lt;/p&gt;
&lt;p&gt;The MEGA65 &lt;code&gt;LIST&lt;/code&gt; command has an option to display a program listing one screenful at a time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LIST P

LIST P 100-300&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Press a key at each page to advance to the next one, or press &lt;kbd&gt;Run Stop&lt;/kbd&gt; to abort at the current page.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/list-p.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/back-to-basics/list-p.png 720w, https://dansanderson.com/mega65/back-to-basics/list-p_hu_83fa968e6101d9be.png 600w, https://dansanderson.com/mega65/back-to-basics/list-p_hu_c4270cd55e1b2fd0.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/back-to-basics/list-p.png&#34;
        alt=&#34;The LIST P command shows one page at a time&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The LIST P command shows one page at a time.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There&amp;rsquo;s a third method to browse long listings, and it&amp;rsquo;s my favorite: press &lt;kbd&gt;F9&lt;/kbd&gt; and &lt;kbd&gt;F11&lt;/kbd&gt; to scroll down and up by a line. (If you&amp;rsquo;ve redefined your function keys, you can use &lt;kbd&gt;Ctrl-P&lt;/kbd&gt; and &lt;kbd&gt;Ctrl-V&lt;/kbd&gt; instead.) I like this method because the screen editor remains active, so you can start typing inside the listing as soon as you see what you want to change. Notice that the screen does &lt;em&gt;not&lt;/em&gt; have a modern-style scrollback buffer, even though it seems like it does: it&amp;rsquo;s actually reading lines from BASIC memory to fill in the scrolling display.&lt;/p&gt;
&lt;p&gt;With lots of text on the screen, remember that you can get new blank lines to type on by running the cursor off the bottom of the screen, or pressing &lt;kbd&gt;Shift + Clr Home&lt;/kbd&gt; to clear the screen entirely. You can also clear just from the cursor’s line to the bottom of the screen by pressing the &lt;kbd&gt;ESC&lt;/kbd&gt; key followed by the &lt;kbd&gt;@&lt;/kbd&gt; key.&lt;/p&gt;
&lt;h2 id=&#34;the-eleven-programming-environment&#34;&gt;The Eleven programming environment&lt;/h2&gt;
&lt;p&gt;The BASIC 65 screen editor is thoroughly retro and thoroughly Commodore, and it picked up some nice features along the way from the Commodore 128, Commodore 65, and a few added by the MEGA65 team. But perhaps you want a coding environment that&amp;rsquo;s a bit more modern—without leaving your MEGA65.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=8b189d0b-ea1e-45a7-a4de-87bcb0b11696&#34;&gt;The Eleven programming environment&lt;/a&gt;, by Stephen Kleinert (username ubik), reinvents the BASIC 65 editing experience. It provides a modern-style code editor and extensions to the BASIC 65 language to make it easier to use for large projects. It dispenses with line numbers, and instead uses labels for flow control (such as &lt;code&gt;goto&lt;/code&gt; statements). Variable names can be longer than two characters, and preprocessor directives allow for efficient definition of constants without taking up variable space.&lt;/p&gt;
&lt;p&gt;The brilliant part is that Eleven compiles your program into plain BASIC 65 code. It generates line numbers, replaces labels, renames variables, strips comments, and minifies syntax. The result is a compact BASIC 65 program that you can save to disk and give to your friends, with no bulky runtime library or other baggage. BASIC 65 is a powerful enough language; Eleven just adds modern documentation and editing conveniences, making BASIC programs easier to write and maintain.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/eleven-dizzy.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/back-to-basics/eleven-dizzy.png 720w, https://dansanderson.com/mega65/back-to-basics/eleven-dizzy_hu_7fe8e98a19d16465.png 600w, https://dansanderson.com/mega65/back-to-basics/eleven-dizzy_hu_b2a95b8698de5350.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/back-to-basics/eleven-dizzy.png&#34;
        alt=&#34;The Eleven editor, with the sample program dizzy.el&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Eleven editor, with the sample program dizzy.el
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A copy of Eleven was included on your SD card, and you can &lt;a href=&#34;https://files.mega65.org?id=8b189d0b-ea1e-45a7-a4de-87bcb0b11696&#34;&gt;download the latest version&lt;/a&gt; from Filehost. Here&amp;rsquo;s how to give it a try:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;MOUNT &amp;quot;ELEVEN.D81&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BOOT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Enjoy reading the documentation directly in the editor. Use cursor keys to scroll.&lt;/li&gt;
&lt;li&gt;Press &lt;kbd&gt;F1&lt;/kbd&gt; to load a program.&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;dizzy.el&lt;/code&gt; and press &lt;kbd&gt;Return&lt;/kbd&gt;. Scroll through the program listing to see how it works.&lt;/li&gt;
&lt;li&gt;Press &lt;kbd&gt;F5&lt;/kbd&gt; to compile. The program compiles and starts running. Press any key to exit to the &lt;code&gt;READY.&lt;/code&gt; prompt.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LIST&lt;/code&gt; to see the compiled BASIC 65 program.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BOOT&lt;/code&gt; to return to the Eleven editor, with the last-saved project loaded.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Eleven will insist that you save your changes before compiling, so you won&amp;rsquo;t lose anything if your program crashes the machine.&lt;/p&gt;
&lt;p&gt;Stephen has &lt;a href=&#34;https://github.com/MEGA65/eleven&#34;&gt;released Eleven to the MEGA65 project&lt;/a&gt; with an open source license. There may be on-going improvements in the future.&lt;/p&gt;
&lt;h2 id=&#34;writing-basic-65-programs-on-your-pc&#34;&gt;Writing BASIC 65 programs on your PC&lt;/h2&gt;
&lt;p&gt;Coding directly on the MEGA65 with the printed User&amp;rsquo;s Guide at your side is a cozy, comfortable experience, free of Internet-y distractions. But sometimes—just sometimes—I want to use modern tools to develop retro software, even if I&amp;rsquo;m writing in BASIC.&lt;/p&gt;
&lt;p&gt;Full disclosure: I&amp;rsquo;m a developer tools nerd. I like storing text source files in a &lt;a href=&#34;https://git-scm.com/&#34;&gt;Git&lt;/a&gt; repository, running things through multiple levels of processing, and automating it all together with &lt;a href=&#34;https://www.gnu.org/software/make/&#34;&gt;Makefiles&lt;/a&gt;. One of my favorite ways to write MEGA65 BASIC is on my PC.&lt;/p&gt;
&lt;p&gt;I use a command-line tool called &lt;a href=&#34;https://vice-emu.sourceforge.io/vice_16.html&#34;&gt;petcat&lt;/a&gt; that converts a text file containing BASIC code into a PRG file that I can run on my MEGA65 or in the &lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;Xemu MEGA65 emulator&lt;/a&gt;. petcat comes with the &lt;a href=&#34;https://vice-emu.sourceforge.io/&#34;&gt;VICE Commodore emulator suite&lt;/a&gt;, which I have installed for all of my non-MEGA65 Commodore projects. VICE doesn&amp;rsquo;t provide a MEGA65 emulator (that&amp;rsquo;s what Xemu is for), but petcat does know about BASIC 65 commands.&lt;/p&gt;
&lt;p&gt;That temperature conversion program looks like this in a petcat text file, literally the same text but in lowercase:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 print &amp;#34;enter a temperature in degrees fahrenheit:&amp;#34;
110 input f
120 c=(f-32)*5/9
130 print
140 print f;&amp;#34; degrees fahrenheit is &amp;#34;;c;&amp;#34; degrees celsius.&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To convert this to a MEGA65 PRG file, use this shell command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;petcat -w65 -o tempconv.prg -- tempconv.bas&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can test the PRG file in Xemu by dragging it into a running Xemu window, or by starting Xemu with appropriate command-line options. If you happen to have a &lt;a href=&#34;https://dansanderson.com/mega65/welcome/using-jtag.html&#34;&gt;JTAG USB adapter&lt;/a&gt;, you can beam this PRG file directly to your MEGA65 with the &lt;a href=&#34;https://github.com/MEGA65/mega65-tools/releases/tag/CI-latest&#34;&gt;m65 command-line tool&lt;/a&gt; or with the M65Connect app (search for &amp;ldquo;M65Connect&amp;rdquo; on &lt;a href=&#34;https://files.mega65.org/html/main.php&#34;&gt;Filehost&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&#34;petcat-labels&#34;&gt;petcat labels&lt;/h2&gt;
&lt;p&gt;You might notice that a text file on a PC doesn&amp;rsquo;t seem to be capable of representing everything that might go in a BASIC program. For example, there are characters on the MEGA65 keyboard that are not present on a PC keyboard, like the Up Arrow symbol. How would a petcat program print the graphical glyphs on the front of the keys, like the heart shape on the &lt;kbd&gt;S&lt;/kbd&gt;? What about the PETSCII control codes, like &lt;kbd&gt;Ctrl-3&lt;/kbd&gt; that changes the print color to red?&lt;/p&gt;
&lt;p&gt;petcat represents as many characters as it can with ASCII equivalents. All of the right-hand glyphs that you access by holding &lt;kbd&gt;Shift&lt;/kbd&gt; and pressing a letter are simply the capital letters. The PETSCII symbols for pound, Up Arrow, Back Arrow, and pi are represented by ASCII characters with the same encoded value: &lt;code&gt;\&lt;/code&gt;, &lt;code&gt;^&lt;/code&gt;, &lt;code&gt;_&lt;/code&gt;, and &lt;code&gt;~&lt;/code&gt;, respectively.&lt;/p&gt;
&lt;p&gt;Nearly everything else appears in a petcat listing as a label inside curly brackets, such as &lt;code&gt;{red}&lt;/code&gt; for &lt;kbd&gt;Ctrl-3&lt;/kbd&gt;. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 print &amp;#34;{clr}{red}SSS {wht}mega65 {red}SSS{wht}&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The left-hand glyphs that you access by holding &lt;kbd&gt;Ctrl&lt;/kbd&gt; and pressing a letter are labels like &lt;code&gt;{CTRL-A}&lt;/code&gt;. A few codes that are typed with the &lt;kbd&gt;Mega&lt;/kbd&gt; key look like &lt;code&gt;{CBM-@}&lt;/code&gt;. Other PETSCII control sequences have named labels like &lt;code&gt;{clr}&lt;/code&gt; or &lt;code&gt;{stop}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I won&amp;rsquo;t clutter this Digest with a complete list. I&amp;rsquo;ll just say that petcat also knows how to convert a PRG file back into text. If you&amp;rsquo;re unsure of what label to use for a character or control code, you can create a small program with the character in it using the MEGA65 or Xemu, then run petcat in reverse to see what it looks like.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;petcat -65 -o myprog.bas -- myprog.prg&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;cbm-prg-studio-4&#34;&gt;CBM PRG Studio 4&lt;/h2&gt;
&lt;p&gt;If your PC runs Windows, there&amp;rsquo;s a compelling new option for MEGA65 cross development. &lt;a href=&#34;https://www.ajordison.co.uk/download.html&#34;&gt;CBM PRG Studio&lt;/a&gt; is a much loved integrated development environment for writing programs for Commodore computers. Starting with version 4.0, it includes support for the MEGA65.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t normally use windows, so I&amp;rsquo;m not deeply familiar with CBM PRG Studio&amp;rsquo;s features. But it took me no time at all to figure out how to use it to write a MEGA65 BASIC program and build the PRG file. It looks like a compelling IDE for &lt;a href=&#34;http://theweb.dk/KickAssembler/Main.html#frontpage&#34;&gt;Kick Assembler&lt;/a&gt;, as well. Give it a try!&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/cbmprgstudio4mega65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/back-to-basics/cbmprgstudio4mega65.png 1598w, https://dansanderson.com/mega65/back-to-basics/cbmprgstudio4mega65_hu_cffec6188742208d.png 600w, https://dansanderson.com/mega65/back-to-basics/cbmprgstudio4mega65_hu_249dcfdfadd4bd28.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/back-to-basics/cbmprgstudio4mega65.png&#34;
        alt=&#34;CBM PRG Studio 4.0 with a MEGA65 BASIC program&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
CBM PRG Studio 4.0 with a MEGA65 BASIC program
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;managing-d81-disk-images-on-a-pc&#34;&gt;Managing D81 disk images on a PC&lt;/h2&gt;
&lt;p&gt;Maybe you&amp;rsquo;ve written a program on your MEGA65 and saved it to a D81 disk image, and now you want to extract the PRG file on your PC. Or perhaps you&amp;rsquo;ve written a PRG on your PC, and want to put it in a D81 disk image for the MEGA65. We&amp;rsquo;ve got tools for that!&lt;/p&gt;
&lt;p&gt;Windows users should go straight to &lt;a href=&#34;https://style64.org/dirmaster&#34;&gt;DirMaster&lt;/a&gt;, a powerful disk image management tool that supports many formats, including D81. You can create new images, open existing ones, copy files to and from images, and much more.&lt;/p&gt;
&lt;p&gt;Mac and Linux users will prefer &lt;a href=&#34;https://droid64.sourceforge.net/&#34;&gt;droiD64&lt;/a&gt;, a desktop app similar to DirMaster. It has fewer features, but I like it because it’s fast and works on all operating systems. It requires a Java 11 runtime, such as &lt;a href=&#34;http://adoptopenjdk.net/&#34;&gt;OpenJDK&lt;/a&gt; or the &lt;a href=&#34;http://java.oracle.com/&#34;&gt;Oracle Java runtime&lt;/a&gt;. I wrote a bit more detail about droiD64 in &lt;a href=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/&#34;&gt;a recent blog post&lt;/a&gt;. Check that out for a technical recommendation on how to improve the start-up script that comes with droiD64.&lt;/p&gt;
&lt;p&gt;Of course, I did say I was a developer tools nerd, so naturally my build scripts use command-line tools to create D81 image files. VICE comes with a tool called &lt;a href=&#34;https://vice-emu.sourceforge.io/vice_14.html&#34;&gt;c1541&lt;/a&gt;, and &lt;a href=&#34;http://www.zimmers.net/anonftp/pub/cbm/crossplatform/converters/unix/cbmconvert.html&#34;&gt;cbmconvert&lt;/a&gt; (&lt;a href=&#34;http://www.zimmers.net/anonftp/pub/cbm/crossplatform/converters/unix/cbmconvert-2.1.2.tar.gz&#34;&gt;download&lt;/a&gt;) is another option. Personally, I write my own D81 build logic in Python with the &lt;a href=&#34;https://pypi.org/project/d64/&#34;&gt;d64 Python library&lt;/a&gt;. Most people will get by just fine with DirMaster or droiD64.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/back-to-basics/droid64_main.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/back-to-basics/droid64_main.png 1043w, https://dansanderson.com/mega65/back-to-basics/droid64_main_hu_87b7179eb3a6411.png 600w, https://dansanderson.com/mega65/back-to-basics/droid64_main_hu_53de180a3657bde5.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/back-to-basics/droid64_main.png&#34;
        alt=&#34;The droiD64 main window&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The droiD64 main window
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr&gt;
&lt;p&gt;It&amp;rsquo;s the end of the year, and I hope everyone is able to take some time off, disconnect from the Internet a bit, and spend some quality time with your MEGA65, and maybe family and friends too if you get around to it. When you get back online at the end of your break, don&amp;rsquo;t forget to share your BASIC programs by uploading them to &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;I hope you&amp;rsquo;re all doing well this holiday, and I hope to see you again in 2023.&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/back-to-basics/M65Digest_2022Dec.mp3" length="26215361" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1311</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/back-to-basics/image1.jpg"/>
      
    </item>
    
    <item>
      <title>Ladder on a Modern PC</title>
      <link>https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/</link>
      <pubDate>Wed, 21 Dec 2022 12:01:23 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/</guid>
      <description>&lt;p&gt;One of my favorite home computer games from early childhood is Ladder for the Kaypro, an action platformer rendered entirely in text characters. Here&amp;rsquo;s how to play it on your modern PC.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;One of my favorite home computer games from early childhood is Ladder for the Kaypro, an action platformer rendered entirely in text characters. Here&amp;rsquo;s how to play it on your modern PC.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_title.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_title.png 817w, https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_title_hu_2eb6502ee1643e5d.png 600w, https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_title_hu_fb2e6cc7b66396ab.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_title.png&#34;
        alt=&#34;The Ladder title screen&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Ladder title screen, running in macOS with two layers of emulation
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Ladder_(video_game)&#34;&gt;Ladder&lt;/a&gt; by Yahoo Software was bundled with the early &lt;a href=&#34;https://en.wikipedia.org/wiki/Kaypro&#34;&gt;Kaypro&lt;/a&gt; computers of the 1980&amp;rsquo;s, bulky &amp;ldquo;luggable&amp;rdquo; portable computers with green monochrome screens optimized for text. The Kaypro ran the &lt;a href=&#34;https://en.wikipedia.org/wiki/CP/M&#34;&gt;CP/M&lt;/a&gt; operating system. My father used his Kaypro primarily for writing in &lt;a href=&#34;https://en.wikipedia.org/wiki/WordStar&#34;&gt;WordStar&lt;/a&gt;. When he wasn&amp;rsquo;t using it, I used it for Microsoft BASIC and Ladder.&lt;/p&gt;
&lt;p&gt;Ladder is an action platform game drawn entirely in ASCII characters. You are the lad, represented by a &lt;code&gt;p&lt;/code&gt; or &lt;code&gt;q&lt;/code&gt; depending on which way you&amp;rsquo;re facing, or &lt;code&gt;g&lt;/code&gt; if you&amp;rsquo;re sitting still. You walk on platforms &lt;code&gt;=&lt;/code&gt;, climb ladders &lt;code&gt;H&lt;/code&gt;, and jump over falling boulders &lt;code&gt;o&lt;/code&gt;, to collect minor treasures &lt;code&gt;&amp;amp;&lt;/code&gt; and reach the main treasure &lt;code&gt;$&lt;/code&gt;. Some levels feature spike hazards &lt;code&gt;^&lt;/code&gt;. Touching a hazard or boulder loses and life and restarts the level. Trampolines &lt;code&gt;.&lt;/code&gt; send you jumping in a random direction if you land on them. The upward motion of the character and downward motion of the boulders remind some of Donkey Kong, though there is no gorilla or any real other characters other than the lad. (Boulders emanate periodically from hanging &lt;code&gt;V&lt;/code&gt; and are absorbed by sitting &lt;code&gt;*&lt;/code&gt;.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_level.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_level.png 817w, https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_level_hu_5f6334cf8c451edd.png 600w, https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_level_hu_8d3d7a938f340dcc.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/ladder-on-a-modern-pc/ladder_level.png&#34;
        alt=&#34;Level 2 of Ladder&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Level 2 of Ladder
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The game can be quite difficult, but it remains addictive thanks to surprisingly precise and fluid controls. Jumps have predictable arcs along the character grid, and you can change direction in mid-air or stop to wait. Clever tricks like hovering over a boulder can rack up points, and several of the single-screen levels have multiple paths and additional challenges. The original game only included seven levels, though to progress you had to loop back to level 1 multiple times, so later levels were difficult to reach.&lt;/p&gt;
&lt;p&gt;The source code to the original Ladder is lost to time, but the binary &lt;code&gt;.COM&lt;/code&gt; files are easy to find (though not necessarily the complete set). There have been several attempts to recreate Ladder from memory and folk knowledge: &lt;a href=&#34;https://ostermiller.org/ladder/&#34;&gt;Ladder written in Java&lt;/a&gt; by Stephen Ostermiller, &lt;a href=&#34;https://github.com/mengstr/ladder&#34;&gt;Ladder in Go&lt;/a&gt; by Mats Engstrom, and &lt;a href=&#34;https://github.com/mecparts/Ladder&#34;&gt;Ladder in Turbo Pascal&lt;/a&gt; by Github user mecparts. I assume at least one of these extracted the original level data from the Ladder &lt;code&gt;.COM&lt;/code&gt; file, if only because it&amp;rsquo;s not that difficult to do.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve always kept it in the back of my mind to periodically try to figure out ways to run the original Ladder program, but I&amp;rsquo;ve never really done a deep dive on CP/M. For no reason in particular, last night I was inspired to poke around again, and I found &lt;a href=&#34;https://groups.google.com/g/comp.os.cpm/c/m4ieb1sGBkM/m/eukXypNyAwAJ&#34;&gt;a comp.sys.cpm Usenet post&lt;/a&gt; from 2020 (!) with a lovely tip: use two layers of emulation, a CP/M emulator written for MS-DOS, running in DOSBox. Minutes later I was playing Ladder on my MacBook Pro.&lt;/p&gt;
&lt;p&gt;Things you&amp;rsquo;ll need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mecparts/Ladder&#34;&gt;DOSBox&lt;/a&gt; for your modern computer (Windows, macOS, Linux).&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.gaby.de/22nce132.zip&#34;&gt;22NICE&lt;/a&gt;, a CP/M emulator for MS-DOS. 22NICE was released as Shareware by &lt;a href=&#34;https://www.sydex.com/&#34;&gt;Sydex&lt;/a&gt; but is no longer distributed. I found it on &lt;a href=&#34;http://www.gaby.de/edownl.htm&#34;&gt;Gaby&amp;rsquo;s Homepage for CP/M and Computer History&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.retroarchive.org/cpm/misc/LADDER.ZIP&#34;&gt;LADDER.ZIP&lt;/a&gt;. There might be more complete versions of the Ladder files out there—this one is missing the config utility—but this is plenty to play it. I found this one on &lt;a href=&#34;http://www.retroarchive.org/cpm/misc/misc.htm&#34;&gt;RetroArchive.org&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To set everything up:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Unzip &lt;code&gt;22nce132.zip&lt;/code&gt; into an empty folder. The macOS Finder refused to open this, but I was able to use the &lt;code&gt;unzip&lt;/code&gt; command in a Terminal: &lt;code&gt;mkdir 22nice; cd 22nice; unzip ../22nce132.zip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Unzip &lt;code&gt;LADDER.ZIP&lt;/code&gt; into the same folder. This provides a file named &lt;code&gt;LADDER.COM&lt;/code&gt;. This is a CP/M command file, not an MS-DOS command file.&lt;/li&gt;
&lt;li&gt;Open DOSBox. Run all following commands in DOSBox.&lt;/li&gt;
&lt;li&gt;Mount the &lt;code&gt;22nice&lt;/code&gt; folder as drive C: &lt;code&gt;mount c ~/Downloads/22nice&lt;/code&gt; where the path is whatever it is on your system. Switch to drive C: &lt;code&gt;c:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Rename &lt;code&gt;ladder.com&lt;/code&gt; to &lt;code&gt;ladder.cpm&lt;/code&gt;: &lt;code&gt;ren ladder.com ladder.cpm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use 22NICE&amp;rsquo;s &lt;code&gt;gencom&lt;/code&gt; to wrap the CP/M program as a DOS program, using the Kaypro display mode: &lt;code&gt;gencom ladder.cpm dis=kay&lt;/code&gt; This produces a new &lt;code&gt;ladder.com&lt;/code&gt; DOS command.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can now run &lt;code&gt;ladder&lt;/code&gt; at the DOS prompt to start the game.&lt;/p&gt;
&lt;p&gt;Controls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;,&lt;/code&gt; and &lt;code&gt;.&lt;/code&gt; move left and right&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a&lt;/code&gt; and &lt;code&gt;z&lt;/code&gt; move up and down when on a ladder&lt;/li&gt;
&lt;li&gt;Space to jump&lt;/li&gt;
&lt;li&gt;&lt;code&gt;b&lt;/code&gt; to stop (useful!)&lt;/li&gt;
&lt;li&gt;Escape to pause&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, you can use 22NICE and DOSBox to run other CP/M software this way. If you do, check out the 22NICE manual (&lt;code&gt;22NICE.DOC&lt;/code&gt;) for information about some handy features like keyboard mapping.&lt;/p&gt;
&lt;p&gt;Hooka! Hooka! Hooka!&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>Advent of Code on the MEGA65</title>
      <link>https://dansanderson.com/lab-notes/advent-of-code-mega65/</link>
      <pubDate>Sun, 04 Dec 2022 00:17:54 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/lab-notes/advent-of-code-mega65/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://adventofcode.com/&#34;&gt;Advent of Code&lt;/a&gt;, the annual non-competitive puzzle event for computer programmers, has begun for 2022. Here are a few tips for anyone who might want to try this year&amp;rsquo;s AoC on the MEGA65.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;&lt;a href=&#34;https://adventofcode.com/&#34;&gt;Advent of Code&lt;/a&gt;, the annual non-competitive puzzle event for computer programmers, has begun for 2022. Here are a few tips for anyone who might want to try this year&amp;rsquo;s AoC on the MEGA65.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/aoc2.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/aoc2.png&#34;
            width=&#34;556&#34;
            height=&#34;397&#34;
            alt=&#34;Advent of Code&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://adventofcode.com/&#34;&gt;Advent of Code&lt;/a&gt; is an &lt;a href=&#34;https://en.wikipedia.org/wiki/Advent_calendar&#34;&gt;Advent calendar&lt;/a&gt; of computer programming puzzles, which just means it has something every day for the first 25 days of December and all participants are doing it concurrently, and there&amp;rsquo;s some light secular Christmas theming. The puzzles can be solved in any programming language, and many programmers use it as an opportunity to sharpen their skills with a language that they know or to learn a new language. The puzzles are primarily intended for programming on modern computers, and typically involve acting on sets of data to calculate a single-value result.&lt;/p&gt;
&lt;p&gt;Vintage computer enthusiasts sometimes attempt AoC on old computers as an excuse to learn vintage programming, or just to spend some time each day writing code in a cozy environment without Internet access. This poses additional AoC challenges. How do you get the input data set for today&amp;rsquo;s puzzle off of the AoC website and onto the vintage computer? How do you read and parse data files?&lt;/p&gt;
&lt;p&gt;Below are some tips for attempting AoC puzzles on the &lt;a href=&#34;https://mega65.org/&#34;&gt;MEGA65&lt;/a&gt;. You can use similar techniques for the Commodore 64 and Commodore 128 if you have a modern peripheral that emulates a disk drive, such as an &lt;a href=&#34;https://ultimate64.com/Main_products&#34;&gt;Ultimate II+&lt;/a&gt; cartridge or an &lt;a href=&#34;https://www.thefuturewas8bit.com/sd2iec-info&#34;&gt;SD2IEC&lt;/a&gt; (&lt;a href=&#34;https://www.thefuturewas8bit.com/shop/commodore/sd2iec-c.html&#34;&gt;purchase&lt;/a&gt;) device.&lt;/p&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;I&amp;rsquo;m publishing this a few days into the month of December, so the event has already begun. You can always start AoC from the beginning, or even visit puzzles from previous years.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;copying-data-files-to-the-mega65&#34;&gt;Copying data files to the MEGA65&lt;/h2&gt;
&lt;p&gt;While it&amp;rsquo;s fun to use the MEGA65&amp;rsquo;s built-in physical floppy drive for that vintage floppy disk feel, it is more convenient to use a microSD card for copying data between the MEGA65 and a PC (Windows, Mac, or Linux). A microSD card prepared on the MEGA65 has a FAT32 partition that can be used with a a PC with microSD card reader. See your User&amp;rsquo;s Guide or my &lt;a href=&#34;https://dansanderson.com/mega65/welcome/&#34;&gt;MEGA65 Welcome Guide&lt;/a&gt; for instructions on how to prepare a microSD card.&lt;/p&gt;
&lt;p&gt;Among other things, the microSD card can contain &lt;em&gt;disk images&lt;/em&gt; of the D81 format, which represents disks compatible with Commodore 1581 drives. You can download D81 files that others have made, or you can create empty D81 files in the MEGA65&amp;rsquo;s Freeze menu.&lt;/p&gt;
&lt;p&gt;There are tools for PCs that can create and manipulate D81 disk images, as well as other vintage disk image types. &lt;a href=&#34;https://style64.org/dirmaster&#34;&gt;DirMaster&lt;/a&gt; is a popular desktop app for Windows with many features, including creating new images and dragging files between images and your PC. Command-line tools such as &lt;a href=&#34;http://www.zimmers.net/anonftp/pub/cbm/crossplatform/converters/unix/cbmconvert.html&#34;&gt;cbmconvert&lt;/a&gt; (&lt;a href=&#34;http://www.zimmers.net/anonftp/pub/cbm/crossplatform/converters/unix/cbmconvert-2.1.2.tar.gz&#34;&gt;download&lt;/a&gt;) or &lt;a href=&#34;https://vice-emu.sourceforge.io/vice_14.html&#34;&gt;c1541&lt;/a&gt; (included with VICE) also work, though they can be difficult to use.&lt;/p&gt;
&lt;p&gt;My personal favorite is &lt;a href=&#34;https://droid64.sourceforge.net/&#34;&gt;droiD64&lt;/a&gt;, a desktop app similar to DirMaster. It has fewer features, but I like it because it&amp;rsquo;s fast and works on Windows, macOS, or Linux. It requires a Java 11 runtime, such as &lt;a href=&#34;http://adoptopenjdk.net/&#34;&gt;OpenJDK&lt;/a&gt; or the &lt;a href=&#34;http://java.oracle.com/&#34;&gt;Oracle Java runtime&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_main.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_main.png 1043w, https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_main_hu_87b7179eb3a6411.png 600w, https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_main_hu_53de180a3657bde5.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_main.png&#34;
        alt=&#34;droid64 main window&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The droiD64 main window.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;setting-up-droid64-on-mac-or-linux&#34;&gt;Setting up droiD64 on Mac or Linux&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://sourceforge.net/projects/droid64/files/droiD64/0.5b/droid64-0.5b-bin.zip/download&#34;&gt;Download droiD64-0.5b-bin.zip&lt;/a&gt; (SourceForge link), then expand the archive to create the &lt;code&gt;droid64-0.5b&lt;/code&gt; folder. To run droiD64 on macOS or Linux, you can use the &lt;code&gt;droid64.sh&lt;/code&gt; script.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a bit of a trick: as written, this script expects the droiD64 folder to be the current working directory so it can find the &lt;code&gt;lib/&lt;/code&gt; subfolder, which isn&amp;rsquo;t the case if you just double-click on the script from the file browser. One way to run it is to open a Terminal, &lt;code&gt;cd droid64-0.5b&lt;/code&gt; (wherever you put the folder), then run &lt;code&gt;./droid64.sh&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I prefer to simply repair the &lt;code&gt;droid64.sh&lt;/code&gt; script, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh
DROID64DIR=`dirname &amp;#34;$(readlink -f &amp;#34;$0&amp;#34;)&amp;#34;`
CPATH=$DROID64DIR/lib/droid64-0.5b.jar:$DROID64DIR/lib/jaxb-impl-2.3.3.jar:$DROID64DIR/lib/jakarta.activation-1.2.2.jar:$DROID64DIR/lib/postgresql-42.2.18.jar:$DROID64DIR/lib/protobuf-java-3.11.4.jar:$DROID64DIR/lib/checker-qual-3.5.0.jar:$DROID64DIR/lib/jakarta.xml.bind-api-2.3.3.jar:$DROID64DIR/lib/mysql-connector-java-8.0.22.jar:$DROID64DIR/lib/jakarta.activation-api-1.2.2.jar
exec java -classpath $CPATH -Xmx1024m droid64.DroiD64 $*&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can double-click on the &lt;code&gt;droid64.sh&lt;/code&gt; icon from Finder to run it, or run it from the command line regardless of the current working directory.&lt;/p&gt;
&lt;p&gt;Windows users can try the &lt;code&gt;droid64.bat&lt;/code&gt; script. I haven&amp;rsquo;t tested whether it needs a similar modification, and I don&amp;rsquo;t know what the Windows batch file equivalent of this is. You can always just paste the full path to the &lt;code&gt;droid64-0.5b&lt;/code&gt; folder before each &lt;code&gt;lib/&lt;/code&gt; instance, after you can given the folder a permanent home.&lt;/p&gt;
&lt;h3 id=&#34;creating-a-d81-disk-image&#34;&gt;Creating a D81 disk image&lt;/h3&gt;
&lt;p&gt;The droiD64 main window consists of two file browsers and a collection of action buttons. You can select a file browser by clicking on it; the selected browser has a red border. Some actions are performed on the currently selected directory or file. Other actions use both browsers.&lt;/p&gt;
&lt;p&gt;Select the right-hand file browser, and browse to a location where you&amp;rsquo;d like to create a D81 disk image. Click the &lt;strong&gt;New Disk&lt;/strong&gt; button. In the &amp;ldquo;New disk&amp;rdquo; dialog, select a type of D81. Provide a disk name (up to 16 letters and numbers) and a two-character ID (it doesn&amp;rsquo;t matter what the ID is). Click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_created81.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_created81.png 585w, https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_created81_hu_387a8ae407fadcf1.png 600w, https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_created81_hu_b5315bb9a8ca63df.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_created81.png&#34;
        alt=&#34;The New Disk dialog, with the D81 type selected and a disk name and ID entered.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The &#34;New disk&#34; dialog, with the D81 type selected.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &amp;ldquo;Save disk image&amp;rdquo; dialog opens already set to the selected folder, with a filename based on the disk name and a &lt;code&gt;.d81&lt;/code&gt; extension. Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_filename.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_filename.png 807w, https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_filename_hu_43a83bd72c925c7a.png 600w, https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_filename_hu_644e742f960146e0.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/advent-of-code-mega65/droid64_filename.png&#34;
        alt=&#34;The Save Disk Image dialog.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The &#34;Save disk image&#34; dialog.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In the main window, the right-hand file browser is now &lt;em&gt;inside&lt;/em&gt; the new D81 disk image. You can tell that it&amp;rsquo;s in the image because the title bar is now blue.&lt;/p&gt;
&lt;h3 id=&#34;transferring-an-aoc-data-file-to-the-disk-image&#34;&gt;Transferring an AoC data file to the disk image&lt;/h3&gt;
&lt;p&gt;Download the AoC data file for the first December 1st puzzle from the website. Rename the file to use a &lt;code&gt;.seq&lt;/code&gt; file extension and a short filename, such as: &lt;code&gt;aoc01.seq&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In the left-hand file browser, navigate to the data file. Select it, then click &lt;strong&gt;Copy File&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The disk image now has a &lt;code&gt;SEQ&lt;/code&gt; file named &lt;code&gt;AOC01&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;mounting-the-disk-image-on-the-mega65&#34;&gt;Mounting the disk image on the MEGA65&lt;/h3&gt;
&lt;p&gt;Use your PC to copy the &lt;code&gt;.d81&lt;/code&gt; file to the microSD card. Eject the card, then re-insert it in your MEGA65.&lt;/p&gt;
&lt;p&gt;If you know the name of the &lt;code&gt;D81&lt;/code&gt; file, the fastest way to mount it to drive unit 0 is with the &lt;code&gt;MOUNT&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MOUNT &amp;#34;AOC01.D81&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alternatively, open the Freeze menu: hold &lt;kbd&gt;Restore&lt;/kbd&gt; for a second then release. Press &lt;kbd&gt;0&lt;/kbd&gt; to select drive unit 0, then use the cursor keys to select your disk image and press &lt;kbd&gt;Return&lt;/kbd&gt;. Press &lt;kbd&gt;F3&lt;/kbd&gt; to return to BASIC.&lt;/p&gt;
&lt;p&gt;Use the &lt;code&gt;DIR&lt;/code&gt; command to confirm that your disk is mounted and your &lt;code&gt;SEQ&lt;/code&gt; file is present.&lt;/p&gt;
&lt;h2 id=&#34;using-the-data-file-from-basic&#34;&gt;Using the data file from BASIC&lt;/h2&gt;
&lt;p&gt;A &lt;code&gt;SEQ&lt;/code&gt; file is a simple sequence of bytes. You can read such a file from BASIC using disk commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 DOPEN#1,&amp;#34;AOC01&amp;#34;
20 GET#1,B$
30 IF ST THEN 60
40 PRINT B$;
50 GOTO 20
60 DCLOSE#1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This program reads each byte from the file one at a time, and tries to print it as if it were PETSCII. AoC input files will never be PETSCII, but we can at least use this to demonstrate that it is reading the file.&lt;/p&gt;
&lt;p&gt;The first AoC 2022 Day 1 puzzle has an input file that consists of ASCII characters that represent a list of decimal numbers, separated by newline (ASCII value 10) bytes. We can modify this program to interpret the file and print it more cleanly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5 V$=&amp;#34;&amp;#34;
10 DOPEN#1,&amp;#34;AOC01&amp;#34;
20 GET#1,B$
30 IF ST THEN 110
40 IF ASC(B$)=10 THEN 70
50 V$=V$+B$
60 GOTO 20
70 V=VAL(V$)
80 PRINT V
90 V$=&amp;#34;&amp;#34;
100 GOTO 20
110 DCLOSE#1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This reads each line one byte at a time, converting each byte to PETSCII and appending it to the &lt;code&gt;V$&lt;/code&gt; string variable. When it encounters a newline (10), it jumps to a routine to parse the contents of &lt;code&gt;V$&lt;/code&gt; as a decimal number using &lt;code&gt;VAL()&lt;/code&gt; and store it in the &lt;code&gt;V&lt;/code&gt; number variable (which is distinct from the &lt;code&gt;V$&lt;/code&gt; string variable). When it&amp;rsquo;s done with the value, it resets the &lt;code&gt;V$&lt;/code&gt; string, then returns to the read loop.&lt;/p&gt;
&lt;p&gt;An actual solution to the Day 1 exercise needs to do something with the numeric value stored in &lt;code&gt;V&lt;/code&gt;. This demonstration simply prints it on its own line. Notice that the data format for this puzzle includes meaningful blank lines, so a solution should test &lt;code&gt;IF V$=&amp;quot;&amp;quot; ...&lt;/code&gt; before calling &lt;code&gt;DEC()&lt;/code&gt; to do something different with the blanks.&lt;/p&gt;
&lt;div class=&#34;callout exercise&#34;&gt;
&lt;p&gt;What does &lt;code&gt;VAL()&lt;/code&gt; do when given a blank line? How would you find out? Is it safe to use the result of &lt;code&gt;VAL()&lt;/code&gt; to detect a blank line, according to the problem description?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;While you&amp;rsquo;re writing and testing your BASIC program, the program may fail before it gets to the &lt;code&gt;DCLOSE#1&lt;/code&gt; command. To stop the disk drive from making noise, enter &lt;code&gt;DCLOSE#1&lt;/code&gt; at the &lt;code&gt;READY.&lt;/code&gt; prompt.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;aoc-in-mega-assembler&#34;&gt;AoC in Mega Assembler&lt;/h2&gt;
&lt;p&gt;Would you rather use this opportunity to learn assembly language? A fun way to do this is with &lt;a href=&#34;https://files.mega65.org?id=3b101d41-5128-4a21-879c-0cf7988edfec&#34;&gt;Mega Assembler&lt;/a&gt; by Thomas Gruber (grubi), an on-device assembly language coding environment.&lt;/p&gt;
&lt;h3 id=&#34;introducing-mega-assembler&#34;&gt;Introducing Mega Assembler&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org?id=3b101d41-5128-4a21-879c-0cf7988edfec&#34;&gt;Download the Mega Assembler disk image&lt;/a&gt; from Filehost, then copy it to your SD card. Mount the Mega Assembler disk image, then &lt;code&gt;RUN &amp;quot;MEGA ASSEMBLER&amp;quot;&lt;/code&gt;. Press the &lt;kbd&gt;Help&lt;/kbd&gt; key to learn about its features.&lt;/p&gt;
&lt;p&gt;The default assembly target address is &lt;code&gt;$1800&lt;/code&gt;. This gives you 2048 bytes of code space before your program starts overwriting the assembler itself when assembling to memory, which is hopefully enough for AoC exercises. Of course, the starting address can be changed, and you can also assemble directly to disk. Mega Assembler v1.1 runs all the way from &lt;code&gt;$2000&lt;/code&gt; to &lt;code&gt;$d59f&lt;/code&gt;, so there&amp;rsquo;s not much room in bank 0 for a long program that also keeps the assembler in memory.&lt;/p&gt;
&lt;p&gt;Try one of the included examples:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Press &lt;kbd&gt;Mega&lt;/kbd&gt;-&lt;kbd&gt;L&lt;/kbd&gt; to load an example, then type &lt;code&gt;TESTDRIVE&lt;/code&gt; and &lt;kbd&gt;Return&lt;/kbd&gt;.&lt;/li&gt;
&lt;li&gt;Press &lt;kbd&gt;Mega&lt;/kbd&gt;-&lt;kbd&gt;A&lt;/kbd&gt; to assemble.&lt;/li&gt;
&lt;li&gt;After assembly, press the &lt;kbd&gt;R&lt;/kbd&gt; key to run it.&lt;/li&gt;
&lt;li&gt;The program performs its function (&lt;code&gt;TESTDRIVE&lt;/code&gt; performs a mirror effect on the screen), then pauses. Press a key to exit back to the editor.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If we inspect the example code in the editor using the cursor keys, we notice two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;.RUN WAIT&lt;/code&gt; directive at the top causes the program to pause for a keypress when it is done when run from Mega Assembler. &lt;code&gt;.RUN CLEAR,WAIT&lt;/code&gt; will clear the screen before running, then wait for a keypress after.&lt;/li&gt;
&lt;li&gt;The program ends with an &lt;code&gt;rts&lt;/code&gt; instruction. Mega Assembler invokes the program as a subroutine.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;loading-aoc-input-data-into-memory&#34;&gt;Loading AoC input data into memory&lt;/h3&gt;
&lt;p&gt;How do we access the data file from assembly language? We could try to write assembly code that calls kernel routines to access the &lt;code&gt;SEQ&lt;/code&gt; file on disk, but this is a hassle for short exercises.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a simpler idea: before running Mega Assembler, load the input data into upper memory. Our assembly code can operate on memory instead of disk. This could be done with a BASIC program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 AD=$40000
20 DOPEN#1,&amp;#34;AOC01&amp;#34;
30 GET#1,B$
40 IF ST THEN 80
50 POKE AD,ASC(B$)
60 AD=AD+1
70 GOTO 30
80 DCLOSE#1
90 POKE AD,10
100 POKE AD+1,10
110 POKE AD+2,0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This loads the &lt;code&gt;SEQ&lt;/code&gt; file into memory starting at address &lt;code&gt;$40000&lt;/code&gt;. Save this BASIC program to the disk, and run it before loading Mega Assembler. If your program does not modify the input data, you can just leave it in memory while you work.&lt;/p&gt;
&lt;p&gt;I added two values at the end of the dataset: a 10, a 10, and a 0 (lines 90-110). We might be able to do without these if we hard-code (or store) the data length in memory somewhere, and write our assembly program carefully enough not to go past that boundary and handle the edge case of the final value having nothing after it. By adding these values, I ensure that the last line with a value ends in a newline, there&amp;rsquo;s a blank line at the end to mark the end of the final list, and there&amp;rsquo;s a special character (a null) that doesn&amp;rsquo;t appear anywhere else in the data set that the program can use to identify the end of the data. I discovered that I needed this by inspecting the memory after run this BASIC program using the &lt;code&gt;MONITOR&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With the data in upper memory, we can now load and run Mega Assembler and start coding.&lt;/p&gt;
&lt;h3 id=&#34;using-upper-memory&#34;&gt;Using upper memory&lt;/h3&gt;
&lt;p&gt;Mega Assembler is a BASIC program, and we want our program to be able to return to Mega Assembler when it finishes. This means we have to be careful not to write an assembly program that clobbers memory resources used by BASIC and Mega Assembler.&lt;/p&gt;
&lt;p&gt;The first 64Kb of memory (bank 0, &lt;code&gt;$00000-$0FFFF&lt;/code&gt;) is used by BASIC, our assembled program, Mega Assembler&amp;rsquo;s BASIC code, kernel ROM. The second 64Kb (bank 1) is used for BASIC disk operations (&lt;code&gt;$10000-$11FFF&lt;/code&gt;), Mega Assembler&amp;rsquo;s working space (&lt;code&gt;$12000-...&lt;/code&gt;), and BASIC working space. Banks 2 and 3 are ROM locations; a program can unlock these and overwrite them, but we need them to preserve BASIC.&lt;/p&gt;
&lt;p&gt;Banks 4 and 5 are used by the BASIC hi-res graphics system, but we&amp;rsquo;re not using that for our assembly program, so we can use it for our data. I can imagine using BASIC hi-res graphics with a future AoC puzzle (or just to visualize something interesting), but I&amp;rsquo;d only use it from a BASIC program, and would try to take advantage of loading data directly from disk in that case instead of storing the entire dataset in memory.&lt;/p&gt;
&lt;p&gt;The original 6502 CPU only knows how to access 64Kb of memory, from &lt;code&gt;$0000-$FFFF&lt;/code&gt;. Successors to the 6502, including the MEGA65&amp;rsquo;s 45GS02, added backwards compatible ways to select upper banks. For our purposes, the best way to read our data from bank 4 is &lt;em&gt;base page indexing&lt;/em&gt;: store a 32-bit address across four bytes in the base page, then refer to the base page address using a special type of instruction. For example, if we store &lt;code&gt;00 80 01 00&lt;/code&gt; at addresses &lt;code&gt;$fc-$ff&lt;/code&gt; on the base page, these instructions will load the byte stored at &lt;code&gt;$00018000&lt;/code&gt; into the accumulator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  ldz #0
  lda [$fc],z&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;lda [...],z&lt;/code&gt; instruction finds the 32-bit address on the base page, adds the Z register to it, then loads a byte from that address.&lt;/p&gt;
&lt;p&gt;The default base page is &lt;code&gt;$00xx&lt;/code&gt;, similar to the &amp;ldquo;zero page&amp;rdquo; on the Commodore 64. We can&amp;rsquo;t use this page without interfering with BASIC. Instead, we can tell the 45GS02 to use a different page of lower memory as the base page. The B register identifies this page, and we can set it by loading a value into the accumulator then calling the &lt;code&gt;tab&lt;/code&gt; instruction. Base page &lt;code&gt;$16xx&lt;/code&gt; is unused by BASIC, so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;; set the base page to $1600-16ff
  lda #$16
  tab

  ; ... our program goes here...

; reset the base page to $0000-00ff
  lda #$00
  tab
  rts&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&amp;rsquo;s an example that copies the first line of the input data to screen memory (assuming the first line is valid and fewer than 255 characters). It uses the 16-bit version of base page indexing to access the screen memory (&lt;code&gt;sta (...),z&lt;/code&gt;), and increments the Z register to traverse the bytes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.run clear,wait

; set the base page to $1600-16ff
  lda #$16
  tab

; store 32-bit address $00040000 at $1600
; store 16-bit address $0800 at $1604
  lda #$00
  sta $1600    ; 00 -- -- -- : -- --
  sta $1601    ; 00 00 -- -- : -- --
  sta $1603    ; 00 00 -- 00 : -- --
  sta $1604    ; 00 00 -- 00 : 00 --
  lda #$04
  sta $1602    ; 00 00 04 00 : 00 --
  lda #$08
  sta $1605    ; 00 00 04 00 : 00 08

; copy the first line of input data to the upper left corner of the screen
  ldz #0
loop
  lda [$00],z  ; read from the 32-bit address stored at $1600, offset by z
  cmp #10      ; check for a newline (ASCII 10)
  beq done
  sta ($04),z  ; store to the 16-bit address stored at $1604, offset by z
  inz
  bra loop
done

; reset the base page to $0000-00ff
  lda #$00
  tab

; return to mega assembler
  rts&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&#34;callout exercise&#34;&gt;
&lt;p&gt;As written, this loop uses the Z register to offset the addresses stored on the base page. The Z register is 8 bits and can only go from 0 to 255.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What would this code do if the first line of input data were longer than 255 bytes?&lt;/li&gt;
&lt;li&gt;How can we improve the loop to support copying a longer line? Hint: The Z register is an offset of the addresses stored in the base page. The &lt;code&gt;inc&lt;/code&gt; instruction can increment the value at a memory location.&lt;/li&gt;
&lt;li&gt;If it&amp;rsquo;s safe to assume that all lines are shorter than 255 bytes, how would you write a routine that processes one line at a time?&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;h2 id=&#34;aoc-with-a-cross-assembler&#34;&gt;AoC with a cross assembler&lt;/h2&gt;
&lt;p&gt;On-device coding is fun, but I enjoy the security of keeping my code on a modern PC, so I can use a modern text editor and revision control. We &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-game-of-life-in-assembly/&#34;&gt;previously discussed&lt;/a&gt; how to do cross-assembly on a PC for the MEGA65 using the &lt;a href=&#34;https://sourceforge.net/projects/acme-crossass/&#34;&gt;ACME assembler&lt;/a&gt;. What&amp;rsquo;s the best way to do AoC puzzles with ACME?&lt;/p&gt;
&lt;p&gt;One idea, and probably the best one, is to attach the input file to the program itself. The program and the input file are stored together in the &lt;code&gt;PRG&lt;/code&gt; file, and loaded as a contiguous block into memory when the program is loaded. In ACME, you do this with the &lt;code&gt;!binary&lt;/code&gt; directive. An assembly program that starts with a BASIC header at &lt;code&gt;$2001&lt;/code&gt; can run all the way to &lt;code&gt;$F6FF&lt;/code&gt;, almost 54 Kb.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the same program as above, this time using regular 16-bit base page indexing to load the data from the address determined by the assembler.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;!cpu m65
!to &amp;#34;aoc01-asm.prg&amp;#34;, cbm

* = $2001

!8 $12,$20,$0a,$00,$fe,$02,$20,$30,$3a,$9e,$20
!pet &amp;#34;$2014&amp;#34;
!8 $00,$00,$00

  lda #$16
  tab

; store the 16-bit address of the &amp;#34;data&amp;#34; label at $1600
  lda #&amp;lt;data
  sta $1600
  lda #&amp;gt;data
  sta $1601

; store the 16-bit address $0800 at $1602
  lda #$00
  sta $1602
  lda #$08
  sta $1603

; copy the first line of input data to the upper left corner of the screen
  ldz #0
loop:
  lda ($00),z  ; read from the 16-bit address stored at $1600, offset by z
  cmp #10      ; check for a newline (ASCII 10)
  beq done
  sta ($02),z  ; store to the 16-bit address stored at $1604, offset by z
  inz
  bra loop
done:

; reset the base page to $0000-00ff
  lda #$00
  tab

; return to mega assembler
  rts

data:
!binary &amp;#34;input.txt&amp;#34;
!byte 10,10,0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have a USB serial interface and the latest version of the &lt;code&gt;m65&lt;/code&gt; tool that can auto-detect the serial port. I can cross-assemble this example and run it on my MEGA65 in a fraction of a second using these commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;acme aoc01.asm
m65 -r aco01-asm.prg&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because we&amp;rsquo;re doing cross-assembly, we don&amp;rsquo;t need to be sensitive about BASIC&amp;rsquo;s needs. The assembly program can just print the result to the screen and enter an infinite loop, without ever exiting back to BASIC. You could even just leave the answer somewhere in memory then read it using the &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/&#34;&gt;Matrix Mode debugger&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;For the first Day 1 exercise, we need to parse ASCII digits into numeric values and keep running totals larger than a 16-bit number. That&amp;rsquo;s easy in BASIC. In assembly language, we either need to write those routines ourselves, or locate existing kernel routines to do that for us. Future puzzles may require multiplication or division of numbers, or handling of fractions, and these are not built-in assembly language instructions. If these routines get long or complicated, it&amp;rsquo;s probably worth cross-assembling instead of using Mega Assembler so it&amp;rsquo;d be easier to reuse those routines in future puzzles.&lt;/p&gt;
&lt;p&gt;Cross-assembly with the data attached to the &lt;code&gt;PRG&lt;/code&gt; is as far as I would take this for AoC puzzles. For fun, I tried a version where the assembly program and data file were separate files, and a third BASIC loader copied the file to memory and loaded and ran the assembly code. This required cross-dev tooling to build the D81 disk image file, send it to the MEGA65 via &lt;code&gt;mega65_ftp&lt;/code&gt;, and run it with &lt;code&gt;m65&lt;/code&gt; typing commands. It&amp;rsquo;s feasible, and it&amp;rsquo;s a potentially useful technique for large projects, but it&amp;rsquo;s slower than sending a single &lt;code&gt;PRG&lt;/code&gt; over serial.&lt;/p&gt;
&lt;p&gt;Coding or cross-dev testing with the Xemu emulator might be a reasonable trade-off for making it easy and fun to do AoC puzzles with MEGA65 tech.&lt;/p&gt;
&lt;p&gt;Best of luck with AoC!&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>Sounds of the SID</title>
      <link>https://dansanderson.com/mega65/sounds-of-the-sid/</link>
      <pubDate>Sun, 27 Nov 2022 12:23:39 -0800</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/sounds-of-the-sid/</guid>
      <description>&lt;p&gt;Sounds of the SID. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for November 2022.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Sounds of the SID. &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for November 2022.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/M65Digest_03_2022Nov.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/M65Digest_03_2022Nov.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Sounds of the SID.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;[Did you know: All issues of the Digest have an audio version! Search for &amp;ldquo;&lt;a href=&#34;https://podcasts.apple.com/us/podcast/dans-mega65-digest-podcast/id1656654132&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt;&amp;rdquo; in your favorite podcast app, or check out the audio player at the top of each issue. — Dan]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The Commodore 64&amp;rsquo;s &lt;a href=&#34;https://en.wikipedia.org/wiki/MOS_Technology_6581&#34;&gt;Sound Interface Device (SID) chip&lt;/a&gt; was ahead of its time. While other personal computers were limited to simple beeps, the SID provided features comparable to professional sound synthesizers, with support for multiple kinds of sound waveforms, three-voice polyphony, and advanced filters and effects. Musician-programmers and game developers pushed the SID&amp;rsquo;s capabilities to the extreme, finding clever ways to drive the chip to produce multi-instrumental arrangements. To this day, artists continue to contribute to a vast legacy of SID-based music.&lt;/p&gt;
&lt;p&gt;The MEGA65&amp;rsquo;s audio subsystem includes four SID chips, alongside more modern sound capabilities. In this Digest, we will scratch the surface of how the SID works, and how to produce sound and music with the SIDs from BASIC. We&amp;rsquo;ll also introduce a new music demo written for the MEGA65 that takes full advantage of all four SID chips. MEGA65 music is a big subject, and we&amp;rsquo;ll cover more music topics in future issues of the Digest.&lt;/p&gt;
&lt;p&gt;But first, some news!&lt;/p&gt;
&lt;section class=&#34;m65news&#34;&gt;
	&lt;div class=&#34;banner&#34;&gt;MEGA65 News&lt;/div&gt;
&lt;h2 id=&#34;new-firmware-release&#34;&gt;New firmware release&lt;/h2&gt;
&lt;p&gt;The new release bundle for the firmware and system software has completed testing and is now officially declared &amp;ldquo;stable.&amp;rdquo; The new batch of MEGA65 computers being delivered by the end of the year 2022 will have this release installed at the factory. Anyone who received their MEGA65 computer earlier this year is encouraged to upgrade.&lt;/p&gt;
&lt;p&gt;Release bundles now have version numbers to make them easier to understand. The new release is known as release v0.95, and includes the MEGA65 core dated October 2022 (&lt;code&gt;20221012.18,93d55f0&lt;/code&gt;) and MEGA65 ROM &lt;code&gt;920377&lt;/code&gt;. The previous release has been retroactively labeled v0.9.&lt;/p&gt;
&lt;p&gt;I have updated &lt;a href=&#34;https://dansanderson.com/mega65/welcome/&#34;&gt;the MEGA65 Welcome Guide&lt;/a&gt; to describe the upgrade procedure, and to welcome the new batch of owners. You can download the release v0.95 bundle from &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost&lt;/a&gt;. Sign in with your account, make sure you have redeemed your owner code, then download the release package:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org/?id=a0276005-e71c-4b2d-8d17-2aa92e492c50&#34;&gt;MEGA65 Core Release Package (mega65r3) incl. ROM&lt;/a&gt; (only accessible if you’re signed in)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have any questions about upgrading, ask for help in &lt;a href=&#34;https://discord.gg/5DNvESf&#34;&gt;the Discord&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id=&#34;real-time-clock-replacement-program&#34;&gt;Real-Time Clock replacement program&lt;/h2&gt;
&lt;p&gt;The MEGA65 has a built-in Real-Time Clock (RTC) chip that keeps track of the date and time. If you haven&amp;rsquo;t yet, you&amp;rsquo;ll want to open your MEGA65 case and install a battery of type CR1220 on the main board. See &lt;a href=&#34;https://dansanderson.com/mega65/welcome/opening-the-case.html&#34;&gt;the Welcome Guide&lt;/a&gt; for instructions with photos.&lt;/p&gt;
&lt;p&gt;It was discovered earlier this year that a minority of MEGA65 computers contained faulty RTC chips, estimated to affect about 20% of computers. Faulty RTCs count the seconds too slowly or not at all. Starting with release v0.95 of the system software, the Freeze menu includes a diagnostic utility that knows how to test for a faulty RTC. (Open the Freeze menu and press the Help key to start it.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/megainfo_slowrtc.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/megainfo_slowrtc.jpeg 1280w, https://dansanderson.com/mega65/sounds-of-the-sid/megainfo_slowrtc_hu_9ba181ad463a22bf.jpeg 600w, https://dansanderson.com/mega65/sounds-of-the-sid/megainfo_slowrtc_hu_54b973a991483896.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/megainfo_slowrtc.jpeg&#34;
        alt=&#34;The MegaInfo utility detecting a slow-ticking internal RTC&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;p&gt;The MegaInfo utility detecting a slow-ticking internal RTC.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If your MEGA65 has a slow or stopped clock, you can request a replacement part that connects to the main board. For instructions on how to run the diagnostic utility, and how to request a replacement unit, see this article on Filehost:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org/?ar=ff484da0-d942-4e9b-adf1-3b5a77acaa25&#34;&gt;Request a Real-Time Clock replacement&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to the generosity of the MEGA65 community, we are able to offer this replacement part for the cost of shipping. Make sure your RTC fails the test with a fresh battery before requesting the part. We will send you email with the cost of shipping to your location after you submit a request, and you can cancel your request without remitting payment. Currently, shipping from the USA to Europe is $18 USD. We will try to find the cheapest shipping option to your location. We only accept PayPal at this time. &lt;em&gt;[Update December 2022: Previously we covered shipping costs through donations. Donations have since been exhausted. Thanks to everyone who contributed!]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I am personally assembling these replacement parts in my basement! Many thanks to the MEGA65 team and community donors for making this fix possible.&lt;/p&gt;
&lt;h2 id=&#34;c64-core-release-4&#34;&gt;C64 core release 4&lt;/h2&gt;
&lt;p&gt;The MEGA65 is not just a MEGA65. Thanks to its FPGA-based architecture, it can be reconfigured to behave like other computers. By far the most thorough transformation available today is the &lt;a href=&#34;https://github.com/MJoergen/C64MEGA65/blob/master/README.md&#34;&gt;Commodore 64 core&lt;/a&gt; by &lt;a href=&#34;https://github.com/MJoergen&#34;&gt;MJoergen&lt;/a&gt; and &lt;a href=&#34;http://www.sy2002.de/&#34;&gt;sy2002&lt;/a&gt;, based on the MiSTer core. This core provides a PAL-mode C64 experience with a high degree of compatibility, and has been tested thoroughly with even the most intense games and demos. The “C64 for MEGA65” earns its place in slot 2 of everyone’s computers.&lt;/p&gt;
&lt;p&gt;They’ve just announced a new &lt;a href=&#34;https://github.com/MJoergen/C64MEGA65/blob/master/VERSIONS.md&#34;&gt;release 4&lt;/a&gt; of the C64 core, which adds RAM Expansion Unit emulation and writable D64 disk images. Many aspects of the core can be configured, especially display settings, and starting with this release you can save your settings to the SD card.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://files.mega65.org/?id=896a012f-59e4-456c-b91f-7e989b958241&#34;&gt;Download the C64 core from Filehost&lt;/a&gt; and install it from the core selection menu, similar to how you upgraded the MEGA65 firmware.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;the-sound-of-ones-and-zeroes&#34;&gt;The sound of ones and zeroes&lt;/h2&gt;
&lt;p&gt;The simplest way for a computer to make sound is to send ones and zeroes to a speaker. A &amp;ldquo;one&amp;rdquo; pushes the diaphragm of the speaker all the way out; a &amp;ldquo;zero&amp;rdquo; pulls it all the way in. If the computer sends alternating ones and zeroes fast enough, we perceive the pressure wave generated by the diaphragm as sound.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/square_ideal_actual.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/square_ideal_actual.png 1395w, https://dansanderson.com/mega65/sounds-of-the-sid/square_ideal_actual_hu_a7ac68be11d711a1.png 600w, https://dansanderson.com/mega65/sounds-of-the-sid/square_ideal_actual_hu_4699b85aac07d110.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/square_ideal_actual.png&#34;
        alt=&#34;An idealized pulse wave (left) and an actual pulse wave generated by the MEGA65 SID chip (right)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
An idealized pulse wave (left) and an actual pulse wave generated by the MEGA65 SID chip (right).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The faster the computer alternates the ones and zeroes, the higher the pitch of the sound we perceive. The slower the alternations, the lower the pitch. We can describe the pitch of the sound in terms of the frequency of the repetitions, expressed as the number of repetitions per second, or Hertz (Hz). A frequency of 880 Hz is higher in pitch than a frequency of 660 Hz.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/square_freq.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/square_freq.png 1254w, https://dansanderson.com/mega65/sounds-of-the-sid/square_freq_hu_bbdabfcb50c11cb3.png 600w, https://dansanderson.com/mega65/sounds-of-the-sid/square_freq_hu_ba692387d6356412.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/square_freq.png&#34;
        alt=&#34;A pulse wave of a low frequency (left) and a high frequency (right)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A pulse wave of a low frequency (left) and a high frequency (right).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The more forcefully the computer pushes the diaphragm of the speaker, the louder the sound. This is known as the amplitude of the wave, or the volume of the sound. The computers sending ones and zeros to a speaker are beeping as loud as they can: the difference between the &amp;ldquo;one&amp;rdquo; and the &amp;ldquo;zero&amp;rdquo; is as much as it can push the speaker. If you&amp;rsquo;re lucky, such a computer has a volume knob connected that reduces the amplitude of the signal electronically before it reaches the speaker.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/square_ampl.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/square_ampl.png 1254w, https://dansanderson.com/mega65/sounds-of-the-sid/square_ampl_hu_d236df9075902f05.png 600w, https://dansanderson.com/mega65/sounds-of-the-sid/square_ampl_hu_cbe49d0c0a472193.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/square_ampl.png&#34;
        alt=&#34;A pulse wave of a high amplitude (left) and a low amplitude (right)&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
A pulse wave of a high amplitude (left) and a low amplitude (right).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;With only ones and zeroes at its disposal, it might seem like this simple computer can only make one kind of sound at different pitches, or no sound at all. In fact, it can change the nature of the sound in one other way. When it sends a &amp;ldquo;one&amp;rdquo; for a small fraction of a second then sends a &amp;ldquo;zero&amp;rdquo; for that same amount of time, and repeats this pattern at a given frequency, the computer generates a special kind of pulse wave known as a &amp;ldquo;square wave.&amp;rdquo; The computer can also differ how long it holds the &amp;ldquo;one&amp;rdquo; relative to the &amp;ldquo;zero,&amp;rdquo; known as the pulse width. The pulse width affects the timbre of the sound, a musical term referring to the nature of the tone independent of its frequency or amplitude.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/pulse_widths.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/pulse_widths.png 310w, https://dansanderson.com/mega65/sounds-of-the-sid/pulse_widths_hu_76f4dc6477a72019.png 600w, https://dansanderson.com/mega65/sounds-of-the-sid/pulse_widths_hu_647136e732bd7d7e.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/pulse_widths.png&#34;
        alt=&#34;Pulse waves of different widths, with the same frequency&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Pulse waves of different widths, with the same frequency.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s worth pausing here to admire what creative coders have done with these simple pulse waveforms. By rapidly adjusting the frequency and width of these pulses in complex patterns, computers can generate music that sounds, at least to a generous observer, &lt;a href=&#34;https://youtu.be/BjCL3KPxBUA?t=171&#34;&gt;like a band of instruments playing a tune&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;introducing-the-sid&#34;&gt;Introducing the SID&lt;/h2&gt;
&lt;p&gt;Pulses are a crude digital way to make noise. By the time of personal computers, musicians had already spent decades developing sophisticated analog sound synthesis techniques. To break free of pulse waves, computers needed analog devices that they could control digitally, entire chips dedicated to sound and music.&lt;/p&gt;
&lt;p&gt;Commodore&amp;rsquo;s solution was the MOS 6581 Sound Interface Device, now known the world over as simply &amp;ldquo;the SID chip.&amp;rdquo; The SID brought sound synthesis features previously found only in professional musical instruments to home computing, and became a defining characteristic of Commodore computers. For later models of the C128 and C64C, Commodore used an improved version with the part number 8580 with minor differences from the 6581. Audiophiles are divided as to which version sounds best. SID designer Bob Yannes went on to found the Ensoniq synthesizer company with an expanded version of the SID in its instruments.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/sidchips.jpg&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/sidchips.jpg 300w, https://dansanderson.com/mega65/sounds-of-the-sid/sidchips_hu_36bb4960820904b2.jpg 600w, https://dansanderson.com/mega65/sounds-of-the-sid/sidchips_hu_b78a7cd8467b7e78.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/sidchips.jpg&#34;
        alt=&#34;MOS Technology SID chips: the 6581, and the 8580.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MOS Technology SID chips: the 6581, and the 8580.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The SID can generate four distinct types of sound wave: pulse waves of multiple pulse widths, triangle waves, sawtooth waves, and a randomized &amp;ldquo;noise&amp;rdquo; waveform. A single SID chip has three independent signal generators, capable of three simultaneous &amp;ldquo;voices&amp;rdquo; with separate wave and volume controls that can be combined for effects or used as separate instruments. (The 8580 can even merge the waveform types, but this is seldom used.)&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/waveforms.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/waveforms.png 344w, https://dansanderson.com/mega65/sounds-of-the-sid/waveforms_hu_8a0e51f3f8c3705e.png 600w, https://dansanderson.com/mega65/sounds-of-the-sid/waveforms_hu_932a6e3853ef65fb.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/waveforms.png&#34;
        alt=&#34;Sound wave types generated by the MEGA65 SID, from top to bottom: pulse wave, triangle wave, sawtooth wave, and noise&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Sound wave types generated by the MEGA65 SID, from top to bottom: pulse wave, triangle wave, sawtooth wave, and noise.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The SID can trigger tones programmed with a volume pattern known as an &amp;ldquo;envelope” that can reproduce behaviors of musical instruments and other sound sources, such as a bowed violin or a plucked guitar. The signal generators can be synchronized and modulated with each other, and the combined output can be filtered by frequency.&lt;/p&gt;
&lt;p&gt;The SID made the Commodore 64 popular with musicians, and composers produced a long legacy of SID music for games and demos. Third-party hardware such as the &lt;a href=&#34;https://www.commodoreserver.com/BlogEntryView.asp?EID=C42BCFDCF09E4E748A0F4DEF0BC4F4D9&#34;&gt;SID Symphony cartridge&lt;/a&gt; gave the Commodore a second SID chip, and you can find many six-voice dual-SID compositions in the archives. Today, hobbyist-made devices to add a second SID chip to a C64 are widely available. The vintage SID chips themselves are getting increasingly difficult to find, though hobbyists have recreated them as FPGA-based devices that slot in to vintage and retro hardware.&lt;/p&gt;
&lt;p&gt;The MEGA65&amp;rsquo;s audio subsystem includes four SIDs as part of its FPGA architecture, for a total of twelve independent voices. The MEGA65 produces stereo audio, and by default places SIDs 1 and 2 panned slightly to the right, and SIDs 3 and 4 slightly to the left. You can adjust the mix yourself from the Freeze menu: hold &lt;kbd&gt;Restore&lt;/kbd&gt; for a second then release, then press the &lt;kbd&gt;A&lt;/kbd&gt; key to select the audio mixer utility.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/m65audiomix.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/m65audiomix.png 720w, https://dansanderson.com/mega65/sounds-of-the-sid/m65audiomix_hu_4a908a5c997fefbe.png 600w, https://dansanderson.com/mega65/sounds-of-the-sid/m65audiomix_hu_d2947254afa29f80.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/m65audiomix.png&#34;
        alt=&#34;The MEGA65 audio mixer utility, accessible from the Freeze menu.&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 audio mixer utility, accessible from the Freeze menu.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The MEGA65 also has separate hardware for playing 16-bit digitized audio samples, and room to add a Yamaha OPL FM synthesizer in a future firmware update. Altogether, MEGA65 audio represents multiple generations of microcomputer sound technology.&lt;/p&gt;
&lt;h2 id=&#34;sound-and-music-with-basic-65&#34;&gt;Sound and music with BASIC 65&lt;/h2&gt;
&lt;p&gt;MEGA65 BASIC makes it easy to include sound and music in your programs with simple commands. BASIC reserves two SID chips (six voices) for sound effects and the other two SIDs (the other six voices) for music, so effects and music never compete for resources.&lt;/p&gt;
&lt;p&gt;All sound occurs simultaneously with the action of your program: the commands return control immediately, so your program can continue to drive animations and game logic while the music plays. This powerful feature is unlike any other BASIC, which, if they have sound commands at all, typically wait for the sound to finish playing before proceeding to the next command.&lt;/p&gt;
&lt;p&gt;While these commands do not provide access to all of the features of the SID chips, they&amp;rsquo;re a quick and easy way to add sound and music to your BASIC programs.&lt;/p&gt;
&lt;h3 id=&#34;the-sound-command&#34;&gt;The SOUND command&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SOUND voice, frequency, duration,
  sweep-dir, sweep-lower-frequency, sweep-size,
  waveform, pulse-width&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;SOUND&lt;/code&gt; command plays a single sound effect. When you provide the voice number (1-6), a frequency (in Hz), and a duration, it plays a square wave:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SOUND 1,3520,90&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The duration is in a unit called a &amp;ldquo;jiffy.&amp;rdquo; The length of a jiffy depends on the MEGA65&amp;rsquo;s video mode: in PAL mode, it&amp;rsquo;s 1/50th of a second, and in NTSC mode it&amp;rsquo;s 1/60th of a second. (We&amp;rsquo;ll discuss this oddity a bit later.) So a duration of 90 in NTSC video mode would sound the tone for one and a half seconds.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;SOUND&lt;/code&gt; command can apply fun frequency sweeping effects, good for sirens, whoops, and rumbles. The sweep is described by three parameters. The first parameter is the direction of the sweep: 0 for up, 1 for down, and 2 to wobble up and down. Next is a second frequency lower than the first, defining a range that the sound will sweep between. The last sweep parameter is a duration of each repeat of the sweep. Larger numbers produce faster sweeps and more repetitions over the duration of the sound effect.&lt;/p&gt;
&lt;p&gt;Experiment with these numbers to see what sounds you get.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SOUND 1,3520,90,0,2640,50&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The command accepts additional parameters to select a different waveform or set the pulse width. If you want to use one or both of these parameters without a frequency sweep, provide empty values (just commas) for the sweep parameters.&lt;/p&gt;
&lt;p&gt;For the waveform parameter, select 0 for a triangle wave, 1 for a sawtooth wave, 2 for a pulse wave, and 3 for noise. If you select the pulse wave (the default), you can set a pulse width in the range 0-4095.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a non-sweeping triangle wave:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SOUND 1,7040,90,,,,0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This produces low noise:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SOUND 1,880,90,,,,3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A noise waveform with frequency sweeping might sound like an airplane engine sputtering:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SOUND 1,4000,45,2,2000,900,3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Try the pulse waveform with different pulse widths to see how it affects the sound of a pulse wave:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SOUND 1,4000,45,2,2000,90,2,200
SOUND 1,4000,45,2,2000,90,2,800
SOUND 1,4000,45,2,2000,90,2,2500&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;the-play-command&#34;&gt;The PLAY command&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;PLAY voice-1, voice-2, voice-3, voice-4, voice-5, voice-6&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While you could generate musical melodies using a series of &lt;code&gt;SOUND&lt;/code&gt; commands, this isn&amp;rsquo;t convenient. Instead, BASIC 65 has a featureful music system, and it&amp;rsquo;s based entirely on strings—strings of text, that is.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;PLAY&lt;/code&gt; command accepts up to six string parameters, one for each voice reserved for music. Each string describes a sequence of notes and directives to be performed by the voice. Sequences for separate voices are performed simultaneously, so you can generate harmonies and rhythms.&lt;/p&gt;
&lt;p&gt;This command plays a simple melody using a piano-like sound:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLAY &amp;#34;CEG&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are the notes C, E, and G, played in sequence with a single voice. To play them simultaneously as a chord, we give one note to each voice in separate strings:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLAY &amp;#34;C&amp;#34;,&amp;#34;E&amp;#34;,&amp;#34;G&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The directives and notes in a &lt;code&gt;PLAY&lt;/code&gt; string are evaluated in order from left to right. A directive affects all subsequent notes played by the voice, until another directive changes the effect. For example, the O directive sets the octave with a number in the range 0-6:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLAY &amp;#34;O3 CDEFGAB O4 CDEFGAB O5 C&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;PLAY&lt;/code&gt; will ignore spaces in the string, so you can organize the symbols for clarity.&lt;/p&gt;
&lt;p&gt;Each note is a letter in the diatonic C major scale: &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, &lt;code&gt;C&lt;/code&gt;, &lt;code&gt;D&lt;/code&gt;, &lt;code&gt;E&lt;/code&gt;, &lt;code&gt;F&lt;/code&gt;, or &lt;code&gt;G&lt;/code&gt;. The letter can be preceded by modifiers: the &lt;code&gt;#&lt;/code&gt; symbol to make it sharp or the &lt;code&gt;$&lt;/code&gt; symbol to make it flat. For example, &lt;code&gt;$B&lt;/code&gt; is B-flat. A note can also be the letter &lt;code&gt;R&lt;/code&gt; to specify a rest.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLAY &amp;#34;O4 RGG $BRRRGG $BRRRG$B O5 $ERDRCR CR O4 $B&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;duration-and-tempo&#34;&gt;Duration and tempo&lt;/h3&gt;
&lt;p&gt;A note is a quarter note by default. You can precede it with a letter to set its length: &lt;code&gt;W&lt;/code&gt; for whole note, &lt;code&gt;H&lt;/code&gt; for half note, &lt;code&gt;Q&lt;/code&gt; for quarter note, &lt;code&gt;I&lt;/code&gt; for eighth note, and &lt;code&gt;S&lt;/code&gt; for sixteenth note. Any of these followed by a dot (&lt;code&gt;.&lt;/code&gt;) extends the duration by half: a dotted quarter note is the same duration as three eighth notes. For example, &lt;code&gt;S#F&lt;/code&gt; is an F-sharp sixteenth note.&lt;/p&gt;
&lt;p&gt;The note duration persists for the voice like a directive, so you only need to specify it once in a run of notes with similar durations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLAY &amp;#34;O4 S#F#G#F#G#F&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can adjust the tempo for the entire song using the &lt;code&gt;TEMPO&lt;/code&gt; command. Its sole parameter is a number in the range 1-255, where larger values are faster. You can think of this value in terms of beats per minute divided by ten: &lt;code&gt;TEMPO 12&lt;/code&gt; sets the tempo at 120 bpm. (The User’s Guide defines this value as the denominator in a fraction of seconds for a whole note, which breaks my brain.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TEMPO 12&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;instruments-and-envelopes&#34;&gt;Instruments and envelopes&lt;/h3&gt;
&lt;p&gt;So far we&amp;rsquo;ve been playing a piano-like instrument. This is defined by a combination of the SID waveform type and an &amp;ldquo;envelope&amp;rdquo; that describes the volume curve for each note. The envelope consists of four segments, during which the volume increases (the attack), abates (the decay), holds (the sustain), then fades out (the release). This is what differentiates instrumental notes from the solid tones we produced with the &lt;code&gt;SOUND&lt;/code&gt; command.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/adsr.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/adsr.png 823w, https://dansanderson.com/mega65/sounds-of-the-sid/adsr_hu_5a4880b3f9a5d97b.png 600w, https://dansanderson.com/mega65/sounds-of-the-sid/adsr_hu_e2aa217a4507b068.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/adsr.png&#34;
        alt=&#34;A diagram of an Attack-Decay-Sustain-Release envelope&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The ADSR envelope shapes the volume of each sound played by the SID to synthesize notes from an instrument. The sound “attacks” up to the voice volume, “decays” down to the sustain level, holds the sustain level to the end of the sound, then “releases” to zero volume.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;BASIC 65 starts with 10 default instrument envelopes, numbered from 0 to 9: piano, accordion, calliope, drum, flute, guitar, harpsichord, organ, trumpet, and xylophone. To change the instrument being used, issue the &lt;code&gt;T&lt;/code&gt; directive followed by the number.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLAY &amp;#34;T6 O4CECGCO5C&amp;#34;
PLAY &amp;#34;T8 O4CECGCO5C&amp;#34;
PLAY &amp;#34;T9 O4CECGCO5C&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some of the instruments are more convincing than others, and may require some experimentation to fit your song.&lt;/p&gt;
&lt;p&gt;You can overwrite any of the ten instrument slots with your own definition. See the &lt;code&gt;ENVELOPE&lt;/code&gt; command in the User&amp;rsquo;s Guide for more information.&lt;/p&gt;
&lt;h3 id=&#34;looping-waiting-and-silencing&#34;&gt;Looping, waiting, and silencing&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;L&lt;/code&gt; directive tells the &lt;code&gt;PLAY&lt;/code&gt; command to loop to the beginning of the string. This is great for background music that needs to play indefinitely. Remember to loop all voices for a piece of music in the same place—or loop them in different places for interesting effects! For instance, you can have a short loop for drums and a long loop for verses and choruses.&lt;/p&gt;
&lt;p&gt;Issuing a new &lt;code&gt;PLAY&lt;/code&gt; command with a new sequence for a voice that&amp;rsquo;s currently playing will stop the current sequence and start the new one. If you want a voice to continue playing while you issue a new sequence to a different voice, leave an empty parameter.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLAY &amp;#34;CEGBGEL&amp;#34;  :rem  a loop for voice 1
PLAY ,&amp;#34;EDCDEGE&amp;#34; :rem  a sequence for voice 2, does not interrupt voice 1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want your program to wait until a &lt;code&gt;PLAY&lt;/code&gt; sequence has completed, use the `RPLAY(n)`` function to test whether a voice is currently sounding. It takes the voice number as a parameter, and returns 1 if that voice is making sound, or 0 otherwise.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 PLAY &amp;#34;O4CECGCO5C&amp;#34;
20 BORDER 0
30 IF RPLAY(1) THEN 30
40 BORDER 6&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To silence all voices, issue the &lt;code&gt;PLAY&lt;/code&gt; command without parameters. You will probably use this often when debugging games with background music, as the music will keep playing after the program halts with an error.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLAY&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;learning-more-about-play&#34;&gt;Learning more about PLAY&lt;/h3&gt;
&lt;p&gt;When you first turned on your MEGA65, it loaded the demo disk menu with some jaunty background music. This menu is a BASIC program, and the music is produced by the &lt;code&gt;PLAY&lt;/code&gt; command. Run the menu, exit to BASIC, then &lt;code&gt;LIST&lt;/code&gt; the program to find the &lt;code&gt;PLAY&lt;/code&gt; statements.&lt;/p&gt;
&lt;p&gt;The User&amp;rsquo;s Guide describes a few more features of the &lt;code&gt;PLAY&lt;/code&gt; command not covered here. The &lt;code&gt;PLAY&lt;/code&gt; command can actuate the ring modulation feature of the SID, an effect that involves combining multiple voices in a complex way, so you&amp;rsquo;ll want to read more about that. &lt;code&gt;PLAY&lt;/code&gt; can also enable and disable the filter on the SID; filter parameters can be set with the &lt;code&gt;FILTER&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Remember that &lt;code&gt;PLAY&lt;/code&gt; sequences are BASIC strings. This means you can assemble and manipulate these strings as values before passing them as arguments to &lt;code&gt;PLAY&lt;/code&gt;. This also means they are constrained by the BASIC limit of 255 characters per string. If you run out of string, you might consider breaking your composition into parts, and using &lt;code&gt;RPLAY()&lt;/code&gt; to wait for each part to finish before &lt;code&gt;PLAY&lt;/code&gt;ing the next part.&lt;/p&gt;
&lt;p&gt;The best way to learn is to experiment! Remember that you can always reset the computer and try again.&lt;/p&gt;
&lt;h2 id=&#34;whats-pal-got-to-do-with-it&#34;&gt;What&amp;rsquo;s PAL got to do with it?&lt;/h2&gt;
&lt;p&gt;Earlier, we said the &lt;code&gt;SOUND&lt;/code&gt; command measures duration differently depending on which video mode your MEGA65 is in: PAL or NTSC. Why would the video mode have anything to do with playing sound?&lt;/p&gt;
&lt;p&gt;Programs that play music are sensitive to timing. They need to execute code with strict regularity to make sure the music keeps up with the beat. Commodore games and demos typically tie their playback loops to another part of the architecture that keeps strict time: the video chip. Using raster interrupts, they set up their code to trigger each time the video chip refreshes the screen. The screen refreshes an exact number of times per second, so this is a good way to advance to the next step in a music composition with strict regularity. It&amp;rsquo;s like turning the cylinder of a music box at a steady pace.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s just one problem with tying playback to the video refresh rate: the PAL and NTSC video standards used different rates! Commodore made different versions of their computers for the analog video standards in the countries where they were sold, PAL in Europe and NTSC in the United States and Japan. (In countries that used a third standard called SECAM, Commodore sold PAL computers with video adapters.) PAL refreshed the screen at 50 Hz, and NTSC refreshed at 60 Hz. In many cases, games and demos written for one video standard played too slowly, too quickly, or not at all on a computer built for the other standard. It’s possible to write a program that works similarly for both, but this requires additional effort, and few people had both kinds of computers to test with.&lt;/p&gt;
&lt;p&gt;The MEGA65 outputs a modern digital video signal that supports multiple refresh rates. For compatibility with older software, the MEGA65 continues to honor PAL and NTSC as separate video modes, including their raster timings. Many modern digital displays will honor both modes, but some of us have older displays that get confused by one or the other. You may or may not remember setting your default video mode when you turned on your MEGA65 for the first time.&lt;/p&gt;
&lt;p&gt;You can check which mode you&amp;rsquo;re in, and change it, in the Freeze menu: hold Restore for a second then release, then locate the Video setting (PAL50 or NTSC60). Press the V key to switch between them. If a game or demo isn&amp;rsquo;t running correctly for you and your display supports both modes, try switching modes and running the program again.&lt;/p&gt;
&lt;h2 id=&#34;pal-vs-ntsc-survey&#34;&gt;PAL vs. NTSC survey!&lt;/h2&gt;
&lt;p&gt;Can the display you use with your MEGA65 support both PAL and NTSC video modes, or just one or the other? Developers want to know!&lt;/p&gt;
&lt;p&gt;MEGA65 musician and demo coder deathy has set up a one-question survey that asks which video modes your set-up supports. Please take a moment to answer it. It&amp;rsquo;ll be a big help to MEGA65 game and demo developers!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.surveymonkey.com/r/BBFR5WG&#34;&gt;PAL vs. NTSC survey for MEGA65 owners&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;[Update: Some readers have reported that SurveyMonkey is failing to show the survey correctly in some European countries. You might be able to copy-paste the URL after visiting it: &lt;code&gt;https://www.surveymonkey.com/r/BBFR5WG&lt;/code&gt; ]&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;xanadu&#34;&gt;Xanadu&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/xanadu.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/xanadu.jpg 817w, https://dansanderson.com/mega65/sounds-of-the-sid/xanadu_hu_2bbc7ed9d173f1d5.jpg 600w, https://dansanderson.com/mega65/sounds-of-the-sid/xanadu_hu_93852fdcd03baeed.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/sounds-of-the-sid/xanadu.jpg&#34;
        alt=&#34;Screenshot from Xanadu, a demo for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Xanadu, a demo for the MEGA65 by deathy.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&#34;https://syntaxparty.org/&#34;&gt;Syntax 2022&lt;/a&gt;, the 16th annual demo party in Melbourne, Australia, took place this month, and the MEGA65 was there! deathy and MEGA65 contributor Gurce, both members of the BAS demo group, produced “Xanadu,” a two-part tribute to the late Olivia Newton-John.&lt;/p&gt;
&lt;p&gt;Part one is written in assembly language and features an arrangement of the Newton-John classic using all four SID chips. Part two offers another take, this time rendered entirely in BASIC with the &lt;code&gt;PLAY&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Download the D81 disk image and run it on your MEGA65 today!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org/?id=b42c7878-1848-43eb-85b9-b0792c7df804&#34;&gt;Xanadu for the MEGA65&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;There&amp;rsquo;s plenty more to say about music on the MEGA65, but it&amp;rsquo;ll have to wait for future issues. Until next time, thanks for listening!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/sounds-of-the-sid/M65Digest_03_2022Nov.mp3" length="34165467" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1708</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/sounds-of-the-sid/sidchips.jpg"/>
      
    </item>
    
    <item>
      <title>MEGA65 Adventures</title>
      <link>https://dansanderson.com/mega65/mega65-adventures/</link>
      <pubDate>Tue, 18 Oct 2022 00:10:59 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/mega65-adventures/</guid>
      <description>&lt;p&gt;MEGA65 Adventures! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for October 2022.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;MEGA65 Adventures! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for October 2022.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/mega65-adventures/M65Digest_02_2022Oct.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/mega65-adventures/M65Digest_02_2022Oct.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
MEGA65 Adventures!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Personal computers in the early 1980s ignited the home video gaming industry with their ability to display animated color graphics. Even so, the games with the best images were the ones with no graphics at all. Text adventure games told tales of fantasy, mystery, and suspense with you as the protagonist, rendering entire worlds using only the written word and your imagination.&lt;/p&gt;
&lt;p&gt;The effectiveness of the medium and the limited hardware requirements have made text games the longest living and most widely supported form. Archivists, hobbyists, and game authors have reverse engineered and ported vintage text games to modern computers, and evolved the form into the modern day. Thanks to members of our community who have continued that work, you can play a vast legacy of interactive fiction—everything from classic games to new releases—on your MEGA65.&lt;/p&gt;
&lt;h2 id=&#34;hibernated-1-directors-cut&#34;&gt;Hibernated 1: Director&amp;rsquo;s Cut&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;A Cold Dark Place
You wake up. A feeling of nausea grips you as you slowly
regain control of your senses. You should open your eyes.

&amp;gt;open eyes
Blurred shapes slowly morph into a clear picture. It
takes a moment for you to find your way back to reality.
Has the Polaris-7 reached its destination? Still a bit
shaky on your legs you climb out of the hypersleep tube.

Hibernation Chamber
The room is lit by a gentle blue light. A glance through
the porthole reveals nothing but the endless vastness of
the Centaurus constellation. Proxima Centauri must be
very close now. But there is no planetary orbit in sight.
It seems an incident has interrupted your journey to
Proxima C1. The only exit is starboard.

The status monitor of the hypersleep tube flashes
intrusively.

&amp;gt;examine monitor
If this information is correct, then you have spent
nearly 20 years in hypersleep. During this time a
distance of about 4.1 light-years was covered. Proxima
Centauri is 4.24 light-years away from Sol, which
confirms the assumption that you haven&amp;#39;t reached the
target system yet. What&amp;#39;s going on here?&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In &lt;em&gt;Hibernated 1&lt;/em&gt; by Stefan Vogt, you play Olivia Lund, a space-faring explorer whose long voyage to Alpha Centauri is interrupted by a mysterious alien vessel. With your artificial intelligence companion Io, you must board the vessel and learn its secrets to break free of its tractor beam.&lt;/p&gt;
&lt;p&gt;To play a text adventure game, you describe the actions of your character in abbreviated English commands. The story proceeds with each action, so you can take your time to read descriptions for clues and work out solutions to puzzles. In &lt;em&gt;Hibernated 1&lt;/em&gt;, you navigate around spaceships (yours and theirs) with commands like &lt;code&gt;starboard&lt;/code&gt;, &lt;code&gt;port&lt;/code&gt;, &lt;code&gt;fore&lt;/code&gt;, and &lt;code&gt;aft&lt;/code&gt;. You can also &lt;code&gt;examine&lt;/code&gt; objects to investigate your surroundings.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;starboard

Lower Corridor
Flashing red warning lights are reflected on the
palladium glass. From here, you&amp;#39;re able to reach every
section of the ship. The hibernation chamber is port,
while your private area is starboard. The docking bay
lies aft.

The passage fore, leading to the Polaris-7 command unit,
is barred by a massive security door. It divides the
narrow corridor into two halves.

&amp;gt;examine lights
Looks like we have a problem.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some objects can be taken, carried, and used at various points in the story. Others are fixed in place, and you must remember where they are and come back to them when needed. When playing text adventures, it is critical to take notes and draw maps in a paper notebook so you don&amp;rsquo;t lose your way.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;aft

Docking Bay
You stand in a desolate hall. This is the section where
raw materials and samples of foreign origin must be
stored, according to the Terran Alliance directive.
Fore you get back to the corridor. An airlock aft allows
you to leave the Polaris-7.

A laser rifle is leaning against the wall.

You also notice your spacesuit.

&amp;gt;take rifle
Taken.

&amp;gt;take spacesuit
Taken.

&amp;gt;wear spacesuit
You are now wearing the spacesuit.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Stefan originally released &lt;em&gt;Hibernated 1&lt;/em&gt; for the Commodore 64 and several other systems in 2018. In 2021, he rewrote the game with a revised story and puzzles, and published the &amp;ldquo;Director&amp;rsquo;s Cut&amp;rdquo; for a whopping twenty-eight (28) microcomputer platforms. You can even play it on a modern computer. &lt;em&gt;Hibernated 1: Director&amp;rsquo;s Cut&lt;/em&gt; is available for the MEGA65, with an 80-column text display and the ability to save your progress to disk.&lt;/p&gt;
&lt;p&gt;You can download &lt;a href=&#34;https://8bitgames.itch.io/hibernated1&#34;&gt;&lt;em&gt;Hibernated 1&lt;/em&gt; from 8bitgames.itch.io&lt;/a&gt;. The download is free of charge; donations to the developer are welcome.&lt;/p&gt;
&lt;p&gt;For an authentic vintage software experience, you can purchase &lt;a href=&#34;https://www.polyplay.xyz/Hibernated-1-Directors-Cut-MEGA65_1&#34;&gt;a physical boxed edition of &lt;em&gt;Hibernated 1&lt;/em&gt; for the MEGA65&lt;/a&gt; from publisher poly.play. The physical edition comes on a 3-1/2&amp;quot; floppy disk that you can use with your MEGA65&amp;rsquo;s floppy drive, in a gorgeous display box designed to resemble the games we used to buy in computer stores. And just like Infocom games back in the day, the box is packed with extras.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-adventures/hibernated-1-directors-cut-mega65.jpg&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/mega65-adventures/hibernated-1-directors-cut-mega65.jpg 1120w, https://dansanderson.com/mega65/mega65-adventures/hibernated-1-directors-cut-mega65_hu_71f7aeff189039f4.jpg 600w, https://dansanderson.com/mega65/mega65-adventures/hibernated-1-directors-cut-mega65_hu_5bbebabf6682e88b.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-adventures/hibernated-1-directors-cut-mega65.jpg&#34;
        alt=&#34;Hibernated 1: Director&amp;amp;#39;s Cut display box&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Hibernated 1: Director&#39;s Cut physical edition for the MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The physical edition of &lt;em&gt;Hibernated 1: Director&amp;rsquo;s Cut&lt;/em&gt; qualifies as the first commercial title for the MEGA65. If boxed software appeals to you, you might also be interested in the second qualifying title, &lt;a href=&#34;https://www.polyplay.xyz/Showdown-Collectors-Edition-MEGA65_1&#34;&gt;&lt;em&gt;Showdown&lt;/em&gt; by Badger Punch Games&lt;/a&gt;, a two-player action game for the MEGA65 available in a display box from poly.play and as a &lt;a href=&#34;https://badgerpunch.itch.io/showdown-mega65&#34;&gt;download from badgerpunch.itch.io&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-is-the-z-machine&#34;&gt;What is the Z-machine?&lt;/h2&gt;
&lt;p&gt;The most famous name in text adventures is Infocom, an American software company founded in 1979. Their most famous game was &lt;em&gt;Zork&lt;/em&gt;, a treasure hunting adventure that begins in a boarded up cottage in the woods. Infocom published 36 original text adventures over ten years, including several &lt;em&gt;Zork&lt;/em&gt; sequels and an adaptation of &lt;em&gt;The Hitchhiker&amp;rsquo;s Guide to the Galaxy&lt;/em&gt; by Douglas Adams.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-adventures/Infocom.png&#34;&gt;
    &lt;img class=&#34;no-border&#34;
        srcset=&#34;https://dansanderson.com/mega65/mega65-adventures/Infocom.png 1280w, https://dansanderson.com/mega65/mega65-adventures/Infocom_hu_72162ed4ba82e1f1.png 600w, https://dansanderson.com/mega65/mega65-adventures/Infocom_hu_e1ac2d6369114be.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-adventures/Infocom.png&#34;
        alt=&#34;Infocom logo&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Infocom logo.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Key to Infocom&amp;rsquo;s early success was the ability to publish versions of their games for multiple microcomputer platforms simultaneously. All games were written in a custom programming language that ran on a common engine known as the Z-machine (Z for Zork). Infocom made versions of the Z-machine for every major microcomputer from the Apple II to the Amiga. This effectively erased the difference between each type of computer as far as the game&amp;rsquo;s Z-machine code was concerned: the story could be written once, compiled to Z-code, then interpreted by each platform&amp;rsquo;s Z-machine to play the game. When a new kind of computer came to market, Infocom simply built a new Z-machine for it, then re-released their entire catalog.&lt;/p&gt;
&lt;p&gt;The longevity of this strategy continues to this day, over 40 years later. After Infocom ceased operations, hobbyists reverse engineered and documented &lt;a href=&#34;https://www.inform-fiction.org/zmachine/standards/&#34;&gt;the Z-machine standard&lt;/a&gt;. It&amp;rsquo;s a fun coding exercise to build your own Z-machine that can run Infocom story files, and &lt;a href=&#34;https://www.ifwiki.org/List_of_Z-machine_interpreters&#34;&gt;implementations exist&lt;/a&gt; for nearly every modern computer. This is how Stefan released &lt;em&gt;Hibernated 1: Director&amp;rsquo;s Cut&lt;/em&gt; for twenty-eight computers simultaneously: it&amp;rsquo;s a game written for Z-machines.&lt;/p&gt;
&lt;p&gt;The Z-machine is a popular target for modern authors thanks to its ubiquity. The annual &lt;a href=&#34;https://ifcomp.org/&#34;&gt;Interactive Fiction Competition&lt;/a&gt; gets new entries in this format every year, and you can find plenty more via the &lt;a href=&#34;https://ifdb.org/&#34;&gt;Interactive Fiction Database&lt;/a&gt;. Be sure to look for game files with names with endings such as &lt;code&gt;.z3&lt;/code&gt;, &lt;code&gt;.z5&lt;/code&gt; or &lt;code&gt;.z8&lt;/code&gt;. (There are several other formats used for interactive fiction, including Glulx, TADS, Twine, and more.)&lt;/p&gt;
&lt;h2 id=&#34;ozmoo&#34;&gt;Ozmoo&lt;/h2&gt;
&lt;p&gt;Ozmoo is a Z-machine player by Johan Berntsson and Fredrik Ramsberg for the MEGA65, Commodore 64, Commodore 128, and Commodore Plus/4. It&amp;rsquo;s a modern take on the idea, capable of taking advantage of each machine&amp;rsquo;s capabilities to their fullest extent, especially when extra memory is available. Ozmoo can run pretty much any game written for the Z-machine, including nearly all Infocom games and most modern Z-machine games.&lt;/p&gt;
&lt;p&gt;Infocom experimented with sound effects and still graphics for a few of their games. Ozmoo supports the ones with sound effects, but not the ones with graphics (&amp;ldquo;v6&amp;rdquo; files).&lt;/p&gt;
&lt;p&gt;The best way to get Ozmoo games for your MEGA65 is with &lt;a href=&#34;https://microheaven.com/ozmooonline/&#34;&gt;Ozmoo Online&lt;/a&gt;, a web-based utility that can convert any compatible Z-machine game file into a playable D81 disk image. Ozmoo is free and open source, and you can learn more about it from &lt;a href=&#34;https://github.com/johanberntsson/ozmoo&#34;&gt;the Ozmoo Github repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Fredrik, known as fredrikr on the Discord, has done a ton of great work to make interactive fiction available to the MEGA65 community. For starters, Ozmoo Online has every classic Infocom game available for download. Simply select one of the provided story files from the menu instead of uploading one.&lt;/p&gt;
&lt;p&gt;Be sure to select MEGA65 as the platform, and &amp;ldquo;81&amp;rdquo; as the build mode. I also recommend enabling the scrollback buffer, a handy feature of Ozmoo that works well with the MEGA65&amp;rsquo;s &amp;ldquo;AtticRAM&amp;rdquo; extended memory.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-adventures/ozmooonline.png&#34;&gt;
        &lt;img 
            src=&#34;https://dansanderson.com/mega65/mega65-adventures/ozmooonline.png&#34;
            width=&#34;585&#34;
            height=&#34;479&#34;
            alt=&#34;Ozmoo Online settings for the MEGA65&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Ozmoo Online settings for the MEGA65.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Fredrik has packaged the two Infocom games with sound files as a separate MEGA65 download. You can find it on Filehost:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=d02dbdc4-6e1e-4f27-9656-a56b69ca0ca0&#34;&gt;Infocom sound games&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;re playing Infocom games, you&amp;rsquo;ll also want the original game manuals. You can download PDF scans of these from &lt;a href=&#34;http://infodoc.plover.net&#34;&gt;infodoc.plover.net&lt;/a&gt;. Some of the manuals contain information required to finish the games.&lt;/p&gt;
&lt;p&gt;The interactive fiction community has been developing new Z-machine games for decades. Fredrik has bundled a selection of the best of these, using Ozmoo for the MEGA65. These are also on Filehost:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=0998bc5f-bc8f-4264-8843-23ecd036ac2b&#34;&gt;The MEGA65 Z-code Text Adventure Collection Pack #1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=0ed2c658-7547-4892-babb-e42fd04799ac&#34;&gt;The MEGA65 Z-code Text Adventure Collection Pack #2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org/html/main.php?id=1f98a9e4-8c7f-4a5b-8f6e-32c4e885679c&#34;&gt;Game Book Collection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Need more? Try these text adventures written by MEGA65 owners, including two by Fredrik himself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=615301eb-be89-4cf1-a109-79c8ae03dcaf&#34;&gt;The Job&lt;/a&gt;, by fredrikr&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=ccd831f8-ca73-4c51-828d-2089aabf126a&#34;&gt;Vacation Gone Awry&lt;/a&gt;, by fredrikr&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=7f303a4e-e1f7-46f0-924d-c1e62a75b7d9&#34;&gt;Arthur&amp;rsquo;s Day Out&lt;/a&gt;, by WauloK&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://files.mega65.org?id=b4439ca4-5331-462a-8b5c-a1c5be1acf75&#34;&gt;Brotquest 2&lt;/a&gt;, by EgonOlson71&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;writing-a-z-machine-game&#34;&gt;Writing a Z-machine game&lt;/h2&gt;
&lt;p&gt;Infocom used their own custom language called &amp;ldquo;&lt;a href=&#34;https://www.ifwiki.org/ZIL&#34;&gt;ZIL&lt;/a&gt;&amp;rdquo; to write their games. Contemporary authors use a family of languages called Inform, specifically Inform 6 and Inform 7. A newer language called Dialog is also worth a look, especially when writing games for microcomputers.&lt;/p&gt;
&lt;h3 id=&#34;inform-6&#34;&gt;Inform 6&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.inform-fiction.org/&#34;&gt;Inform 6&lt;/a&gt; is a programming language for writing Infocom-style adventure games for the Z-machine. Typically, you use it with the Inform 6 standard library, which implements a wide range of useful object properties (doors, keys, containers, food) and player verbs (open, unlock, put in, eat). The Inform 6 compiler is a command-line tool that takes an Inform 6 source file and produces a Z-machine game file.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a tiny excerpt of how a bit of the Docking Bay in &lt;em&gt;Hibernated 1&lt;/em&gt; might be implemented. (This is not the actual code. Among many things, I&amp;rsquo;ve omitted code that replaces &amp;ldquo;north&amp;rdquo; and &amp;ldquo;south&amp;rdquo; with shipboard directions &amp;ldquo;fore&amp;rdquo; and &amp;ldquo;aft.&amp;rdquo;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Object docking_bay &amp;#34;Docking Bay&amp;#34;
with description &amp;#34;You stand in a desolate hall. This is
    the section where raw materials and samples of
    foreign origin must be stored, according to the
    Terran Alliance directive. Fore you get back to the
    corridor. An airlock aft allows you to leave the
    Polaris-7.&amp;#34;
n_to lower_corridor,
s_to airlock,
has light;

Object rifle &amp;#34;laser rifle&amp;#34; docking_bay
with
    name &amp;#39;rifle&amp;#39; &amp;#39;laser&amp;#39; &amp;#39;gun&amp;#39;,
    initial &amp;#34;A laser rifle is leaning against the wall.&amp;#34;,
    description &amp;#34;The rifle supports two modes: paralyze and
        disintegrate.&amp;#34;;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Even though Inform 6 is intended to build to the Z-machine format, its standard library was written with modern computers in mind, and tends to produce game files too large to run on vintage microcomputers. Ozmoo co-author Johan Berntsson produced &lt;a href=&#34;https://github.com/johanberntsson/PunyInform&#34;&gt;PunyInform&lt;/a&gt;, a replacement for the Inform 6 standard library optimized for low memory computers like the Commodore 64. You use PunyInform with the Inform 6 compiler.&lt;/p&gt;
&lt;p&gt;macOS and Linux users can &lt;a href=&#34;https://www.ifarchive.org/indexes/if-archive/infocom/compilers/inform6/source/&#34;&gt;download the Inform 6 source bundle&lt;/a&gt; with everything you need, including the Inform 6 compiler, standard library, and PunyInform. The &lt;a href=&#34;https://www.ifarchive.org/indexes/if-archive/infocom/compilers/inform6/&#34;&gt;Interactive Fiction Archive&lt;/a&gt; also has pre-built versions of Inform 6 for many platforms, library add-ons, and plenty of example code. I recommend using Visual Studio Code to write Inform 6 games: there are extensions available that allow you to compile &lt;em&gt;and play&lt;/em&gt; your game directly in the editor.&lt;/p&gt;
&lt;p&gt;The definitive book about the Inform 6 language is &lt;a href=&#34;https://www.inform-fiction.org/manual/html/index.html&#34;&gt;The Inform Designer&amp;rsquo;s Manual&lt;/a&gt; by Inform&amp;rsquo;s creator Graham Nelson. It&amp;rsquo;s exceptionally well written and includes general information about interactive fiction and game design, as well as a tour of the language and its library. I consider it a classic text, and recommend it to anyone with even a casual interest in the subject. &lt;a href=&#34;http://inform-fiction.org/manual/index.html&#34;&gt;Read it online&lt;/a&gt;, or buy it in &lt;a href=&#34;https://www.amazon.com/Inform-Designers-Manual-Graham-Nelson/dp/0971311935/&#34;&gt;hardcover&lt;/a&gt; or &lt;a href=&#34;https://www.amazon.com/Inform-Designers-Manual-Graham-Nelson/dp/0971311900/&#34;&gt;paperback&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;inform-7&#34;&gt;Inform 7&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://ganelson.github.io/inform-website/&#34;&gt;Inform 7&lt;/a&gt; is a newer language and authoring system for narrative game writing. It&amp;rsquo;s a radical departure from Inform 6, using a logical programming paradigm and a natural language syntax, so source code reads like English prose. Inform 7 also includes a friendly authoring application where you can write an Inform 7 game, test it, read high quality documentation, and even develop automated tests that put your game through its paces.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how that Docking Bay example would be written in Inform 7 (again, not the actual code):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Docking Bay is a room. &amp;#34;You stand in a desolate hall.
This is the section where raw materials and samples of
foreign origin must be stored, according to the Terran
Alliance directive. Fore you get back to the corridor.
An airlock aft allows you to leave the Polaris-7.&amp;#34;

The Docking Bay is south of the Lower Corridor. The
Docking Bay is north of the Airlock.

A laser rifle is in the Docking Bay. Understand &amp;#34;rifle&amp;#34;
and &amp;#34;laser&amp;#34; and &amp;#34;gun&amp;#34; as the laser rifle. &amp;#34;A laser
rifle is leaning against the wall.&amp;#34; The description of
the laser rifle is &amp;#34;The rifle supports two modes:
paralyze and disintegrate.&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inform 7 is designed to be accessible to authors without a computer programming background, but it doesn&amp;rsquo;t skimp on computational power or expressiveness. Some programmers prefer Inform 6 because it looks more like a programming language. Most new language innovation is happening with Inform 7.&lt;/p&gt;
&lt;p&gt;The only reason I didn&amp;rsquo;t give Inform 7 top billing in this section is that games made with Inform 7 tend to run slowly on microcomputers. The MEGA65 version of Ozmoo can handle simple Inform 7 games with the &amp;ldquo;Inform 7 XL Stack&amp;rdquo; option enabled in Ozmoo Online, but they tend to be too slow to play.&lt;/p&gt;
&lt;p&gt;For making Z-machine games for the MEGA65, stick with Inform 6. If you also want your game to run on smaller machines like the Commodore 64, use PunyInform instead of the Inform standard library.&lt;/p&gt;
&lt;h3 id=&#34;dialog&#34;&gt;Dialog&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://linusakesson.net/dialog/index.php&#34;&gt;Dialog&lt;/a&gt; is another modern take on writing interactive fiction by Linus Åkesson. It borrows ideas from Inform 7 and the Prolog programming language, with an emphasis on minimalism, clarity, and performance. Dialog brings some of the best language design ideas to games that can be played on vintage microcomputers with Z-machine players. Like Inform, Dialog includes a rich standard library that makes starting new stories easy.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s my novice attempt at describing the Docking Bay in Dialog:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#docking-bay
(room *)
(name *) Docking Bay
(look *)
    You stand in a desolate hall. This is the section where
    raw materials and samples of foreign origin must be
    stored, according to the Terran Alliance directive.
    Fore you get back to the corridor. An airlock aft
    allows you to leave the Polaris-7.
(from * go #north to #lower-corridor)
(from * go #south to #airlock)

#rifle
(item *)
(name *)   laser rifle
(descr *)  The rifle supports two modes: paralyze and
    disintegrate.
(appearance *)  A laser rifle is leaning against the wall.
(dict *)    rifle laser gun
(* is #in #docking-bay)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dialog includes a command-line compiler and a handy interactive debugger. The software bundle includes pre-built tools for Windows and Linux, and it&amp;rsquo;s easy to build them from source on macOS. Linus also has his own alternative to the Z-machine, which he calls the &lt;a href=&#34;https://linusakesson.net/dialog/aamachine/&#34;&gt;Å-machine&lt;/a&gt;, optimized for converting Dialog games to playable web pages and Commodore 64 disk images.&lt;/p&gt;
&lt;h2 id=&#34;adventures-in-basic&#34;&gt;Adventures in BASIC&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve always been interested in how computers can be used to tell stories. One of my favorite books as a kid was &lt;a href=&#34;https://archive.org/details/tibook_creating-adventure-games-on-your-computer&#34;&gt;&lt;em&gt;Creating Adventure Games on Your Computer&lt;/em&gt;&lt;/a&gt; by Tim Hartnell (1983, Ballantine Books). In fewer than 200 pages, Hartnell covers game design, BASIC coding techniques, and several fully playable adventure games that you can type in, play, and modify.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-adventures/adventurebooks.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/mega65-adventures/adventurebooks.png 600w, https://dansanderson.com/mega65/mega65-adventures/adventurebooks_hu_a427d02bd3713332.png 600w, https://dansanderson.com/mega65/mega65-adventures/adventurebooks_hu_1117eff30228e28.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/mega65-adventures/adventurebooks.png&#34;
        alt=&#34;Book covers for four vintage text adventure game books&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Four vintage text adventure game BASIC books.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I love the title of the kid&amp;rsquo;s book &lt;a href=&#34;https://archive.org/details/write-your-own-program-creating-a-database-adventure-game&#34;&gt;&lt;em&gt;Creating a Database Adventure Game&lt;/em&gt;&lt;/a&gt; by Steve Rodgers and Marcus Milton (1985, Aladdin Books). It&amp;rsquo;s a genuine insight that adventure games are like explorable databases: tables of values that describe the state of the world, and long strings of text that become the game&amp;rsquo;s narrative based on the player&amp;rsquo;s actions.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://archive.org/details/adventure-programs/mode/2up&#34;&gt;&lt;em&gt;Write Your Own Adventure Programs&lt;/em&gt;&lt;/a&gt; by Jenny Tyler and Les Howarth (1983, Usborne Publishing) is another, with excellent visualizations of how BASIC programs are structured. Both of these books use a grid structure to represent the game world, with each cell a location with potential exits in the four cardinal directions (north, east, south, west).&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://archive.org/details/Compute_s_Guide_to_Adventure_Games&#34;&gt;&lt;em&gt;Compute!&amp;rsquo;s Guide to Adventure Games&lt;/em&gt;&lt;/a&gt; by Gary McGath (1984, Compute! Books) only dedicates a few chapters at the end to authorship, but it includes useful advice on structured programming and a short type-in. Most of the book is a catalog of the state of adventure games of the era, summarizing their stories and reviewing their features. Infocom gets its own chapter.&lt;/p&gt;
&lt;p&gt;Of all the books on BASIC that came out of the 1980s, the ones about adventure games were some of the most informative and inspirational. They described how to organize large programs, how to design and implement data structures beyond simple variables, and how to build a game engine as much as a game. And they showed how evocative text games can be, even with no graphics, simple command parsers, and short text descriptions. You can read these vintage BASIC books and others on &lt;a href=&#34;https://archive.org/&#34;&gt;Archive.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was going to write up a bunch of tips for coding adventure games in MEGA65 BASIC for this Digest, but we&amp;rsquo;re running a little long. Instead, here&amp;rsquo;s a brief example of a technique for representing a world map that&amp;rsquo;s common to most vintage BASIC books on the subject: the travel table.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s say our game takes place on the Polaris 7, Olivia&amp;rsquo;s ship from &lt;em&gt;Hibernated 1&lt;/em&gt;. At the beginning of the game, Olivia can access five rooms: the Hibernation Chamber, the Lower Corridor, the Private Area, the Docking Bay, and the Airlock. Olivia can navigate these rooms by traveling fore, aft, starboard, or port, according to the entrances and exits to each room.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/mega65-adventures/h1map.png&#34;&gt;
        &lt;img class=&#34;no-border&#34;
            src=&#34;https://dansanderson.com/mega65/mega65-adventures/h1map.png&#34;
            width=&#34;479&#34;
            height=&#34;354&#34;
            alt=&#34;A map of five rooms on the Polaris 7&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Five rooms on the Polaris 7.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For this example, we&amp;rsquo;ll go with the simplest possible command parser. We&amp;rsquo;ll use an &lt;code&gt;INPUT&lt;/code&gt; statement to accept the command, and compare the value against the four directional commands. If a command is recognized, it is converted into a number from 0 to 3 in the C variable, and processing continues on line 380. Otherwise it is rejected with a message, and control loops back to the &lt;code&gt;INPUT&lt;/code&gt; statement.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100 DIM CM$(4):FOR I=0 TO 3:READ CM$(I):NEXT
110 DATA FORE,AFT,STARBOARD,PORT

300 INPUT C$
310 PRINT
320 C=-1:FOR I=0 TO 3
330 IF C$=CM$(I) THEN C=I
340 NEXT I
350 IF C&amp;lt;&amp;gt;-1 THEN 380
360 PRINT &amp;#34;I DON&amp;#39;T UNDERSTAND.&amp;#34;
370 GOTO 300&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The travel table is a two-dimensional array, with one row for each room, and one column for each movement direction. The value of a cell represents the exit for that room in that direction. If the value is a room number, that is the destination of the exit. If the value is 0, then there is no exit in that direction. We reserve room #0 for this purpose, so room numbering starts at #1. For example, the Docking Bay has an exit fore to the Lower Corridor (room #2). Fore is direction 0, so the Docking Bay&amp;rsquo;s zero-th column in the travel table is 2.&lt;/p&gt;
&lt;p&gt;We initialize the &lt;code&gt;TT(room, direction)&lt;/code&gt; array by reading the map data from &lt;code&gt;DATA&lt;/code&gt; statements. For convenience, we put the room names on the same lines in the &lt;code&gt;DATA&lt;/code&gt; statements and read them into the &lt;code&gt;RO$(room)&lt;/code&gt; array.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;120 DIM TT(6,4):DIM RO$(6)
130 FOR I=1 TO 5
140 FOR J=0 TO 3:READ TT(I,J):NEXT J
150 READ RO$(I)
160 NEXT I
180 DATA 0,0,2,0,&amp;#34;HIBERNATION CHAMBER&amp;#34;
190 DATA 0,4,3,1,&amp;#34;LOWER CORRIDOR&amp;#34;
200 DATA 0,0,0,2,&amp;#34;PRIVATE AREA&amp;#34;
210 DATA 2,5,0,0,&amp;#34;DOCKING BAY&amp;#34;
220 DATA 4,0,0,0,&amp;#34;AIRLOCK&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Olivia begins the game in the Hibernation Chamber, room 1. The &lt;code&gt;PL&lt;/code&gt; variable stores her location. At the top of the game loop, we tell the player where they are, and which directions from the current room have exits—that is, are non-zero in the travel table.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;230 PL=1
240 PRINT CHR$(13)+&amp;#34;YOU ARE IN THE &amp;#34;+RO$(PL)+&amp;#34;.&amp;#34;
250 PRINT &amp;#34;EXITS: &amp;#34;;
260 FOR I=0 TO 3
270 IF TT(PL,I)&amp;lt;&amp;gt;0 THEN PRINT CM$(I)+&amp;#34; &amp;#34;;
280 NEXT I
290 PRINT&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can finish processing the command. With a valid direction command in the C variable, we can determine whether there is an exit from the player&amp;rsquo;s current location in that direction by consulting the travel table. If not, we inform the player. Otherwise, we move the player to that location, then return to the top of the game loop.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;380 IF TT(PL,C)&amp;lt;&amp;gt;0 THEN 410
390 PRINT &amp;#34;YOU CAN&amp;#39;T GO THAT WAY.&amp;#34;
400 GOTO 240
410 PL=TT(PL,C)
420 GOTO 240&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;rsquo;s a complete albeit not very interesting game. It might be more interesting if there&amp;rsquo;s an object that the player can find to open the security door fore of the Lower Corridor. We might update the room description routine at the top of the game loop to announce whether the object is in the player&amp;rsquo;s current location. It might also describe the security door when the player is in the Lower Corridor, and whether it is open or closed. A new command could allow the player to pick up the object, when appropriate. When the player opens the security door, the game logic would update the travel table to allow passage between the Lower Corridor and what lies beyond.&lt;/p&gt;
&lt;h2 id=&#34;50-years-of-text-games-by-aaron-reed&#34;&gt;50 Years of Text Games, by Aaron Reed&lt;/h2&gt;
&lt;p&gt;This isn&amp;rsquo;t MEGA65 specific but I can&amp;rsquo;t close this out without recommending &lt;em&gt;50 Years of Text Games&lt;/em&gt; by Aaron Reed, a historical deep dive on the genre and its many unusual twisty passages. Well researched and compellingly written, Reed originally published this as &lt;a href=&#34;https://if50.substack.com/&#34;&gt;a serial newsletter&lt;/a&gt;, then crowdfunded a book version. The project raised over $640,000.&lt;/p&gt;
&lt;p&gt;The Kickstarter has ended, but there is a limited number of extra print copies &lt;a href=&#34;https://50-years-of-text-games.backerkit.com/hosted_preorders&#34;&gt;available for pre-order&lt;/a&gt;. If you&amp;rsquo;re still reading this Digest, you&amp;rsquo;ll love Aaron&amp;rsquo;s book.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The MEGA65 might be my favorite text adventure gaming platform. With the distraction-free 80-column display and quality mechanical keyboard, I can shut off the Internet and immerse myself in an interactive story. And the large amount of memory, fast disk access, and ability to store a giant library on an SD card mean I can play modern text games without the limitations of other microcomptuers.&lt;/p&gt;
&lt;p&gt;I hope you give at least a few of these games a try, and maybe write one of your own. Happy adventuring!&lt;/p&gt;
&lt;p&gt;— Dan&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/mega65-adventures/M65Digest_02_2022Oct.mp3" length="29325500" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>1466</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/mega65-adventures/hibernated-1-directors-cut-mega65.jpg"/>
      
    </item>
    
    <item>
      <title>MEGA65: The Next Batch!</title>
      <link>https://dansanderson.com/mega65/the-next-batch/</link>
      <pubDate>Sat, 17 Sep 2022 22:01:07 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/the-next-batch/</guid>
      <description>&lt;p&gt;MEGA65: The Next Batch! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for September 2022.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;MEGA65: The Next Batch! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for September 2022.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/the-next-batch/M65Digest_01_2022Sept.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/the-next-batch/M65Digest_01_2022Sept.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
MEGA65: The Next Batch!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;First off, thank you all so much for the outpouring of support for this Digest idea. I didn&amp;rsquo;t expect to see so many of you subscribe to a newsletter sight unseen. I really hope it&amp;rsquo;ll be an enjoyable use of your attention.&lt;/p&gt;
&lt;p&gt;And boy did we time this right, because we get to discuss big news in the first issue!&lt;/p&gt;
&lt;h2 id=&#34;batch-2-is-shipping-soon&#34;&gt;Batch #2 is shipping soon&lt;/h2&gt;
&lt;p&gt;MEGA&amp;rsquo;s assembly and distribution partner Trenz Electronic has parts in hand for the next batch of 400 computers, and is scheduled to assemble and deliver them by the end of the 2022 calendar year. Soon there will be 800 MEGA65s in the hands of new owners, not counting the 100 Dev Kits.&lt;/p&gt;
&lt;p&gt;All batch #2 machines will ship with updated factory-installed firmware and system software, including fixes and improvements made since batch #1 shipped back in May. Batch #2 will include the printed User’s Guide from the first print run. If you receive a batch #2 machine, you&amp;rsquo;ll want to &lt;a href=&#34;https://files.mega65.org/manuals-upload/&#34;&gt;download the most recent PDF&lt;/a&gt; as a supplement. I&amp;rsquo;ll try to keep the &lt;a href=&#34;https://dansanderson.com/mega65/welcome/&#34;&gt;Welcome Guide&lt;/a&gt; up to date as well.&lt;/p&gt;
&lt;p&gt;Trenz is planning these fulfillment batches based on the availability of parts, especially the Xilinx FPGA chips. The MEGA65 team has done a great job mitigating risk in the supply chain, with unusual pieces like the injection molded cases and floppy disk drives well stocked. (We were all surprised when the first batch was delayed due to &lt;a href=&#34;https://c65gs.blogspot.com/2022/05/the-chipageddon-parts-shortage-is-weird.html&#34;&gt;a shortage of cardboard&lt;/a&gt;, of all things.) We can all look forward to continued fulfillment of pre-orders through next year.&lt;/p&gt;
&lt;h2 id=&#34;help-with-testing-for-batch-2&#34;&gt;Help with testing for batch #2&lt;/h2&gt;
&lt;p&gt;The MEGA65 community made a huge push to test the factory-installed firmware and system software for batch #1. We&amp;rsquo;re doing it again for the batch #2 release candidate—and you can help!&lt;/p&gt;
&lt;p&gt;The closer you can get your MEGA65 to the final configuration, the better for testing. If you own a MEGA65, a Dev Kit, or a Nexys FPGA board, jump in the &lt;code&gt;#release-test&lt;/code&gt; forum on &lt;a href=&#34;https://discord.gg/5DNvESf&#34;&gt;the Discord&lt;/a&gt;. Check out the &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/8716289/Release+verification+0.95+batch+2+instructions+and+tips&#34;&gt;release candidate verification home page&lt;/a&gt; with links to downloads and instructions for testing and reporting bugs. You can install the latest core in slot 1 of the core management utility, and prepare a new internal SD card with the latest system software and bundled disk images.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re one of the lucky ones to have both a batch #1 MEGA65 and a JTAG programming interface, you can install the candidate core in the special &amp;ldquo;slot 0,&amp;rdquo; which is how batch #2 machines will be configured. Overwriting slot 0 requires opening your case to flip a tiny switch, as well as running some fancy commands. We need slot 0 testers, so if this sounds like you, please give it a try. See &lt;a href=&#34;https://mega65.atlassian.net/wiki/spaces/MEGA65/pages/8716289/Release+verification+0.95+batch+2+instructions+and+tips&#34;&gt;the wiki page for instructions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you don’t yet have a MEGA65, you can still help test the ROM using the Xemu emulator. You’ll need to use the &lt;a href=&#34;https://files.mega65.org/?id=fd2c40b9-f337-41f7-8a81-0254b1e09fb5&#34;&gt;C65 ROM diff files&lt;/a&gt; along with a copy of the original Commodore 65 ROM version 910828 (which you can find online or on the &lt;a href=&#34;https://www.c64forever.com/&#34;&gt;C64 Forever CD-ROM&lt;/a&gt;) to produce the &lt;code&gt;mega65.rom&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Thanks to everyone who can help out!&lt;/p&gt;
&lt;h2 id=&#34;whats-the-latest-firmware-anyway&#34;&gt;What&amp;rsquo;s the latest firmware, anyway?&lt;/h2&gt;
&lt;p&gt;The core team and contributors have been improving the MEGA65 firmware and system software (including the MEGA65 version of the Commodore 65 ROM code) continuously since batch #1 shipped. So what&amp;rsquo;s considered the &amp;ldquo;latest&amp;rdquo; version, and should you upgrade?&lt;/p&gt;
&lt;p&gt;There are two major release packages for the system software: the &lt;em&gt;stable&lt;/em&gt; release package, and the &lt;em&gt;experimental&lt;/em&gt; release package.&lt;/p&gt;
&lt;p&gt;The stable release package contains the most recent set of software that has been through a testing phase, which today is the factory-installed set from batch #1. It includes MEGA65 core version &lt;code&gt;20220109.11,1586ad4&lt;/code&gt; and the MEGA65 ROM version &lt;code&gt;920287&lt;/code&gt;. When we&amp;rsquo;ve completed verification of the batch #2 software set, that set will become the new stable release. You can download this from the &lt;a href=&#34;https://files.mega65.org/?id=a0276005-e71c-4b2d-8d17-2aa92e492c50&#34;&gt;MEGA65 R3 Release Package&lt;/a&gt; page on Filehost. (You&amp;rsquo;ll need a Filehost account registered with your owner code to access it, because it contains the licensed ROM.) Stable releases have their own version number to represent the entire set of software, with the current release known as version 0.9.&lt;/p&gt;
&lt;p&gt;The experimental release package is the bleeding edge, built regularly from the latest changes committed to the source repo. As of this writing, the experimental package download contains core version &lt;code&gt;20220717.12-develo-3253c5d&lt;/code&gt;. Contributors do their best to keep everything in working order when they submit changes. For additional assurance that changes maintain backwards compatibility, they are held in this &amp;ldquo;experimental&amp;rdquo; state while we test them and put them through their paces. You can download the experimental release core and system software from the &lt;a href=&#34;https://files.mega65.org/?id=f461df65-4957-4d5b-9f6e-890dc63ee501&#34;&gt;Experimental Release MEGA65 R3&lt;/a&gt; page on Filehost.&lt;/p&gt;
&lt;p&gt;Unlike the stable package, the experimental release package does not contain the ROM. As of now, the latest ROM is &lt;code&gt;920377&lt;/code&gt;, and is available from the &lt;a href=&#34;https://files.mega65.org/?id=54e69439-f25e-4124-8c78-22ea7ddc0f1c&#34;&gt;C65/MEGA65 Kernal ROM&lt;/a&gt; page on Filehost.&lt;/p&gt;
&lt;p&gt;The batch #2 verification build has &lt;a href=&#34;https://files.mega65.org/?id=f98ee771-5aac-42c0-886f-f68e6ff31c1f&#34;&gt;its own download page&lt;/a&gt; and may be slightly newer than the experimental release during the test phase.&lt;/p&gt;
&lt;h2 id=&#34;which-release-should-i-use&#34;&gt;Which release should I use?&lt;/h2&gt;
&lt;p&gt;Which release you choose to install on your own MEGA65 is a matter of taste. Everyone is encouraged to install the latest stable release. For batch #1 owners, this just means that we&amp;rsquo;ll throw an upgrade party when batch #2 is finalized. If you don&amp;rsquo;t want to hassle with frequent upgrades of experimental releases, and the occasional downgrade when issues are discovered, stick with the stable release and watch for announcements. If you&amp;rsquo;d like to preview new features, get the latest bug fixes, and help test new contributions, consider installing the latest experimental release. I&amp;rsquo;ve had a good time keeping the latest experimental release on my MEGA65 all year, though I&amp;rsquo;ve also been paying close attention to bug reports.&lt;/p&gt;
&lt;p&gt;One of the coolest things about the MEGA65 is that it&amp;rsquo;s easy to switch between multiple versions of these components. You can have multiple cores in flash memory, you can have multiple ROMs on the SD card, and you can easily switch between them when you boot the machine. This is not quite true for the auxiliary system software in those &lt;code&gt;.m65&lt;/code&gt; files on the SD card. If you find yourself switching between stable releases, you might want more than one SD card prepared with the appropriate files. The differences in the files between experimental releases tend to be minor enough to just use one SD card.&lt;/p&gt;
&lt;p&gt;As of right now, my personal recommendation is for batch #1 owners to proceed with upgrading to the experimental or batch #2 verification release set. Since batch #1 shipped, newer releases have fixed noticeable bugs and improved the overall quality of life for MEGA65 owners. You&amp;rsquo;ll also be helping with the verification effort by upgrading now. When the batch #2 testing phase completes, that&amp;rsquo;ll be a good time to install the new stable release as your default core (in slot 1) and default ROM (with filename &lt;code&gt;mega65.rom&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;As anyone who has done software release management professionally can tell you, release verification is an expensive process. We’re gradually building out automated testing solutions to reduce the time between stable releases, though this is challenging when custom hardware is involved. I&amp;rsquo;m grateful to everyone who tests experimental releases. You make continuous improvement possible!&lt;/p&gt;
&lt;p&gt;For instructions on how to upgrade your MEGA65&amp;rsquo;s firmware and system software, see the User&amp;rsquo;s Guide included with the machine, as well as the Welcome Guide.&lt;/p&gt;
&lt;h2 id=&#34;upcoming-type-in-zine-call-for-submissions&#34;&gt;Upcoming type-in zine, call for submissions&lt;/h2&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/the-next-batch/megazine_logo.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/the-next-batch/megazine_logo.png 320w, https://dansanderson.com/mega65/the-next-batch/megazine_logo_hu_7e6a152dd2695e98.png 600w, https://dansanderson.com/mega65/the-next-batch/megazine_logo_hu_2d7369684dc6a30b.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/the-next-batch/megazine_logo.png&#34;
        alt=&#34;The Megazine logo&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Megazine!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;ZeHa of Dr. Wuro Industries (known as ZeHa on the forums, drwuro on Discord) is producing &lt;em&gt;Megazine&lt;/em&gt;, a printed zine of type-in BASIC programs for the MEGA65, and is calling for submissions. If you&amp;rsquo;ve always wanted to see one of your programs featured in magazines like &lt;em&gt;Compute!&amp;rsquo;s Gazette&lt;/em&gt;, now is your big chance!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Megazine&lt;/em&gt; is looking for BASIC programs with a focus on fun, such as games, animations, or demos. Keep it short, and keep it readable enough for beginner programmers to understand. (I remember doing a type-in as a kid and encountering the word &lt;code&gt;FORK&lt;/code&gt; in the program and wondering what it did. It took me a moment to realize it was just a &lt;code&gt;FOR&lt;/code&gt; statement and a variable named &lt;code&gt;K&lt;/code&gt;, with the space removed.) Also please only submit unreleased programs.&lt;/p&gt;
&lt;p&gt;When the zine was originally announced, the submission deadline was set at September 30. This will probably be extended, though a new date has not yet been determined as of this writing. Check out &lt;a href=&#34;https://www.forum64.de/index.php?thread/125994-megazine-a-type-in-magazine-for-the-mega65/&#34;&gt;the original forum announcement&lt;/a&gt; for submission details and updates.&lt;/p&gt;
&lt;h2 id=&#34;character-graphics-made-easy&#34;&gt;Character graphics made easy&lt;/h2&gt;
&lt;p&gt;One of the easiest ways to get started with programming games on the MEGA65 is with &lt;em&gt;character graphics.&lt;/em&gt; Your BASIC program plots colored letters and symbols on the screen, checks whether the joystick or fire button is pushed, and decides on new positions for player, enemy, and environment objects. Do that in a loop and you&amp;rsquo;ve got a game.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/the-next-batch/charwars65.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/the-next-batch/charwars65.png 1394w, https://dansanderson.com/mega65/the-next-batch/charwars65_hu_19b8964aafc2db68.png 600w, https://dansanderson.com/mega65/the-next-batch/charwars65_hu_9ebaa2e840b5fd55.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/the-next-batch/charwars65.png&#34;
        alt=&#34;Screenshot of Charwars 65, a game by hstampfl from the MEGA65 demo disk&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
CHARWARS 65, a game by hstampfl using unmodified characters for graphics, from the demo disk
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Just like with the Commodore 64, you can replace the glyphs used for each letter or symbol with your own custom designs. And starting with ROM version 920347, MEGA65 BASIC makes this super easy!&lt;/p&gt;
&lt;p&gt;The CHARDEF command takes the character screen code whose glyph you want to replace, and eight numbers that describe the new 8x8 pixel image, one number for each row. Try this at the &lt;code&gt;READY.&lt;/code&gt; prompt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CHARDEF 0,$0C,$1C,$18,$FF,$18,$3C,$66,$C3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you get a &lt;code&gt;SYNTAX ERROR&lt;/code&gt;, double-check that you&amp;rsquo;re using the latest version of the ROM. (ROM 920347 came after the batch #1 v0.9 release.)&lt;/p&gt;
&lt;p&gt;Now type the &amp;ldquo;at&amp;rdquo; symbol (&lt;code&gt;@&lt;/code&gt;) a few times.&lt;/p&gt;
&lt;p&gt;The first 0 is the screen code for the &amp;ldquo;at&amp;rdquo; symbol. Screen codes 1 through 26 are the letters A through Z. See this table for all the screen codes. CHARDEF supports the first 256 screen codes in the uppercase PETSCII mode. (This will be updated to support all 512 codes, uppercase and lowercase PETSCII, in an upcoming release of the ROM.)&lt;/p&gt;
&lt;p&gt;Each of the numbers following the screen code describes a row of the character glyph.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20example.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20example.png 351w, https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20example_hu_481a0af49962caf3.png 600w, https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20example_hu_c963ec4340efbc05.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20example.png&#34;
        alt=&#34;Example of a custom character, with hex codes&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
CHARDEF example: a player character
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;MEGA65 BASIC&amp;rsquo;s built-in support for hexadecimal notation comes in really handy here, because each hexadecimal digit describes exactly four pixels.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20hex.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20hex.png 445w, https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20hex_hu_5cdd8a2e23aafb61.png 600w, https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20hex_hu_f1cb94a5caef3517.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20hex.png&#34;
        alt=&#34;Table of hexadecimal digits and pixel representations&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Hexadecimal digits and their pixel representations
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Many of the games I wrote as a kid featured this classic &amp;ldquo;brick wall&amp;rdquo; glyph. Look at the diagram below. What hexadecimal numbers describe this pattern? What CHARDEF command would change the letter A to appear as a brick wall?&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20exercise.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20exercise.png 385w, https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20exercise_hu_9baece17e4fd6b80.png 600w, https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20exercise_hu_4af38614dbb8cc.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20exercise.png&#34;
        alt=&#34;A custom character encoding exercise: a brick wall&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Using the hexadecimal table above, what numbers represent this brick wall glyph? What happens when you use these values with CHARDEF?
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;pre&gt;&lt;code&gt;CHARDEF __, $__, $__, $__, $__, $__, $__, $__, $__&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To restore the glyphs back to the MEGA65 PETSCII font, use the FONT command, with the letter C as an argument:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FONT C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s also a &lt;code&gt;FONT A&lt;/code&gt;, which replaces some lowercase glyphs with ASCII punctuation not available in PETSCII, and &lt;code&gt;FONT B&lt;/code&gt; which resembles a DOS-like font. Try them! (Remember you can toggle between uppercase and lowercase modes with Mega+Shift.)&lt;/p&gt;
&lt;p&gt;With CHARDEF in your BASIC programs, you&amp;rsquo;re well on your way to making some fun games. Be sure to submit yours to Megazine!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;That&amp;rsquo;ll do it for this month. Best of luck to all the testers, and congrats to everyone about to receive a new MEGA65!&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/the-next-batch/M65Digest_01_2022Sept.mp3" length="14765369" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>738</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/the-next-batch/02%20CHARDEF%20example.png"/>
      
    </item>
    
    <item>
      <title>Dan&#39;s MEGA65 Digest</title>
      <link>https://dansanderson.com/projects/dans-mega65-digest/</link>
      <pubDate>Thu, 08 Sep 2022 10:53:21 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/projects/dans-mega65-digest/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m starting an email newsletter for the MEGA65! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Subscribe today!&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;I&amp;rsquo;m starting an email newsletter for the MEGA65! &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Subscribe today!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve wanted there to be a newsletter for the &lt;a href=&#34;https://mega65.org/&#34;&gt;MEGA65&lt;/a&gt; ever since I got one back in March. Owning this retro-futuristic machine can be great fun, but it often involves keeping track of a lot of information: Where&amp;rsquo;s the latest firmware? What games and utilities have people made for it? How do I write my own programs? 2022 has been a year of rapid change for the new platform, and the answers to these questions have been shifting and settling. The community around the platform is growing rapidly as pre-orders get filled, and more people means more activity, more energy, more to keep track of.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; is a new email newsletter intended for MEGA65 owners, soon-to-be owners, wanna-be owners, and anyone curious about what&amp;rsquo;s happening with the project. My goal is to keep it brief and interactive, so there&amp;rsquo;s always something new you can try with your MEGA65 (or with the free &lt;a href=&#34;https://github.lgb.hu/xemu/&#34;&gt;Xemu emulator&lt;/a&gt;, if you don&amp;rsquo;t yet have a machine). It&amp;rsquo;s not a full magazine, just enough to inspire and inform.&lt;/p&gt;
&lt;p&gt;The newsletter is especially for people who aren&amp;rsquo;t yet intimately familiar with the MEGA65. I believe the MEGA65 is a unique opportunity to recreate an elusive quality of the vintage computing experience, a cozy environment for exploration and creativity intended for everyone, not just experienced computer programmers. I want help everyone who received a MEGA65 to make the most of this opportunity, and to find new ways to engage with the computer and the community. Hopefully this newsletter is just the beginning.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/projects/dans-mega65-digest/mega65_ready.jpeg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/projects/dans-mega65-digest/mega65_ready.jpeg 640w, https://dansanderson.com/projects/dans-mega65-digest/mega65_ready_hu_6678c3b9bfbda06f.jpeg 600w, https://dansanderson.com/projects/dans-mega65-digest/mega65_ready_hu_7a2ed3b38f17da8d.jpeg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/projects/dans-mega65-digest/mega65_ready.jpeg&#34;
        alt=&#34;The MEGA65 READY prompt&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGA65 at the READY.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;heres-what-you-can-do&#34;&gt;Here&amp;rsquo;s what you can do&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m extremely grateful for the outpouring of support the newsletter has received since I first announced it, especially considering I haven&amp;rsquo;t posted a real issue yet. If this sounds like a good idea to you, there are a few things you can do right now:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/keeping-up-with-the-mega65/&#34;&gt;&lt;strong&gt;Read&lt;/strong&gt; the inaugural welcome post&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;&lt;strong&gt;Subscribe&lt;/strong&gt;&lt;/a&gt;. You can get the Digest by email or RSS feed reader.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tell people about it.&lt;/strong&gt; We want everyone who is interested in the project to know there&amp;rsquo;s a newsletter, so they don&amp;rsquo;t miss out.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A friend of mine has convinced me to do a read-aloud audio version, so for a few issues at least, you can listen to me reading the thing. The audio player should be available from the email, website, or the app. If I can manage to produce these consistently, I might set up a podcast feed. Let me know if that&amp;rsquo;s of interest.&lt;/p&gt;
&lt;p&gt;Thank you for your support!&lt;/p&gt;
&lt;h2 id=&#34;other-mega65-projects&#34;&gt;Other MEGA65 projects&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve set up a dedicated &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;MEGA65 page&lt;/a&gt; with links to my MEGA65 projects. Subscribing to this blog is the best way to get updates. Of course I&amp;rsquo;ll probably mention my projects in the newsletter from time to time. But, you know, tastefully. 😊&lt;/p&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>Keeping Up With the MEGA65</title>
      <link>https://dansanderson.com/mega65/keeping-up-with-the-mega65/</link>
      <pubDate>Wed, 31 Aug 2022 10:00:24 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/mega65/keeping-up-with-the-mega65/</guid>
      <description>&lt;p&gt;Keeping Up With the MEGA65, &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for August 2022.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Keeping Up With the MEGA65, &lt;a href=&#34;https://dansanderson.com/mega65/&#34;&gt;Dan&amp;rsquo;s MEGA65 Digest&lt;/a&gt; for August 2022.&lt;/p&gt;
&lt;figure&gt;
    &lt;audio preload=&#34;metadata&#34; controls src=&#34;https://dansanderson.com/mega65/keeping-up-with-the-mega65/M65Digest_00_2022August.mp3&#34;&gt;&lt;a href=&#34;https://dansanderson.com/mega65/keeping-up-with-the-mega65/M65Digest_00_2022August.mp3&#34;&gt;(Audio)&lt;/a&gt;&lt;/audio&gt;
    &lt;figcaption&gt;
Keeping Up With the MEGA65
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The party was already in full swing when I got my &lt;a href=&#34;https://www.google.com/url?q=https://mega65.org/&amp;amp;sa=D&amp;amp;source=editors&amp;amp;ust=1663481331365191&amp;amp;usg=AOvVaw3CsT2RdcjlesB_jd5vZtn4&#34;&gt;MEGA65&lt;/a&gt; back in March of 2022. I got mine as part of the first shipment of production units, the ones with the sweet injection molded cases, but 100 others already had the acrylic-encased &lt;a href=&#34;https://www.google.com/url?q=https://www.rgcd.co.uk/2021/02/mega65-devkit-first-impressions.html&amp;amp;sa=D&amp;amp;source=editors&amp;amp;ust=1663481331365494&amp;amp;usg=AOvVaw0n2fSMoPLRlIhk1tq3Ic_a&#34;&gt;Dev Kit&lt;/a&gt; beta units from the previous year. Many more were eagerly running the MEGA65 core on &lt;a href=&#34;https://www.google.com/url?q=https://www.stevencombs.com/mega65-nexys4-livestream&amp;amp;sa=D&amp;amp;source=editors&amp;amp;ust=1663481331365698&amp;amp;usg=AOvVaw3BRpQivtYn2qrXg68I8TfM&#34;&gt;Nexys FPGA boards&lt;/a&gt; or testing the waters with the &lt;a href=&#34;https://www.google.com/url?q=https://github.lgb.hu/xemu/&amp;amp;sa=D&amp;amp;source=editors&amp;amp;ust=1663481331365880&amp;amp;usg=AOvVaw3dnV_PUvDobe8rnhTkOSfj&#34;&gt;Xemu emulator&lt;/a&gt;. By the time batch #1 shipped, it included multiple disk images packed with demonstrations and games from an already thriving community.&lt;/p&gt;
&lt;p&gt;A flurry of essential firmware and ROM updates followed the March delivery, and it was important to keep up with developments. I was lucky to have just started a sabbatical from my software job and had the time to read through daily discussions on the &lt;a href=&#34;https://discord.gg/5DNvESf&#34;&gt;MEGA65 Discord&lt;/a&gt;. I knew other newly minted MEGA65 owners that didn&amp;rsquo;t have that kind of time and were struggling to dig into their new machines. For them and others, I wrote the &lt;a href=&#34;https://dansanderson.com/mega65/welcome/&#34;&gt;&lt;em&gt;MEGA65 Welcome Guide&lt;/em&gt;&lt;/a&gt;, a supplement to the already &lt;a href=&#34;https://files.mega65.org/manuals-upload/&#34;&gt;excellent documentation&lt;/a&gt; that tried to synthesize information about recent changes and practical advice, stuff too temporary for the official manual but still useful to the first 400 owners.&lt;/p&gt;
&lt;p&gt;And the new stuff keeps coming. I&amp;rsquo;ve been keeping track of all of the amazing things this growing community has been doing with the MEGA65 all year, from boxed retail games to music demos to tools and libraries to YouTube videos and tutorials. There was so much being posted, I built the &lt;a href=&#34;https://twitter.com/MEGA65Files&#34;&gt;@MEGA65Files Twitter bot&lt;/a&gt; as a way for people to be notified of new software and articles posted to the &lt;a href=&#34;https://files.mega65.org/&#34;&gt;Filehost repository&lt;/a&gt;. As of this writing, the Filehost has nearly 200 downloadable files and over 60 articles.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/mega65/keeping-up-with-the-mega65/image1.jpg&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/mega65/keeping-up-with-the-mega65/image1.jpg 1086w, https://dansanderson.com/mega65/keeping-up-with-the-mega65/image1_hu_7d3bb9e3d106f4d4.jpg 600w, https://dansanderson.com/mega65/keeping-up-with-the-mega65/image1_hu_2e8eb95bcb8d0c4b.jpg 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/mega65/keeping-up-with-the-mega65/image1.jpg&#34;
        alt=&#34;MEGA65 BASIC screen at the READY prompt&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
MEGA65 at the READY.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;By the end of 2022, there will be 800 MEGA65s in the wild—not counting the 100 Dev Kits—and the pace of development is likely to increase. With more people and more activity, it won’t be sufficient to assume that everyone is reading the Discord chat. I think it&amp;rsquo;s time for a newsletter.&lt;/p&gt;
&lt;p&gt;Whether you already have a MEGA65, have &lt;a href=&#34;https://shop.trenz-electronic.de/en/Products/MEGA65/&#34;&gt;preordered one&lt;/a&gt; from a future batch, are jumping in with a Nexys board or the emulator, or are just curious about the MEGA65 project and its community, this Digest will keep you up to date. Firmware updates, shipping status, new software releases, game jams, tips and tricks, and maybe the occasional interview. Things you can do with your MEGA65 right now. It’ll be short, interactive, and free.&lt;/p&gt;
&lt;p&gt;There are two things you can do to help:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Subscribe.&lt;/strong&gt; You can get the Digest by email, RSS reader, or the Substack app.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tell people about it.&lt;/strong&gt; We want everyone who is interested in the project to know there&amp;rsquo;s a newsletter, so they don&amp;rsquo;t miss out.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Look for the first post in mid-September.&lt;/p&gt;
&lt;p&gt;Thanks all! &lt;code&gt;GO 65&lt;/code&gt;!&lt;/p&gt;</content:encoded>
      
      <enclosure url="https://dansanderson.com/mega65/keeping-up-with-the-mega65/M65Digest_00_2022August.mp3" length="3665941" type="audio/mpeg"/>
      <itunes:author>Dan Sanderson</itunes:author>
      <itunes:explicit>No</itunes:explicit>
      <itunes:duration>183</itunes:duration>
      <itunes:image href="https://dansanderson.com/mega65/keeping-up-with-the-mega65/image1.jpg"/>
      
    </item>
    
    <item>
      <title>C projects with GNU Autotools in 2022</title>
      <link>https://dansanderson.com/lab-notes/autotools-in-2022/</link>
      <pubDate>Thu, 18 Aug 2022 08:44:14 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/lab-notes/autotools-in-2022/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been a user of the &lt;a href=&#34;https://www.gnu.org/software/automake/manual/html_node/GNU-Build-System.html&#34;&gt;GNU Build System&lt;/a&gt; (aka &lt;em&gt;GNU Autotools&lt;/em&gt;) nearly all my life, as the installation mechanism for countless open source software packages. Only recently have I tried setting up a software project that uses it. I ended up with a new project template and a lightweight C module management system, with unit testing and mocks.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;I&amp;rsquo;ve been a user of the &lt;a href=&#34;https://www.gnu.org/software/automake/manual/html_node/GNU-Build-System.html&#34;&gt;GNU Build System&lt;/a&gt; (aka &lt;em&gt;GNU Autotools&lt;/em&gt;) nearly all my life, as the installation mechanism for countless open source software packages. Only recently have I tried setting up a software project that uses it. I ended up with a new project template and a lightweight C module management system, with unit testing and mocks.&lt;/p&gt;
&lt;p&gt;In this article, I&amp;rsquo;ll give an overview of the template&amp;rsquo;s simple (possibly naïve) philosophy, and I&amp;rsquo;ll describe the Autotools features it tries to simplify. See &lt;a href=&#34;https://github.com/dansanderson/c-autotools-template/blob/main/README.md&#34;&gt;the template README.md&lt;/a&gt; for the practical details on how to use it, and &lt;a href=&#34;https://github.com/dansanderson/c-autotools-template&#34;&gt;the template repo itself&lt;/a&gt; for examples. Hopefully this at least provides some hints to future Autotoolers, even if you don&amp;rsquo;t use the automation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/dansanderson/c-autotools-template&#34;&gt;C Autotools new project template&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Update, August 20:&lt;/strong&gt; I decided to challenge a premise of the first template to make a smaller simpler template. If you want modules with multiple source files, use the main template and the provided tool to generate &lt;code&gt;Makefile.am&lt;/code&gt;. If you&amp;rsquo;re fine with one source file per module (common in small-to-medium C projects), this smaller template suggests a workflow with a hand-edited &lt;code&gt;Makefile.am&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/dansanderson/c-autotools-template-small&#34;&gt;C Autotools new project template, one file per module&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-autotools-weve-known&#34;&gt;The Autotools we&amp;rsquo;ve known&lt;/h2&gt;
&lt;p&gt;Perhaps you&amp;rsquo;ve done this at a command line to download and install open source software for Linux or macOS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget https://example.com/downloads/coolsoftware-1.0.tar.gz
tar xzf coolsoftware-1.0.tar.gz
cd coolsoftware-1.0
./configure
make
sudo make install&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This software was packaged with &lt;a href=&#34;https://www.gnu.org/software/automake/manual/html_node/index.html&#34;&gt;GNU Autotools&lt;/a&gt;, a powerful tool for distributing software that can run on multiple types of computers. Instead of downloading pre-built software for a specific operating system, Autotools expects you to download the source code, then use software building toolsto generate the final program tailored to your specific computer. The Autotools magic is in the &lt;code&gt;./configure&lt;/code&gt; command, which scans your system for tools and libraries, and adapts the installation process to what it finds. You can even give &lt;code&gt;./configure&lt;/code&gt; customization options to further tweak the result.&lt;/p&gt;
&lt;p&gt;This is mostly useful among Unix and Linux machines that might have many variations of components. Autotools assumes they all comply with the &lt;a href=&#34;https://en.wikipedia.org/wiki/POSIX&#34;&gt;POSIX&lt;/a&gt; standard, a baseline of functionality that it can use to bootstrap the custom install process. This includes Unix, Linux, BSD, and macOS (which is based on BSD). Windows users can install a POSIX-compliant subsystem such as &lt;a href=&#34;https://en.wikipedia.org/wiki/Cygwin&#34;&gt;Cygwin&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/MinGW&#34;&gt;MinGW&lt;/a&gt;, or the &lt;a href=&#34;https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux&#34;&gt;Windows Subsystem for Linux&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Even if you don&amp;rsquo;t distribute a source package like &lt;code&gt;coolsoftware-1.0.tar.gz&lt;/code&gt;, Autotools can make it easier to produce app downloads for different operating systems from a single set of source files. Autotools is so widely used as to be a de facto standard for some things, and so featureful that it&amp;rsquo;s difficult to get the same result any other way.&lt;/p&gt;
&lt;h2 id=&#34;why-i-think-i-want-autotools-in-2022&#34;&gt;Why (I think) I want Autotools in 2022&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m working on a command-line tool written in the C language. It&amp;rsquo;ll be somewhat large and take advantage of C code and libraries written by others. It&amp;rsquo;ll be released as open source, and some customers will prefer a GNU standard source distribution ala &lt;code&gt;coolsoftware-1.0.tar.gz&lt;/code&gt;. Other customers will require or prefer pre-compiled Windows and Mac apps, which will probably be generated by a Continuous Integration (CI) system from a public source repository. It may someday be a &lt;a href=&#34;https://brew.sh/&#34;&gt;Homebrew&lt;/a&gt; installation recipe.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll admit up front that I have not yet taken a close look at &lt;a href=&#34;https://cmake.org/&#34;&gt;CMake&lt;/a&gt; or &lt;a href=&#34;https://mesonbuild.com/&#34;&gt;Meson&lt;/a&gt;, two newer build systems with good support for C programs that are increasingly popular. The user and developer community to which I&amp;rsquo;m contributing this hasn&amp;rsquo;t adopted either, and while I want build logic more formalized than hand-written Makefiles, I didn&amp;rsquo;t want to introduce a new tool dependency. In practice, I&amp;rsquo;m probably asking them to install a bunch of dependencies anyway, so this may not be a major concern.&lt;/p&gt;
&lt;p&gt;I want my tool to behave according to the expectations of seasoned command-line users, expectations heavily influenced by and implemented by prevalent GNU libraries. Established well-documented tool chains &lt;em&gt;should&lt;/em&gt; make this easier to pull together.&lt;/p&gt;
&lt;p&gt;If this were a professional environment, I would do a more thorough comparative analysis, and maybe lean toward more modern tooling. For a personal project, the established vintage nature of Autotools has its charms, like using the decades-old machines in a high school woodshop. It&amp;rsquo;s an old-fashioned project for an old-fashioned community, and it&amp;rsquo;ll be fun to do a project in C with Autotools.&lt;/p&gt;
&lt;h2 id=&#34;organizing-a-c-project&#34;&gt;Organizing a C project&lt;/h2&gt;
&lt;p&gt;I want the project root directory to only contain high-level documentation, Autotools files, and Git configuration. Application source code goes in a &lt;code&gt;src/&lt;/code&gt; directory, test code and data goes in a &lt;code&gt;tests/&lt;/code&gt; directory, more documentation under &lt;code&gt;docs/&lt;/code&gt;, and custom developer automation under &lt;code&gt;scripts/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The Unix-y way to depend on a third-party library is to inform the user through documentation that they must download and install the library on their system before building the application. If the library you want is open source in a way that&amp;rsquo;s compatible with your project, a useful alternative is to copy the library&amp;rsquo;s source code directly into your project, so the user has one less thing to worry about. Furthermore, if that library has a public Git repository, you can use &lt;a href=&#34;https://git-scm.com/book/en/v2/Git-Tools-Submodules&#34;&gt;Git Submodules&lt;/a&gt; to formalize the relationship. Either way, it belongs in a &lt;code&gt;third-party/&lt;/code&gt; directory to keep it separate from the project source.&lt;/p&gt;
&lt;p&gt;Throw in some &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;VSCode&lt;/a&gt; IDE project settings, and this seems like a sensible top-level file list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.vscode/
  launch.json
  settings.json
  tasks.json
docs/
scripts/
src/
tests/
third-party/
.gitignore
configure.ac
LICENSE
Makefile.am
README.md&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;modules-in-c&#34;&gt;Modules in C&lt;/h2&gt;
&lt;p&gt;Any large software project is organized into smaller self-contained units that refer to one another. Modern languages have facilities for defining these units built into the language, such as packages, classes, and namespaces. The C language doesn&amp;rsquo;t prescribe a way to do this, so C programmers adopt a discipline of best practices to accomplish the same effect. I&amp;rsquo;m confident that what I describe here is pretty close to common practice, at least in a simplistic sense, though different projects might do this differently because there is no real standard.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;module&lt;/em&gt; is a self-contained, well-understood set of functionality in our program. It can be tested independently of other modules, and it can depend on other modules explicitly. Ideally, a module&amp;rsquo;s internals are not visible to other modules, so they are easy to change without concern that an internal change in one module breaks another module.&lt;/p&gt;
&lt;p&gt;C offers these features on a per-file basis. A single &lt;code&gt;.c&lt;/code&gt; source file can define functions and storage for use by other files, and can also define &lt;code&gt;static&lt;/code&gt; functions and storage visible only to the file. To share the non-static definitions to other source files, you declare them in a &lt;code&gt;.h&lt;/code&gt; header file, and refer to the header file with an &lt;code&gt;#include&lt;/code&gt; preprocessor directive in the source files that use them. Each &lt;code&gt;.c&lt;/code&gt; compilation unit is compiled into an &lt;code&gt;.o&lt;/code&gt; object file individually, and all of the object files are linked together by the names (symbols) of the declarations to form the final program.&lt;/p&gt;
&lt;p&gt;Consider a module for parsing a configuration file into a data structure, which we&amp;rsquo;ll call &lt;code&gt;cfgfile&lt;/code&gt;. The &lt;code&gt;cfgfile.h&lt;/code&gt; header file might look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#ifndef CFGFILE_H_
#define CFGFILE_H_

#include &amp;lt;stdbool.h&amp;gt;

/**
 * Configuration for the program.
 */
typedef struct {
    char *logfile_path;
    // ...
} config_t;

/**
 * Parses the text of a configuration file.
 */
bool parse(char *filetext, config_t **result);

#endif&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This might be implemented in a &lt;code&gt;cfgfile.c&lt;/code&gt; source file like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;#34;cfgfile.h&amp;#34;

#include &amp;lt;stdbool.h&amp;gt;

static char tempbuf[1024];

static void handle_token(char *token, int len) {
    // ...
}

bool parse(char *filetext, config_t **result) {
    // ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This has the features we&amp;rsquo;re looking for: it defines a struct type named &lt;code&gt;config&lt;/code&gt; that we intend callers of the module to know about, and public function with the signature &lt;code&gt;bool parse(char *, config **)&lt;/code&gt; for callers to use. Implementation details in &lt;code&gt;cfgfile.c&lt;/code&gt; are hidden from the caller by the &lt;code&gt;static&lt;/code&gt; declaration: callers can&amp;rsquo;t access &lt;code&gt;tempbuf&lt;/code&gt; or &lt;code&gt;handle_token&lt;/code&gt;, and could even declare their own &lt;code&gt;tempbuf&lt;/code&gt; without conflicting with the module.&lt;/p&gt;
&lt;p&gt;Unlike modern languages, the C language does &lt;em&gt;not&lt;/em&gt; have a built-in notion of &lt;em&gt;namespaces&lt;/em&gt;. Even though &lt;code&gt;parse&lt;/code&gt; is declared in &lt;code&gt;cfgfile.h&lt;/code&gt;, this fact is immaterial to the linking process. In the final program, there can be only one &lt;code&gt;parse&lt;/code&gt;. If two source files try to provide a symbol named &lt;code&gt;parse&lt;/code&gt;, the linker will fail because it doesn&amp;rsquo;t know which version to use when &lt;code&gt;parse&lt;/code&gt; is called.&lt;/p&gt;
&lt;p&gt;The solution is simple, but requires a bit of discipline: use the module name as a prefix for all non-static stuff.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;typedef struct {
    // ...
} cfgfile_config_t;

bool cfgfile_parse(char *filetext, cfgfile_config_t **result);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This feels a bit unwieldy, but it makes some sense. There&amp;rsquo;s not much difference between &lt;code&gt;cfgfile_parse&lt;/code&gt; and a (hypothetical) &lt;code&gt;cfgfile::parse&lt;/code&gt;, at least when called from outside the (hypothetical) namespace.&lt;/p&gt;
&lt;h2 id=&#34;multi-file-modules&#34;&gt;Multi-file modules&lt;/h2&gt;
&lt;p&gt;Maybe it&amp;rsquo;s just habits I&amp;rsquo;ve formed from other languages, but I&amp;rsquo;d prefer to keep my source files shorter than what I have in mind for what would go in a module. I want each module to be a &lt;em&gt;collection&lt;/em&gt; of source files in a subdirectory, and still retain the encapsulation benefits of a single C file as much as possible. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/cfgfile/
  cfgfile.h
  cfgfile.c
  cfgmap.c
  cfgmap.h&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As before, &lt;code&gt;cfgfile.h&lt;/code&gt; declares our module exports, and &lt;code&gt;cfgfile.c&lt;/code&gt; implements them. The module implementation spans across additional source files not intended for consumption outside of the module. &lt;code&gt;cfgfile.c&lt;/code&gt; might &lt;code&gt;#include &amp;quot;cfgmap.h&amp;quot;&lt;/code&gt;, but nobody else should.&lt;/p&gt;
&lt;p&gt;C doesn&amp;rsquo;t have a way to make symbols &amp;ldquo;static&amp;rdquo; across a set of files. The best we can do is use another naming convention: symbols shared across files within the module start with an underscore followed by the module name. Potential entries for &lt;code&gt;cfgmap.h&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#ifndef _CFGFILE_CFGMAP_H_
#define _CFGFILE_CFGMAP_H_

typedef struct {
    // ...
} _cfgfile_cfgmap_map;

_cfgfile_cfgmap_map *_cfgfile_cfgmap_create_map();

#endif&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The underscore says &amp;ldquo;privacy, please,&amp;rdquo; but the module name is still needed in the prefix because these private symbols are still technically accessible across modules. Another module might have its own internal &amp;ldquo;create map&amp;rdquo; function, and we don&amp;rsquo;t want collisions. I also prefixed the header protection &lt;code&gt;#define&lt;/code&gt;, to be thorough. Using both the module name and the filename in the prefix is probably overkill, but this is what keeps me from worrying about unintended consequences.&lt;/p&gt;
&lt;p&gt;I stop short of adding a prefix to the header filename itself, because this is easily remedied another way: set the include path to &lt;code&gt;src/&lt;/code&gt;, so all &lt;code&gt;#include&lt;/code&gt;s must begin with the module directory name, such as &lt;code&gt;#include &amp;quot;cfgfile/cfgfile.h&amp;quot;&lt;/code&gt;. (We could also make a style choice to use all relative paths in &lt;code&gt;#include&lt;/code&gt;s, but I think this is cleaner.) We&amp;rsquo;ll introduce the compiler setting for the include path later.&lt;/p&gt;
&lt;h2 id=&#34;a-module-for-main&#34;&gt;A module for main&lt;/h2&gt;
&lt;p&gt;This project is an application (as opposed to a library), so somewhere there must be a function with the signature &lt;code&gt;int main(int argc, char **argv)&lt;/code&gt;. Whether to put its source file in a submodule directory is an arbitrary choice because there&amp;rsquo;s little reason to treat &lt;code&gt;main&lt;/code&gt; as if it&amp;rsquo;s in a module. Nevertheless:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/myapp/myapp.c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When we discuss testing later, we&amp;rsquo;ll see that each test will be a small program with its own &lt;code&gt;main&lt;/code&gt; routine. That makes &lt;code&gt;myapp.c&lt;/code&gt; a difficult thing to test this way. This source file should probably contain very little code and export nothing. That makes it un-module-like. Locating this at &lt;code&gt;src/myapp.c&lt;/code&gt; would also be a sensible choice.&lt;/p&gt;
&lt;h2 id=&#34;configureac&#34;&gt;configure.ac&lt;/h2&gt;
&lt;p&gt;Our source distribution has a local script named &lt;code&gt;./configure&lt;/code&gt; that knows everything our project needs. It consists of a bunch of code to gather user requests, tool locations, and dependencies, then generate a &lt;code&gt;Makefile&lt;/code&gt; that can be executed by &lt;code&gt;make&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We use a GNU Autotools tool, &lt;a href=&#34;https://www.gnu.org/software/autoconf/&#34;&gt;Autoconf&lt;/a&gt;, to generate the &lt;code&gt;./configure&lt;/code&gt; file from a specification, a file named &lt;code&gt;configure.ac&lt;/code&gt;. The command &lt;code&gt;autoreconf --install&lt;/code&gt; reads this file and generates &lt;code&gt;./configure&lt;/code&gt; (and a bunch of other temporary things).&lt;/p&gt;
&lt;p&gt;Not everything goes in &lt;code&gt;configure.ac&lt;/code&gt;. Much of the flexibility of Autotools comes from the fact that we still get to write &lt;code&gt;Makefile&lt;/code&gt; rules when we need to. The most powerful rules are built in, and to use them we only need to define certain variables. These definitions and custom rules live in a file named &lt;code&gt;Makefile.am&lt;/code&gt;. The generated &lt;code&gt;./configure&lt;/code&gt; command converts these into files named &lt;code&gt;Makefile&lt;/code&gt;, which the &lt;code&gt;make&lt;/code&gt; command uses in the end. This subsystem is known as &lt;a href=&#34;https://www.gnu.org/software/automake/&#34;&gt;Automake&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;configure.ac&lt;/code&gt; lives in the project root. Let&amp;rsquo;s start with some canonical set-up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AC_INIT([myapp], [0.1])
AM_INIT_AUTOMAKE([foreign -Wall -Werror -Wno-portability subdir-objects])

AC_PROG_CC
AM_PROG_AR
LT_INIT

AC_CONFIG_MACRO_DIRS([m4])
AC_CONFIG_HEADERS([config.h])

AC_CONFIG_FILES([Makefile])

AC_OUTPUT&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See &lt;a href=&#34;https://www.lrde.epita.fr/~adl/autotools.html&#34;&gt;the Autotools tutorial&lt;/a&gt; for introductions to these directives. Briefly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AC_INIT&lt;/code&gt; has the name of the application and a version number. These are used in various places, including the source distribution filename (&lt;code&gt;myapp-0.1.tar.gz&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AC_INIT_AUTOMAKE&lt;/code&gt; sets up Automake with a few options.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AC_PROG_*&lt;/code&gt; check for common tools, such as a gcc-compatible C compiler.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LT_INIT&lt;/code&gt; sets up &lt;a href=&#34;https://www.gnu.org/software/automake/manual/html_node/A-Shared-Library.html&#34;&gt;Libtool&lt;/a&gt;, which we will use in our module system.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AC_CONFIG_HEADERS&lt;/code&gt; generates a C header named &lt;code&gt;config.h&lt;/code&gt; in the project root directory. This header contains &lt;code&gt;#define&lt;/code&gt; preprocessor statements with values calculated by the configuration process.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AC_CONFIG_FILES&lt;/code&gt; must mention every Makefile we want in our project. In general, Autotools needs every file to be mentioned explicitly somewhere to be considered part of the project.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AC_OUTPUT&lt;/code&gt; triggers the generation of files described by previous configuration macros.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;makefileam&#34;&gt;Makefile.am&lt;/h2&gt;
&lt;p&gt;Each module will have its own build definitions and rules, and it&amp;rsquo;d be great if those rules could live in separate files, one per module. Autotools supports &lt;a href=&#34;https://www.gnu.org/software/automake/manual/html_node/Subdirectories.html&#34;&gt;traversing subdirectories&lt;/a&gt; for &lt;code&gt;Makefile.am&lt;/code&gt; files, as long as they are declared in parent &lt;code&gt;Makefile.am&lt;/code&gt; files with a &lt;code&gt;SUBDIRS = ...&lt;/code&gt; variable.&lt;/p&gt;
&lt;p&gt;While this keeps Makefiles short, it has the serious disadvantage that Makefiles can&amp;rsquo;t see each other, and so can&amp;rsquo;t reliably depend on each others&amp;rsquo; targets. I started out assuming I&amp;rsquo;d have one &lt;code&gt;Makefile.am&lt;/code&gt; per directory, only to realize that this made the ordering of &lt;code&gt;SUBDIRS&lt;/code&gt; significant: if a module wasn&amp;rsquo;t built by the time it was needed by another module, the build would fail. I had to manage the dependency tree manually with &lt;code&gt;SUBDIRS&lt;/code&gt;, and I couldn&amp;rsquo;t build certain individual targets without building the entire project because the targets didn&amp;rsquo;t know about their dependencies in other files. (Not to mention I kept forgetting to add new Makefiles to &lt;code&gt;configure.ac&lt;/code&gt;&amp;rsquo;s &lt;code&gt;AC_CONFIG_FILES&lt;/code&gt; variable.)&lt;/p&gt;
&lt;p&gt;So now I&amp;rsquo;m a fan of maintaining one large &lt;code&gt;Makefile.am&lt;/code&gt; for the project. It&amp;rsquo;s easy to define common rules and variables, and keep descriptions of modules and module dependencies succinct.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a start:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ACLOCAL_AMFLAGS = -I m4

AM_CPPFLAGS = \
    -I$(top_srcdir) \
    -I$(top_srcdir)/src&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This sets &lt;code&gt;ACLOCAL_AMFLAGS&lt;/code&gt; as recommended by Libtool, and sets up that &lt;code&gt;#include&lt;/code&gt; path. I put the project root in the include path also, so the program can reach the &lt;code&gt;config.h&lt;/code&gt; file that &lt;code&gt;./configure&lt;/code&gt; generates. This is optional, but I like it.&lt;/p&gt;
&lt;h2 id=&#34;making-programs&#34;&gt;Making programs&lt;/h2&gt;
&lt;p&gt;We want Automake to build a tool named &lt;code&gt;myapp&lt;/code&gt; with at least &lt;code&gt;src/myapp/myapp.c&lt;/code&gt; as a source file. Without any dependencies on other modules, this would look like this in &lt;code&gt;Makefile.am&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bin_PROGRAMS = myapp

myapp_SOURCES = myapp.c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;bin_PROGRAMS&lt;/code&gt; is a list of programs to build. For each program, we provide a &lt;code&gt;xxx_SOURCES&lt;/code&gt; variable, where &lt;code&gt;xxx&lt;/code&gt; is the name of the program. (If the program name contained weird characters like hyphens, the variable name would use underscores, e.g. &lt;code&gt;some-tool&lt;/code&gt; would be &lt;code&gt;some_tool_SOURCES&lt;/code&gt;.) Automake uses the &lt;code&gt;SOURCES&lt;/code&gt; list to figure out that it needs to run the C compiler on the &lt;code&gt;.c&lt;/code&gt; files to produce &lt;code&gt;.o&lt;/code&gt; files, and to link all of those &lt;code&gt;.o&lt;/code&gt; files together into a program named &lt;code&gt;myapp&lt;/code&gt;. This is also how Automake figures out to include all &lt;code&gt;SOURCES&lt;/code&gt; in the source distribution.&lt;/p&gt;
&lt;p&gt;So how do we bring in the &lt;code&gt;cfgfile&lt;/code&gt; module so that &lt;code&gt;myapp.c&lt;/code&gt; can call it? One way would be to just add all of &lt;code&gt;cfgfile&lt;/code&gt;&amp;rsquo;s source files to &lt;code&gt;myapp_SOURCES&lt;/code&gt;. Not only would this become difficult to manage (Makefile variables might help), as our dependency tree grows, our build would slow down with unnecessary re-builds of all of these source files. There is a better way.&lt;/p&gt;
&lt;h2 id=&#34;making-modules&#34;&gt;Making modules&lt;/h2&gt;
&lt;p&gt;We want each module to act like a &lt;em&gt;library&lt;/em&gt;, a self-contained unit that encapsulates all of the module&amp;rsquo;s code and dependencies. It is built as needed and linked in everywhere it is used.&lt;/p&gt;
&lt;p&gt;Just as &lt;code&gt;Makefile.am&lt;/code&gt; defines &lt;code&gt;PROGRAMS&lt;/code&gt;, it can also define &lt;code&gt;LTLIBRARIES&lt;/code&gt;. &amp;ldquo;LT&amp;rdquo; stands for &lt;a href=&#34;https://www.gnu.org/software/libtool/manual/html_node/Integrating-libtool.html&#34;&gt;Libtool&lt;/a&gt;, a mechanism for packaging a shared library and its dependencies into a file whose name ends in &lt;code&gt;.la&lt;/code&gt;. Autotools can build and install shared libraries into the user&amp;rsquo;s system library directory for use by other program builds.&lt;/p&gt;
&lt;p&gt;We don&amp;rsquo;t actually want that in this case: our modules will only ever be used to build this program, and we don&amp;rsquo;t want to clutter the user&amp;rsquo;s system with unnecessary files. Instead, we can tell Autotools to build a module as a library, but then not install it. The &lt;code&gt;noinst_LTLIBRARIES&lt;/code&gt; variable declares a list of LT libraries to build for the sole purpose supporting other builds. These are known as &lt;a href=&#34;https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html&#34;&gt;convenience libraries&lt;/a&gt; because they just help us organize our code and build logic.&lt;/p&gt;
&lt;p&gt;An LT library has a name beginning with &lt;code&gt;lib&lt;/code&gt; and ending in &lt;code&gt;.la&lt;/code&gt;, so our &lt;code&gt;cfgfile&lt;/code&gt; module looks like this in &lt;code&gt;Makefile.am&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;noinst_LTLIBRARIES = \
    libcfgfile.la

libcfgfile_la_SOURCES = \
    src/cfgfile/cfgfile.c \
    src/cfgfile/cfgfile.h \
    src/cfgfile/cfgmap.c \
    src/cfgfile/cfgmap.h&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To declare that &lt;code&gt;cfgfile&lt;/code&gt; is a dependency for &lt;code&gt;myapp&lt;/code&gt; program, set &lt;code&gt;myapp_LDADD&lt;/code&gt; like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;myapp_LDADD = libcfgfile.la&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To make one library module depend on another (library) module, use &lt;code&gt;LIBADD&lt;/code&gt; instead of &lt;code&gt;LDADD&lt;/code&gt;. For example, say a module named &lt;code&gt;executor&lt;/code&gt; depends on &lt;code&gt;cfgfile&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;noinst_LTLIBRARIES = \
    libcfgfile.la \
    libexecutor.la

# libcfgfile_la_SOURCES = ...

libexecutor_la_SOURCES = \
    src/executor/executor.c \
    src/executor/executor.h
libexecutor_la_LIBADD = \
    libcfgfile.la&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;In some documentation and examples, you&amp;rsquo;ll see &lt;code&gt;LIBRARIES&lt;/code&gt; that are not &lt;code&gt;LTLIBRARIES&lt;/code&gt;, with names ending in &lt;code&gt;.a&lt;/code&gt; instead of &lt;code&gt;.la&lt;/code&gt;. The main difference is an LT library builds in all of the library&amp;rsquo;s dependencies. With plain libraries, each module would contain its own object code, but the program rule would need to explicitly depend on all of its dependencies&amp;rsquo; dependencies. This leaks an implementation detail between modules. In practice, we could just list every module in &lt;code&gt;myapp_LDADD&lt;/code&gt; and avoid &lt;code&gt;LIBADD&lt;/code&gt; entirely, but I like not having to think about this.&lt;/p&gt;
&lt;p&gt;You may wonder, as I did, whether there is an issue with two modules both depending on a common module, then both being dependencies for something else, aka a &lt;a href=&#34;https://en.wikipedia.org/wiki/Dependency_hell&#34;&gt;diamond dependency&lt;/a&gt;. Do the two copies of the common module conflict? Apparently not! The linker is smart enough to consolidate the results.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;trying-out-the-build&#34;&gt;Trying out the build&lt;/h2&gt;
&lt;p&gt;The following commands use the files we just created to generate the configuration script, run it, then make the program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;autoreconf --install
./configure
make&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;myapp&lt;/code&gt; program appears in the project root directory. If we were to &lt;code&gt;make install&lt;/code&gt;, it would get copied to our system&amp;rsquo;s &lt;code&gt;/usr/local/bin&lt;/code&gt; directory, available for people to use.&lt;/p&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;During development, when you change a source file, you only need to re-run &lt;code&gt;make&lt;/code&gt;. When you change a &lt;code&gt;Makefile.am&lt;/code&gt;, re-run &lt;code&gt;./configure&lt;/code&gt; then &lt;code&gt;make&lt;/code&gt;. When you change &lt;code&gt;configure.ac&lt;/code&gt;, re-run &lt;code&gt;autoreconf --install&lt;/code&gt;, &lt;code&gt;./configure&lt;/code&gt;, then &lt;code&gt;make&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The generated Makefile is usually smart enough to re-run &lt;code&gt;./configure&lt;/code&gt; automatically as needed, but this only works if the Makefile is functional. If something isn&amp;rsquo;t working, it is safe to re-run these commands to confirm Autotools configuration isn&amp;rsquo;t the issue.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;wrangling-intermediate-build-files&#34;&gt;Wrangling intermediate build files&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Oh my gawd&lt;/em&gt; what are all those files doing in our project?? Yes, Autotools just made a big mess, spitting out helper scripts, log files, and intermediate forms of various things. None of these files should be committed to your source repo.&lt;/p&gt;
&lt;p&gt;Github provides a &lt;a href=&#34;https://github.com/github/gitignore/blob/main/Autotools.gitignore&#34;&gt;default .gitignore file for Autotools projects&lt;/a&gt; that prevents build artifacts from getting committed. We definitely want all of those rules in our &lt;code&gt;.gitignore&lt;/code&gt; file. I found a bunch more as I was setting up my project.&lt;/p&gt;
&lt;p&gt;Is there a way to get Autotools to just&amp;hellip; not do that? Like, put everything in a &lt;code&gt;build/&lt;/code&gt; subdirectory? Yes and no. Autoconf (the first &lt;code&gt;autoreconf&lt;/code&gt; step) needs to produce files in the project root.&lt;/p&gt;
&lt;p&gt;Assuming our Makefiles are written correctly, Automake is a little more flexible: you can run the &lt;code&gt;configure&lt;/code&gt; script from any directory. That directory becomes the &lt;em&gt;build tree&lt;/em&gt;, and all subsequent files are generated there. The location of the &lt;code&gt;configure&lt;/code&gt; script is considered the &lt;em&gt;source tree&lt;/em&gt;. Automake knows how to find what it needs in both locations, and avoids writing to the source tree. When we tell it to build the source distribution, it will test this by making the source files read-only while it does a build.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;autoreconf --install
mkdir build
cd build
../configure
make&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I say you can run the &lt;code&gt;configure&lt;/code&gt; script, but what I really mean is &lt;em&gt;the user&lt;/em&gt; can run the &lt;code&gt;configure&lt;/code&gt; script. Nothing about the contents of the &lt;code&gt;configure.ac&lt;/code&gt; and &lt;code&gt;Makefile.am&lt;/code&gt; files themselves should assume the location of the build tree. You can write a utility script of your own to divert Automake output if you like. (Put it in &lt;code&gt;scripts/&lt;/code&gt;.) Do not write rules that assume one way or the other.&lt;/p&gt;
&lt;p&gt;OK, so if it&amp;rsquo;s so common to just let Autotools make a big mess, is there a way to clean it up? Yes and no:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;make clean&lt;/code&gt; does a good job deleting files produced by &lt;code&gt;make&lt;/code&gt;. Automake generates this rule for you in the &lt;code&gt;Makefile&lt;/code&gt; it produces.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make distclean&lt;/code&gt; goes further and mops up the generated &lt;code&gt;Makefile&lt;/code&gt; file and a few others. You can&amp;rsquo;t run &lt;code&gt;make&lt;/code&gt; again until you re-run &lt;code&gt;./configure&lt;/code&gt; to re-generate &lt;code&gt;Makefile&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;There&amp;rsquo;s also a &lt;code&gt;make maintainer-clean&lt;/code&gt; which is the same as &lt;code&gt;distclean&lt;/code&gt; by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of these rules undoes what &lt;code&gt;autoreconf&lt;/code&gt; does. This is by design: these rules are available in the source distribution you send to users, and users are not expected to have Autotools installed, so they can&amp;rsquo;t (and shouldn&amp;rsquo;t) run &lt;code&gt;autoreconf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I settled on the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Let Autoconf, Automake, and make spew files into my source tree.&lt;/li&gt;
&lt;li&gt;Block generated files from my repo with a thorough &lt;code&gt;.gitignore&lt;/code&gt;, based on &lt;a href=&#34;https://github.com/github/gitignore/blob/main/Autotools.gitignore&#34;&gt;the Github starter&lt;/a&gt;, extending it as needed.&lt;/li&gt;
&lt;li&gt;As I add new rules that generate their own intermediate files, add these to &lt;code&gt;.gitignore&lt;/code&gt;. Also add them to the &lt;code&gt;CLEANFILES&lt;/code&gt; variable in the appropriate &lt;code&gt;Makefile.am&lt;/code&gt;, which adds them to the list of files deleted by &lt;code&gt;make clean&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Technically that&amp;rsquo;s sufficient &lt;em&gt;if your Makefiles are written correctly&lt;/em&gt;. As I was setting up my first project, I discovered many cases where I had an error that generated a bad file, didn&amp;rsquo;t clean up automatically, and got stuck with bad behavior until I deleted it myself.&lt;/p&gt;
&lt;p&gt;So I wrote a tool that &amp;ldquo;super-cleans&amp;rdquo; the project directory, deleting every file ignored by &lt;code&gt;.gitignore&lt;/code&gt;. It also cleans up any files that were created in Git submodules, which in my case are always build artifacts because I am not editing submodules via the project directory. (We&amp;rsquo;re about to use submodules to bring in a testing library.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 scripts/superclean.py&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/dansanderson/c-autotools-template/blob/main/scripts/superclean.py&#34;&gt;scripts/superclean.py&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This gives me peace of mind that my project repo is buildable from scratch without any of the build artifacts giving me a false sense of security.&lt;/p&gt;
&lt;h2 id=&#34;installing-unity-test-and-cmock&#34;&gt;Installing Unity Test and CMock&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m used to using automated unit tests as a regular part of my development workflow. I wouldn&amp;rsquo;t impress a &lt;a href=&#34;https://en.wikipedia.org/wiki/Test-driven_development&#34;&gt;Test-Driven Development&lt;/a&gt; aficionado, but I happily annoy my teammates with an insistence on high test coverage.&lt;/p&gt;
&lt;p&gt;For a test framework, I went with &lt;a href=&#34;http://www.throwtheswitch.org/unity&#34;&gt;Unity Test&lt;/a&gt; and &lt;a href=&#34;http://www.throwtheswitch.org/cmock&#34;&gt;CMock&lt;/a&gt; by &lt;a href=&#34;http://www.throwtheswitch.org/&#34;&gt;ThrowTheSwitch.org&lt;/a&gt;. The C code is lean without dependencies on libraries or specific build systems. They use Ruby scripts for code generation, so this adds a dependency on Ruby, but only for running tests. Source distro users can still build and install with just the POSIX tools.&lt;/p&gt;
&lt;p&gt;Unity Test and CMock are &lt;a href=&#34;https://github.com/ThrowTheSwitch/CMock/blob/master/LICENSE.txt&#34;&gt;MIT licensed&lt;/a&gt;, which is compatible with my project&amp;rsquo;s license, so I can include them in my project and source distribution. I could have downloaded and copied CMock into my &lt;code&gt;third-party/&lt;/code&gt; library, and you might want to do it that way for the security of freezing a local copy. I used &lt;a href=&#34;https://git-scm.com/book/en/v2/Git-Tools-Submodules&#34;&gt;Git submodules&lt;/a&gt; to formalize the relationship directly in my repo metadata. CMock brings in Unity Test (and their CException library) recursively, so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir third-party
cd third-party
git submodule add https://github.com/ThrowTheSwitch/CMock.git
git submodule update --init --recursive&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates &lt;code&gt;.gitmodules&lt;/code&gt; in the project root, and downloads CMock into &lt;code&gt;third-party/CMock/&lt;/code&gt;. Unity Test is inside, under &lt;code&gt;third-party/CMock/vendor/unity/&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;Be sure to mention in your project&amp;rsquo;s developer documentation that contributors should &lt;code&gt;git clone&lt;/code&gt; your project repo with the &lt;code&gt;--recurse-submodules&lt;/code&gt; option, or run &lt;code&gt;git submodule update --init --recursive&lt;/code&gt; after cloning.&lt;/p&gt;
&lt;p&gt;Users building from the source distribution will not need Git in any form, as we&amp;rsquo;ll soon see.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;A build tool might spit out some temporary files inside the submodule directory. I&amp;rsquo;m not contributing to these submodules by editing them locally, so this is OK, but it confuses tools trying to report status. Edit &lt;code&gt;.gitmodules&lt;/code&gt; and add &lt;code&gt;ignore = dirty&lt;/code&gt;, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[submodule &amp;#34;third-party/CMock&amp;#34;]
  path = third-party/CMock
  url = https://github.com/ThrowTheSwitch/CMock
  ignore = dirty&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Commands like &lt;code&gt;git status&lt;/code&gt; now know to ignore anything that Autotools creates under &lt;code&gt;third-party/CMock/&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;callout note&#34;&gt;
&lt;p&gt;Alas, VSCode&amp;rsquo;s Git support does &lt;em&gt;not&lt;/em&gt; know to honor &lt;code&gt;ignore = dirty&lt;/code&gt; for submodules, and will draw annoying colored dots in the file explorer for &lt;code&gt;third-party/&lt;/code&gt; after a test build. I try to ignore it, and when I really want it to go away I use my &lt;code&gt;superclean.py&lt;/code&gt; script. 😅&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;For the source distribution to work, it needs the files from Unity Test and CMock that we depend on in the Makefile. Everything listed under a &lt;code&gt;SOURCES&lt;/code&gt; rule is already included, but this does not include the Ruby scripts. To make sure they also get included, define &lt;code&gt;EXTRA_DIST&lt;/code&gt; in &lt;code&gt;Makefile.am&lt;/code&gt;. (Also include CMock&amp;rsquo;s &lt;code&gt;LICENSE.txt&lt;/code&gt; because we&amp;rsquo;re distributing CMock sources.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;EXTRA_DIST = \
    README.md \
    third-party/CMock/LICENSE.txt \
    third-party/CMock/README.md \
    third-party/CMock/config \
    third-party/CMock/lib \
    third-party/CMock/scripts \
    third-party/CMock/vendor/unity/LICENSE.txt \
    third-party/CMock/vendor/unity/README.md \
    third-party/CMock/vendor/unity/auto&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I tried just listing &lt;code&gt;third-party/CMock&lt;/code&gt; here, but this can accidentally include some build artifacts in the final source distribution that cause the distribution verification build to fail.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-unity-test-with-autotools&#34;&gt;Setting up Unity Test with Autotools&lt;/h2&gt;
&lt;p&gt;The CMock project repo has Meson build files in it, but thankfully we don&amp;rsquo;t need those. There are only a few C sources, and we can refer to them directly in our own build rules, or make them an LT library to avoid unnecessary rebuilds. We&amp;rsquo;ll also need new custom rules for running the Ruby scripts to generate source files.&lt;/p&gt;
&lt;p&gt;I want to be extra supportive to my users regarding the Ruby dependency. I could just let the &lt;code&gt;ruby&lt;/code&gt; command in my build rules fail if it&amp;rsquo;s not present, but it&amp;rsquo;s more polite to explicitly check for it and fail with a message if needed. It should not be required for the main build, and the test build should print a useful message and abort.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s get Autoconf to help, because part of its job is to look for tools. In &lt;code&gt;configure.ac&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AC_PATH_PROG([RUBY], [ruby])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks for &lt;code&gt;ruby&lt;/code&gt; on the command path, and either sets the &lt;code&gt;RUBY&lt;/code&gt; variable to the path to the tool if found, or sets it to the empty string if not found. Our Makefile rules that run Ruby scripts can start with this line to test this variable and bail with a nice error message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    @test -n &amp;#34;$(RUBY)&amp;#34; || { echo &amp;#34;\nPlease install Ruby to run tests.\n&amp;#34;; exit 1; }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We could have used a different &lt;code&gt;configure.ac&lt;/code&gt; macro to cause the &lt;code&gt;./configure&lt;/code&gt; step to fail if Ruby is not found, but again, I want the main build to work without Ruby.&lt;/p&gt;
&lt;p&gt;We will put test source files under &lt;code&gt;tests/&lt;/code&gt;, in a subdirectory named after the module under test. Test suites are C source files whose names start with &lt;code&gt;test_&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tests/cfgfile/test_cfgfile.c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A module test suite includes the header file of the module under test, and the &lt;code&gt;unity.h&lt;/code&gt; header. Each test is a function with a name starting with &lt;code&gt;test_&lt;/code&gt;. It can have an optional &lt;code&gt;setUp()&lt;/code&gt; and &lt;code&gt;tearDown()&lt;/code&gt;. Unity provides various assertions with useful error reporting.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;#34;cfgfile/cfgfile.h&amp;#34;
#include &amp;#34;unity.h&amp;#34;

void setUp(void) {}

void tearDown(void) {}

void test_cfgfileFunc_ReturnsZero(void) {
  TEST_ASSERT_EQUAL_MESSAGE(0, cfgfile_func(999), &amp;#34;func returns 0&amp;#34;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See &lt;a href=&#34;http://www.throwtheswitch.org/unity&#34;&gt;the Unity Test docs&lt;/a&gt; and &lt;a href=&#34;https://github.com/ThrowTheSwitch/Unity/tree/master/docs&#34;&gt;more docs&lt;/a&gt; for details on how to write test suites. It&amp;rsquo;s good stuff.&lt;/p&gt;
&lt;p&gt;Notice there&amp;rsquo;s no &lt;code&gt;main()&lt;/code&gt; in the test suite. Unity Test generates a &lt;em&gt;runner&lt;/em&gt; program with a main routine that does all the setting up, tearing down, and calling of test functions.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s set up the test rules. Add the following lines to &lt;code&gt;Makefile.am&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;## Top of Makefile.am

check_LTLIBRARIES = libcmock.la
libcmock_la_SOURCES = \
    third-party/CMock/src/cmock.c \
    third-party/CMock/src/cmock.h \
    third-party/CMock/src/cmock_internals.h \
    third-party/CMock/vendor/unity/src/unity.c \
    third-party/CMock/vendor/unity/src/unity.h \
    third-party/CMock/vendor/unity/src/unity_internals.h
libcmock_la_CPPFLAGS = \
    -I$(top_srcdir)/third-party/CMock/vendor/unity/src \
    -I$(top_srcdir)/third-party/CMock/src

CLEANFILES = tests/runners/runner_test_*.c
check_PROGRAMS =

## cfgfile module

check_PROGRAMS += tests/runners/test_cfgfile

# Replace these indents with tabs!
tests/runners/runner_test_cfgfile.c: tests/cfgfile/test_cfgfile.c
    @test -n &amp;#34;$(RUBY)&amp;#34; || { echo &amp;#34;\nPlease install Ruby to run tests.\n&amp;#34;; exit 1; }
    mkdir -p tests/runners
    $(RUBY) $(top_srcdir)/third-party/CMock/vendor/unity/auto/generate_test_runner.rb $&amp;lt; $@

tests/cfgfile/runners_test_cfgfile-test_cfgfile.$(OBJEXT): \
    tests/runners/runner_test_cfgfile.c \
    libcfgfile.la \
    libcmock.la

tests_runners_test_cfgfile_SOURCES = \
    tests/cfgfile/test_cfgfile.c \
    src/cfgfile/cfgfile.h
nodist_tests_runners_test_cfgfile_SOURCES = \
    tests/runners/runner_test_cfgfile.c
tests_runners_test_cfgfile_LDADD = \
    libcfgfile.la \
    libcmock.la
tests_runners_test_cfgfile_CPPFLAGS = \
    -I$(top_srcdir)/third-party/CMock/vendor/unity/src \
    -I$(top_srcdir)/third-party/CMock/src \
    -I$(top_srcdir)/src

## Bottom of Makefile.am

TESTS = $(check_PROGRAMS)&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&#34;callout caution&#34;&gt;
&lt;p&gt;Remember that in a &lt;code&gt;Makefile.am&lt;/code&gt;, just like in a &lt;code&gt;Makefile&lt;/code&gt;, shell commands in rule definitions need to be indented with tab characters. Copy-pasting from this article won&amp;rsquo;t do this correctly (thanks to my Markdown editor, sorry), so be extra careful if you&amp;rsquo;re following along. The commands in the &lt;code&gt;runners&lt;/code&gt; rule must be intended with tabs.&lt;/p&gt;
&lt;p&gt;And &lt;em&gt;oh my gawd&lt;/em&gt; the error messages for incorrect indentation are &lt;em&gt;unhelpful.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;check_LTLIBRARIES&lt;/code&gt; builds Libtool libraries specifically for testing (which Autotools calls &amp;ldquo;checking&amp;rdquo;). We define such a library for CMock sources, so it only gets built once for the project then linked into every test runner. &lt;code&gt;libcmock.la&lt;/code&gt; definitions only need to appear once for the entire file.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;check_PROGRAMS&lt;/code&gt; is similar to &lt;code&gt;bin_PROGRAMS&lt;/code&gt;, but this specifically declares programs that should be built for the purposes of testing. &lt;code&gt;TESTS&lt;/code&gt; is the list of programs to run when testing, which in this case is identical to &lt;code&gt;check_PROGRAMS&lt;/code&gt; so we just make them equal.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tests/runners/runner_test_cfgfile.c:&lt;/code&gt; is a Makefile rule (not an Automake definition) for generating the test runner. When this file is needed, the rule invokes Unity Test with &lt;code&gt;tests/cfgfile/test_cfgfile.c&lt;/code&gt; as an argument. These source files are referred to by &lt;code&gt;CLEANFILES&lt;/code&gt; so that &lt;code&gt;make clean&lt;/code&gt; knows to delete them.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tests/cfgfile/runners_test_cfgfile-test_cfgfile.$(OBJEXT):&lt;/code&gt; is another rule, though this rule has no commands, only dependencies. The rule name is the name of the object file for &lt;code&gt;runner_test_cfgfile.c&lt;/code&gt;. The &lt;code&gt;-test_cfgfile&lt;/code&gt; piece is the name of the program that depends on it. &lt;code&gt;$(OBJEXT)&lt;/code&gt; is the object filename extension for the target platform (such as, but not always, &lt;code&gt;.o&lt;/code&gt;). This rule says, &amp;ldquo;Before you try to build &lt;code&gt;runner_test_cfgfile.c&lt;/code&gt;, make sure to trigger the rule that generates it, and the rules for the related convenience libraries.&amp;rdquo;&lt;/p&gt;
&lt;div class=&#34;callout note&#34;&gt;
&lt;p&gt;The convenience libraries are listed as dependencies here in case any library build generates a header file that we need to compile this test. &lt;code&gt;LDADD&lt;/code&gt; causes the dependencies to built, but not necessarily before test sources are compiled.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We declared a &lt;code&gt;tests/runners/test_cfgfile&lt;/code&gt; program, so it has &lt;code&gt;tests_runners_test_cfgfile_SOURCES&lt;/code&gt;, with our test source and the header for the module under test is here. &lt;code&gt;nodist_tests_runners_test_cfgfile_SOURCES&lt;/code&gt; lists the generated runner source. The &lt;code&gt;nodist_&lt;/code&gt; prevents the generated source from being included in the source distribution. The &lt;code&gt;LDADD&lt;/code&gt; links in the dependency libraries. &lt;code&gt;CPPFLAGS&lt;/code&gt; adds Unity Test, CMock, and the project &lt;code&gt;src/&lt;/code&gt; directory to the &lt;code&gt;#include&lt;/code&gt; path.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;TESTS&lt;/code&gt; definition lists all programs that should be run when testing the project. For our purposes, it can be identical to &lt;code&gt;check_PROGRAMS&lt;/code&gt;, so we equate them at the bottom of the file.&lt;/p&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;It&amp;rsquo;s a good practice to make sure generated sources are generated by the user&amp;rsquo;s build. Relying on Automake to generate sources then include the generated result in the source distribution is fragile and not the intent of Automake&amp;rsquo;s design.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.gnu.org/software/automake/manual/html_node/Built-Sources-Example.html&#34;&gt;Built Sources Examples&lt;/a&gt; section of the Automake manual proposes several ways to trigger the generation of sources. The technique used here, with the dependency list on the first source file&amp;rsquo;s object file, allows the test runner to be built in isolation from a clean build tree. Alternatively, we could have defined &lt;code&gt;BUILT_SOURCES&lt;/code&gt; as a list of the generated files to be built before building any targets, but as described in the manual, this would only trigger for &lt;code&gt;make all&lt;/code&gt;, &lt;code&gt;make check&lt;/code&gt;, and &lt;code&gt;make install&lt;/code&gt;. With this method, we can &lt;code&gt;make tests/runners/runner_text_cfgfile&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We can now run unit tests. To build and run every test suite:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make check&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To build every test suite (as needed) and run a specific test:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make check TESTS=&amp;#39;tests/cfgfile/test_cfgfile&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;setting-up-cmock&#34;&gt;Setting up CMock&lt;/h2&gt;
&lt;p&gt;CMock takes a module&amp;rsquo;s external header file (such as &lt;code&gt;src/cfgfile/cfgfile.h&lt;/code&gt;) and generates source for a mock version of the module with all of the same functions. The mock version allows tests to declare expected inputs and outputs for the functions, for the purposes of testing.&lt;/p&gt;
&lt;p&gt;Why would we want this? If we&amp;rsquo;re writing tests for a module, we want our tests to call the module&amp;rsquo;s actual code. But we &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; want it to call the actual code of a module on which the module under test depends. In an extreme case, using all real code requires setting up a test environment that can run the entire program. For this to be a &lt;em&gt;unit&lt;/em&gt; test, it should only test the one module.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;executor&lt;/code&gt; is the module under test, and it depends on &lt;code&gt;cfgfile&lt;/code&gt;, we can build the runner program for &lt;code&gt;executor&lt;/code&gt;&amp;rsquo;s test suite so that it links with the mock verison of &lt;code&gt;cfgfile&lt;/code&gt; instead of the actual &lt;code&gt;cfgfile&lt;/code&gt;. This ensures that only &lt;code&gt;executor&lt;/code&gt; code is being tested, and avoids propagating test environment dependencies to every test suite.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;Makefile.am&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Replace these indents with tabs!
tests/mocks/mock_cfgfile.c: src/cfgfile/cfgfile.h
    @test -n &amp;#34;$(RUBY)&amp;#34; || { echo &amp;#34;\nPlease install Ruby to run tests.\n&amp;#34;; exit 1; }
    mkdir -p tests/mocks
    CMOCK_DIR=$(top_srcdir)/third-party/CMock \
    MOCK_OUT=tests/mocks \
    $(RUBY) $(top_srcdir)/third-party/CMock/scripts/create_mock.rb $&amp;lt;

check_LTLIBRARIES += libcfgfile_mock.la
nodist_libcfgfile_mock_la_SOURCES = \
    tests/mocks/mock_cfgfile.c
libcfgfile_mock_la_CPPFLAGS = \
    -I$(top_srcdir)/third-party/CMock/vendor/unity/src \
    -I$(top_srcdir)/third-party/CMock/src \
    -I$(top_srcdir)/src \
    -I$(top_srcdir)/src/cfgfile
libcfgfile_mock_la_LIBADD = libcmock.la

CLEANFILES += tests/mocks/mock_cfgfile.c tests/mocks/mock_cfgfile.h&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&#34;callout caution&#34;&gt;
&lt;p&gt;Remember to use tabs to indent the commands in the mock generation rule!&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This should be familiar. The only tricky bit is we add &lt;code&gt;src/cfgfile&lt;/code&gt; to the include path. CMock&amp;rsquo;s generated mock source attempts to &lt;code&gt;#include&lt;/code&gt; the original module header without a leading path, so we add the module source root to the include path. (There&amp;rsquo;s an undocumented config option for CMock to add a header prefix, but I couldn&amp;rsquo;t see how to pass it on the command line, so I&amp;rsquo;m doing this instead.)&lt;/p&gt;
&lt;p&gt;Earlier we imagined a module named &lt;code&gt;executor&lt;/code&gt; that depends on &lt;code&gt;cfgfile&lt;/code&gt;, so let&amp;rsquo;s continue that example. Set up unit tests for &lt;code&gt;executor&lt;/code&gt;, linking the &lt;code&gt;libexecutor.la&lt;/code&gt; library and the &lt;code&gt;libcfgfile_mock.la&lt;/code&gt; libraries.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;check_PROGRAMS += tests/runners/test_executor

# Replace these indents with tabs!
tests/runners/runner_test_executor.c: tests/cfgfile/test_executor.c
    @test -n &amp;#34;$(RUBY)&amp;#34; || { echo &amp;#34;\nPlease install Ruby to run tests.\n&amp;#34;; exit 1; }
    mkdir -p tests/runners
    $(RUBY) $(top_srcdir)/third-party/CMock/vendor/unity/auto/generate_test_runner.rb $&amp;lt; $@

tests/executor/runners_test_executor-test_executor.$(OBJEXT): \
    tests/runners/runner_test_executor.c \
    tests/mocks/mock_cfgfile.c \
    tests/mocks/mock_cfgfile.h \
    libcmock.la \
    libexecutor.la \
    libcfgfile_mock.la

tests_runners_test_executor_SOURCES = \
    tests/executor/test_executor.c \
    src/executor/executor.h
nodist_tests_runners_test_executor_SOURCES = \
    runners/runner_test_executor.c \
    tests/mocks/mock_cfgfile.c \
    tests/mocks/mock_cfgfile.h
tests_runners_test_executor_LDADD = \
    libcmock.la \
    libexecutor.la \
    libcfgfile_mock.la
tests_runners_test_executor_CPPFLAGS = \
    -I$(top_srcdir)/third-party/CMock/vendor/unity/src \
    -I$(top_srcdir)/third-party/CMock/src \
    -I$(top_srcdir)/src \
    -Itests/mocks&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now our &lt;code&gt;tests/executor/test_executor.c&lt;/code&gt; can engage the mock &lt;code&gt;cfgfile&lt;/code&gt; before calling &lt;code&gt;executor&lt;/code&gt; methods, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;#34;executor/executor.h&amp;#34;
#include &amp;#34;mock_cfgfile.h&amp;#34;
#include &amp;#34;unity.h&amp;#34;

void test_Square_UsesExampleTwo(void) {
  cfgfile_func_ExpectAndReturn(7, 49);
  int result = executor_doit(7);
  TEST_ASSERT_EQUAL_INT(49, result);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This assumes the &lt;code&gt;executor&lt;/code&gt; module exports an &lt;code&gt;int executor_doit(int)&lt;/code&gt; function that calls &lt;code&gt;cfgfile_func&lt;/code&gt;. I&amp;rsquo;ll let you invent your own definition for the example. 😄&lt;/p&gt;
&lt;p&gt;Re-run our build commands, then &lt;code&gt;make check&lt;/code&gt; to see the new test in action:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./configure
make check&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;too-much-boilerplate&#34;&gt;Too much boilerplate!&lt;/h2&gt;
&lt;p&gt;We walked through &lt;code&gt;Makefile.am&lt;/code&gt; code for setting up test runners and mocks just to understand it better, but that&amp;rsquo;s too much boilerplate to manage for each module. I just want to be able to say the name of a module and the modules it depends on, and have everything just work.&lt;/p&gt;
&lt;p&gt;I resisted writing a module management system, I really did. I researched best practices for a solid week, hoping to find a canonical C language workflow with all of the modern features I&amp;rsquo;m used to. Perhaps not surprisingly, not even GNU Autotools itself has exactly one way to do some things.&lt;/p&gt;
&lt;p&gt;I had an early version that minimized repeated text using Makefile variables and pattern rules, which helped some. Plain Makefiles have a way to define variables to contain entire templated rules, which would be super-useful here and almost a complete solution. Unfortunately, while Automake can pass through some Makefile definitions to the final Makefile, it does &lt;em&gt;not&lt;/em&gt; support multi-line variable definitions or full-text macros. Regardless, what I actually need is for those templates to expand to &lt;em&gt;Automake&lt;/em&gt; definitions.&lt;/p&gt;
&lt;p&gt;I concluded that it&amp;rsquo;s just easier to reason about modules, and easier to write corresponding templated Automake rules, if I use another layer of code generation. Here also I tried looking for prior art. &lt;a href=&#34;https://www.gnu.org/software/gnulib/manual/html_node/Modules.html&#34;&gt;Gnulib has a module system&lt;/a&gt; called &lt;code&gt;gnulib-tool&lt;/code&gt; that takes module description files and generates &lt;code&gt;configure.ac&lt;/code&gt; and &lt;code&gt;Makefile.am&lt;/code&gt;. I was running out of patience with on-boarding at this point, and decided that a little bit of Python within the repo was better than adding another tool dependency.&lt;/p&gt;
&lt;p&gt;Yes, this means Python itself is a new dependency. I could have used Ruby, which is already needed for CMock, or Perl, which is already used by Automake, or C, which is the language of choice for the project itself. I could have even used &lt;a href=&#34;https://www.gnu.org/software/m4/manual/m4.html&#34;&gt;m4&lt;/a&gt;, the macro language on which Autoconf is based and is therefore included with Autotools. If you want to port my scripts for me, have at it. 😉&lt;/p&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;It&amp;rsquo;s tempting to rewrite at least the code generator rules as pattern rules, so they only need to appear once in the file. Unfortunately, the way we&amp;rsquo;ve written them would require that the &lt;code&gt;%&lt;/code&gt; pattern substitution happen more than once (the directory name and the source name), which is not supported by pattern rules.&lt;/p&gt;
&lt;p&gt;Luckily we&amp;rsquo;re about to introduce a Makefile generation tool, so we won&amp;rsquo;t need to worry about too much repetition.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;callout note&#34;&gt;
&lt;p&gt;I don&amp;rsquo;t really understand how Autotools can have an entire macro language in it and not make it more accessible to Automake. Maybe I&amp;rsquo;m fundamentally misunderstanding how Autotools is meant to be customized, but I didn&amp;rsquo;t see any good examples of macro-izing &lt;code&gt;Makefile.am&lt;/code&gt; in books and manuals.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;generating-makefileam&#34;&gt;Generating Makefile.am&lt;/h2&gt;
&lt;p&gt;I took everything covered in this article and rewrote it as a tool that scans the &lt;code&gt;src/&lt;/code&gt; and &lt;code&gt;tests/&lt;/code&gt; directories and generates the Automake definitions for all of the library and program modules, along with a preamble and postamble. Each module has a &lt;code&gt;module.cfg&lt;/code&gt; file that declares whether the module is a library or program, and declares which library modules it depends on. For example, here&amp;rsquo;s &lt;code&gt;src/executor/module.cfg&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[module]
library = executor
deps = cfgfile&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The script generates a complete &lt;code&gt;Makefile.am&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 scripts/makemake.py&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You run the script every time you would normally edit &lt;code&gt;Makefile.am&lt;/code&gt;, such as after creating or deleting a source file, or modifying a &lt;code&gt;module.cfg&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;This greatly simplifies the management of Makefile rules—assuming the project can be organized into modules as we&amp;rsquo;ve described them.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/dansanderson/c-autotools-template/blob/main/README.md&#34;&gt;the README&lt;/a&gt; for instructions on how to use &lt;code&gt;makemake.py&lt;/code&gt; and &lt;code&gt;module.cfg&lt;/code&gt; files. I have opted to commit the generated &lt;code&gt;Makefile.am&lt;/code&gt; to the source repo, so you can &lt;a href=&#34;https://github.com/dansanderson/c-autotools-template/blob/main/Makefile.am&#34;&gt;browse the example Makefile.am&lt;/a&gt;. There are a few other fun features in there, too.&lt;/p&gt;
&lt;p&gt;To completely reset the workspace:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 scripts/superclean.py
python3 scripts/makemake.py
autoreconf --install
./configure
make&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;make-distcheck&#34;&gt;make distcheck&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=IYRurPB4WA0&#34;&gt;It&amp;rsquo;s time to make the donuts!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Run this command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make distcheck&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This produces the source distribution, &lt;code&gt;myapp-0.1.tar.gz&lt;/code&gt;. Give it to your friends.&lt;/p&gt;
&lt;p&gt;As if that weren&amp;rsquo;t already kind of amazing, &lt;code&gt;distcheck&lt;/code&gt; also &lt;em&gt;tests&lt;/em&gt; the source distribution. It does the whole &lt;code&gt;tar xzf&lt;/code&gt; and &lt;code&gt;./configure&lt;/code&gt; and &lt;code&gt;make&lt;/code&gt; process off in a temporary directory to make sure all of the generated rules run in isolation from your project directory. It also runs &lt;code&gt;make check&lt;/code&gt; to perform your test suite on the result.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;This C Autotools project starter template and associated tools provide a simple way to organize, build, test, and distribute applications written in C. I&amp;rsquo;ll probably be revising it as I realize its shortcomings over the course of a real project.&lt;/p&gt;
&lt;p&gt;As usual, I&amp;rsquo;m eager for feedback, especially if I&amp;rsquo;m overlooking Autotools or C project best practices, or popular tool alternatives.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/dansanderson/c-autotools-template&#34;&gt;C Autotools new project template&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded>
      
    </item>
    
    <item>
      <title>Using MEGA65&#39;s Matrix Mode</title>
      <link>https://dansanderson.com/lab-notes/mega65-matrix-mode/</link>
      <pubDate>Sun, 31 Jul 2022 11:58:51 -0700</pubDate>
      <author>contact@dansanderson.com (Dan Sanderson)</author>
      <guid>https://dansanderson.com/lab-notes/mega65-matrix-mode/</guid>
      <description>&lt;p&gt;The MEGA65 has a powerful debugging facility built into it that would have been high fantasy for vintage computer programmers back in the day: the Matrix Mode debugger. Today in Lab Notes, we explore Matrix Mode&amp;rsquo;s capabilities to further help us with assembly language programming, continuing to use our Game of Life program as an example.&lt;/p&gt;</description>
      <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;The MEGA65 has a powerful debugging facility built into it that would have been high fantasy for vintage computer programmers back in the day: the Matrix Mode debugger. Today in Lab Notes, we explore Matrix Mode&amp;rsquo;s capabilities to further help us with assembly language programming, continuing to use our Game of Life program as an example.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Articles in this series:&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-game-of-life/&#34;&gt;Game of Life on the MEGA65, in BASIC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-game-of-life-in-assembly/&#34;&gt;Game of Life on the MEGA65, in assembly language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-monitor/&#34;&gt;Using the MEGA65 Monitor to troubleshoot assembly programs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Using MEGA65&amp;rsquo;s Matrix Mode&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;the-story-so-far&#34;&gt;The story so far&lt;/h2&gt;
&lt;p&gt;We prototyped &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-game-of-life/&#34;&gt;a MEGA65 version of Conway&amp;rsquo;s Game of Life in BASIC&lt;/a&gt;. We reimplemented &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-game-of-life-in-assembly/&#34;&gt;the generation algorithm in assembly language&lt;/a&gt; for a huge speed increase, and discussed assembly debugging techniques that involved adding test code and data visualizations to the program itself. We did a deep dive on &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-monitor/&#34;&gt;the MEGA65 machine language monitor&lt;/a&gt;, which allowed us to do some of the same debugging tasks by adding only &lt;code&gt;brk&lt;/code&gt; statements (and occasionally some conditional checks) to the code.&lt;/p&gt;
&lt;p&gt;Today, we will explore another powerful tool for debugging machine code, something exclusive to the MEGA65 that I could barely dream about with vintage computers back in the day: the Matrix Mode debugger.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll continue to use our Game of Life program as an interactive example. As before, make sure you have the &lt;a href=&#34;https://sourceforge.net/projects/acme-crossass/&#34;&gt;ACME assembler&lt;/a&gt; and the Game of Life source file:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-game-of-life-in-assembly/golml.a&#34;&gt;golml.a&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Use this command to build the PRG file and generate the symbol list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;acme --symbollist golml.lst golml.a&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Today, we&amp;rsquo;ll be debugging &lt;em&gt;without&lt;/em&gt; making changes to the program code. If you don&amp;rsquo;t have a &lt;a href=&#34;https://dansanderson.com/mega65/welcome/using-jtag.html&#34;&gt;a JTAG or serial connection&lt;/a&gt;, you can just copy the PRG file to your MEGA65&amp;rsquo;s SD card, and load it as needed like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DLOAD &amp;#34;GOLML.PRG&amp;#34;,U12&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That said, if you don&amp;rsquo;t have a JTAG or serial connection, you&amp;rsquo;ll want one by the end of this article.&lt;/p&gt;
&lt;h2 id=&#34;what-is-the-matrix-mode-debugger&#34;&gt;What is the Matrix Mode debugger?&lt;/h2&gt;
&lt;p&gt;Most of the MEGA65 architecture roughly resembles the Commodore 65 on which it is based: there&amp;rsquo;s a CPU, memory, video and sound hardware, and interfaces for the vintage peripheral ports. This architecture runs our BASIC and assembly language programs, as well as code in the ROM for the kernel, the BASIC interpreter, and the MEGA65 monitor. This CPU can either run our program &lt;em&gt;or&lt;/em&gt; it can run the MEGA65 monitor. As we&amp;rsquo;ve seen, we can add a &lt;code&gt;brk&lt;/code&gt; instruction to interrupt our program and start the monitor.&lt;/p&gt;
&lt;p&gt;Surrounding the C65-like hardware is an outer shell with its own operating system (known as the &lt;em&gt;Hypervisor&lt;/em&gt;). This manages all of the modern conveniences and hardware interfaces, such as the configuration utility, the SD card, the core manager, and the Freeze utility.&lt;/p&gt;
&lt;p&gt;The Matrix Mode debugger is a tool in the outer shell. It has greater visibility into—and control of—system state than the MEGA65 monitor because it runs &lt;em&gt;outside of&lt;/em&gt; and &lt;em&gt;simultaneous to&lt;/em&gt; the C65-like inner architecture. Like the MEGA65 monitor, it has features for inspecting and editing memory and register contents. It can also do things the MEGA65 monitor could ever do: it can pause the CPU entirely, tell it to step through machine code one instruction at a time, and watch a running program for specific changes to the program counter, registers, and memory locations.&lt;/p&gt;
&lt;p&gt;The debugger uses a simple command interface. This interface can be accessed directly on the MEGA65, or it can be accessed from your PC over a serial connection with a JTAG/serial adapter. The command interface also serves as a serial protocol that cross-development tools can use to manipulate the MEGA65.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start by taking a look at the command console options. Then we will explore how to use Matrix Mode commands to perform debugging tasks.&lt;/p&gt;
&lt;h2 id=&#34;the-matrix-mode-command-console&#34;&gt;The Matrix Mode command console&lt;/h2&gt;
&lt;p&gt;Try this: Load and run Game of Life. Draw a quick pattern, something that cycles (such as the blinker), then press &lt;kbd&gt;Return&lt;/kbd&gt; to start the evolution.&lt;/p&gt;
&lt;p&gt;While the program is running, hold the &lt;kbd&gt;Mega&lt;/kbd&gt; key, then press &lt;kbd&gt;Tab&lt;/kbd&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/matrixmode.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/matrixmode.png 640w, https://dansanderson.com/lab-notes/mega65-matrix-mode/matrixmode_hu_219d61c3b28db1ee.png 600w, https://dansanderson.com/lab-notes/mega65-matrix-mode/matrixmode_hu_90c41985dad083d2.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/matrixmode.png&#34;
        alt=&#34;Matrix Mode with the Game of Life program running&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Matrix Mode console, with Game of Life running in the background
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Welcome to Matrix Mode! Named and styled after &lt;a href=&#34;https://www.imdb.com/title/tt0133093/&#34;&gt;the 1999 sci-fi action thriller&lt;/a&gt;, Matrix Mode lets you perform machine language monitor tasks &lt;em&gt;while the program is running&lt;/em&gt;. You can see Game of Life spinning away behind the Matrix Mode display.&lt;/p&gt;
&lt;p&gt;Type &lt;code&gt;h&lt;/code&gt; then press &lt;kbd&gt;Return&lt;/kbd&gt;. The Matrix Mode console prints &lt;code&gt;Serial Monitor&lt;/code&gt; and the version ID of the MEGA65 core that is currently running.&lt;/p&gt;
&lt;p&gt;To exit the Matrix Mode console, hold the &lt;kbd&gt;Mega&lt;/kbd&gt; key then press &lt;kbd&gt;Tab&lt;/kbd&gt; again.&lt;/p&gt;
&lt;div class=&#34;callout note&#34;&gt;
&lt;p&gt;A note on terminology: MEGA65 documentation refers to the entire debugger feature as &amp;ldquo;Matrix Mode&amp;rdquo; or &amp;ldquo;the monitor.&amp;rdquo; I&amp;rsquo;m calling it &amp;ldquo;the Matrix Mode debugger&amp;rdquo; or &amp;ldquo;the debugger&amp;rdquo; to distinguish it from the Matrix Mode console that you open with &lt;kbd&gt;Mega&lt;/kbd&gt;+&lt;kbd&gt;Tab&lt;/kbd&gt;, and from the MEGA65 monitor we&amp;rsquo;ve used previously. As we&amp;rsquo;re about to see, there are other ways to access the debugger besides the Matrix Mode console.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;using-a-serial-console-on-your-pc&#34;&gt;Using a serial console on your PC&lt;/h2&gt;
&lt;p&gt;The Matrix Mode console is an on-device command console that sends commands to and prints results from the debugger. This same command interface can be accessed from your PC over a JTAG or serial connection.&lt;/p&gt;
&lt;p&gt;The M65Connect app has a built-in console capable of sending commands to the debugger and displaying responses over such a connection. If you don&amp;rsquo;t already have this installed, download it from Filehost: there are versions for &lt;a href=&#34;https://files.mega65.org?id=d612d745-360e-4e86-8e15-14af525b6220&#34;&gt;Windows&lt;/a&gt;, &lt;a href=&#34;https://files.mega65.org?id=5919a8b8-c23c-4616-9a52-37e077076638&#34;&gt;Mac&lt;/a&gt;, and &lt;a href=&#34;https://files.mega65.org?id=c1dbc7fe-89ad-4f1d-9e72-ad3f55cf02a1&#34;&gt;Linux&lt;/a&gt;. See &lt;a href=&#34;https://dansanderson.com/mega65/welcome/using-jtag.html&#34;&gt;The MEGA65 Welcome Guide&lt;/a&gt; for more set-up instructions.&lt;/p&gt;
&lt;p&gt;The M65Connect window has a series of function buttons along the top, a Console window, and an area for typing commands. When connected to your MEGA65, the Console and command area give you complete access to the same debugger command interface as the Matrix Mode console.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect.png 1210w, https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect_hu_842d61dc4b395b16.png 600w, https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect_hu_6fc844f95c5065ad.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect.png&#34;
        alt=&#34;The M65Connect app, with console display and terminal input&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The M65Connect app
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;Don&amp;rsquo;t like the default fonts and colors of the M65Connect console? Go to the Settings menu, select Console, and pick new ones!&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;As another option, you can use any serial console app to connect to the debugger. For Windows, programs like &lt;a href=&#34;https://www.putty.org/&#34;&gt;PuTTY&lt;/a&gt; or &lt;a href=&#34;https://www.hilgraeve.com/&#34;&gt;HyperTerminal&lt;/a&gt; work well. For Mac, I like &lt;a href=&#34;https://www.decisivetactics.com/products/serial/&#34;&gt;Serial&lt;/a&gt;, a robust app with excellent features. Serial costs $39.99 US, but it earns its price for ease of use.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/mac-serial.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/mac-serial.png 773w, https://dansanderson.com/lab-notes/mega65-matrix-mode/mac-serial_hu_1dcf7e42fe8c589f.png 600w, https://dansanderson.com/lab-notes/mega65-matrix-mode/mac-serial_hu_dde9a88adfda0412.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/mac-serial.png&#34;
        alt=&#34;Serial, a serial console app for macOS&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
Serial, a serial terminal app for macOS
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If you like a terminal window and don&amp;rsquo;t want to pay money, &lt;a href=&#34;https://github.com/npat-efault/picocom&#34;&gt;picocom&lt;/a&gt; fits the bill nicely. It&amp;rsquo;s available for Windows via Cygwin, for Mac via &lt;a href=&#34;https://brew.sh/&#34;&gt;Homebrew&lt;/a&gt; (&lt;code&gt;brew install picocom&lt;/code&gt;), and for Linux via any package repository. Or you can just download and build it &lt;a href=&#34;https://github.com/npat-efault/picocom&#34;&gt;from Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The MEGA65 serial connection uses the unusual bitrate (&amp;ldquo;baud&amp;rdquo;) of &lt;code&gt;2000000&lt;/code&gt;. Other settings are common: 8 databits, 1 stop bit, no parity bit. Configure your serial console app accordingly. For &lt;code&gt;picocom&lt;/code&gt;, use this command line to start, substituting your serial port or device for the final argument:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;picocom --baud 2000000 --databits 8 --stopbits 1 --parity n /dev/cu.usbserial-9&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To exit &lt;code&gt;picocom&lt;/code&gt;, type &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;A&lt;/kbd&gt; then &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;X&lt;/kbd&gt;.&lt;/p&gt;
&lt;p&gt;Make sure Matrix Mode is closed on the MEGA65, then open M65Connect or a serial console app and connect to the appropriate device. Type the &lt;code&gt;h&lt;/code&gt; command and press &lt;kbd&gt;Return&lt;/kbd&gt;. (In M65Connect, use the text field below the console output to enter a command.) If everything is working, the core version message appears, just as it did in the Matrix Mode console.&lt;/p&gt;
&lt;div class=&#34;callout note&#34;&gt;
&lt;p&gt;The serial connection can only accept commands while the Matrix Mode console is closed. If the Matrix Mode console is open on the MEGA65, the serial console will not receive keystrokes, and serial features of M65Connect or the &lt;code&gt;m65&lt;/code&gt; command will not work. Be sure that Matrix Mode is closed before using these features.&lt;/p&gt;
&lt;p&gt;A serial console will &lt;em&gt;receive&lt;/em&gt; data from the MEGA65 with the Matrix Mode console open. When you enter commands in the Matrix Mode console, the output appears on the screen and is sent over the serial connection. This is handy for recording command output while using the Matrix Mode console.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;determining-the-serial-port-or-device&#34;&gt;Determining the serial port or device&lt;/h2&gt;
&lt;p&gt;Any serial console app needs to know the serial port or device for the JTAG adapter, similar to the M65Connect app and &lt;code&gt;m65&lt;/code&gt; command. This is a COM port on Windows, or a USB serial device path on Mac or Linux. Your computer may have more than one &amp;ldquo;serial port&amp;rdquo; or &amp;ldquo;USB serial device&amp;rdquo; recognized by the operating system—even if the only actual USB serial device you have connected is the JTAG adapter.&lt;/p&gt;
&lt;p&gt;M65Connect&amp;rsquo;s Connection settings window (Settings menu, Connection) lists the available serial ports/devices in a dropdown menu, and can attempt to auto-detect which one is the correct one to use. In my experience on a Mac, my JTAG adapter shows up as four different devices, only one of them is the correct one, and M65Connect&amp;rsquo;s auto-detect doesn&amp;rsquo;t work. I usually have to try each option until I find the right one. The answer is usually one that looks like &lt;code&gt;/dev/cu.usbserial-9&lt;/code&gt;. Moreover, it changes between sessions! The device path stays the same until I reboot my Mac or unplug the JTAG device.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect-ports.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect-ports.png 711w, https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect-ports_hu_7c3ad8b85d06254f.png 600w, https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect-ports_hu_f176485f34e1377d.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/m65connect-ports.png&#34;
        alt=&#34;The Connection settings window of the M65Connect app&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The Connection settings window of the M65Connect app
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I usually use M65Connect&amp;rsquo;s Connection interface to figure out the correct serial device at the beginning of the session, even if I intend to use another tool like the &lt;code&gt;m65&lt;/code&gt; command or a serial console app. A future version of &lt;code&gt;m65&lt;/code&gt; will have improved Mac-compatible port detect logic, and hopefully that will be added to M65Connect as well.&lt;/p&gt;
&lt;h2 id=&#34;which-console-is-best&#34;&gt;Which console is best?&lt;/h2&gt;
&lt;p&gt;The various methods of accessing the debugger have advantages and disadvantages.&lt;/p&gt;
&lt;p&gt;The Matrix Mode console is on the MEGA65 itself and can be used without a PC or serial connection. Other than the flashy opening animation, it&amp;rsquo;s not much to look at, and the 40-column display wraps lines in a way that&amp;rsquo;s sometimes difficult to read. It uses color when displaying memory, which is not available in a serial console. It covers the MEGA65 display translucently, which is a cute trick but can still get in the way depending on what you&amp;rsquo;re debugging. Debugging sometimes involves analyzing a bunch of data, and viewing all of the console output on the MEGA65 means I can&amp;rsquo;t copy that data to a file.&lt;/p&gt;
&lt;p&gt;The Matrix Mode console currently has &lt;a href=&#34;https://github.com/MEGA65/mega65-core/issues/595&#34;&gt;a bug&lt;/a&gt; in the NTSC video mode. Once you fill the screen with commands, the prompt will be one line &lt;em&gt;below&lt;/em&gt; the bottom of the screen and you&amp;rsquo;ll have to type commands blindly from then on. PAL mode does not have this issue, though my display doesn&amp;rsquo;t handle PAL mode very well. For me, this means Matrix Mode is only good for occasional use, and anything else needs a serial connection.&lt;/p&gt;
&lt;p&gt;M65Connect is convenient but also has issues. I like how a single app can beam newly built PRG files, take scerenshots, and interact with the debugger all in one interface. Only one PC app can access the serial port at a time, so it&amp;rsquo;s useful for my serial console to also be a multi-tool. The current release of M65Connect has &lt;a href=&#34;https://github.com/MEGA65/m65connect/issues/10&#34;&gt;an issue&lt;/a&gt; where it won&amp;rsquo;t let you send an empty command to the debugger, which is useful in some cases (though there are workarounds); this will be fixed in a future release.&lt;/p&gt;
&lt;p&gt;A serial console app provides a complete, copy-pasteable display of every character sent to and received from the debugger. It also hogs the serial connection, so you can&amp;rsquo;t use M65Connect or &lt;code&gt;m65&lt;/code&gt; to beam PRG files while it is open. Personally, I find it convenient enough to close the serial app every time I want to use another tool; it reopens instantly. If there&amp;rsquo;s session history in the serial app that I want to keep, I copy and paste it from the serial app to a text file.&lt;/p&gt;
&lt;h2 id=&#34;inspecting-memory&#34;&gt;Inspecting memory&lt;/h2&gt;
&lt;p&gt;The debugger can perform commands similar to the MEGA65 monitor. It isn&amp;rsquo;t as friendly to use as the MEGA65 monitor, and it has a somewhat different feature set.&lt;/p&gt;
&lt;p&gt;Our GoL program is still running, so let&amp;rsquo;s take a peek at the GoL line buffer. Enter this command in your console of choice:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;m 21ec&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reply looks something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;00021EC:00000000000000000000000000000000&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;m&lt;/code&gt; command displays values from memory, similar to the MEGA65 monitor. As you can see, it only shows 16 bytes, and doesn&amp;rsquo;t bother with a PETSCII interpretation (because you may not even be on a PETSCII-capable serial console). It also runs all the hexadecimal digits together, which is kind of difficult to read in a serial console. Matrix Mode adds a bit of color, which helps some.&lt;/p&gt;
&lt;p&gt;You can type &lt;code&gt;m&lt;/code&gt; without an address to view the next 16 bytes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;m&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also use &lt;code&gt;M&lt;/code&gt; (&lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;M&lt;/kbd&gt;) to request that it display 256 bytes at a time. (Unlike the MEGA65 monitor, debugger commands can be lowercase or uppercase.) Without an argument, it will display the next page of 256 bytes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;M 21ec

M&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you use a 16-bit address (four hexadecimal digits) with the debugger, it &lt;em&gt;always&lt;/em&gt; assumes you mean the address in the first 64 KB of RAM, as if preceded by &lt;code&gt;000&lt;/code&gt;. The debugger accepts 28-bit addresses (seven hexadecimal digits) to access the entire MEGA65 memory space, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;M 00021ec

M 8000000&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want to use a 16-bit address interpreted in the context of the CPU&amp;rsquo;s current memory map settings, use the special address prefix &lt;code&gt;777&lt;/code&gt; followed by the four hexadecimal digits:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;M 77721ec&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember that the GoL program is actively running while we do this! It is processing the entire screen 100 times a second, which means it is updating the line buffer 2,300 times a second. We peeked at the line buffer at some arbitrary point in time, which is not particularly useful, especially if we&amp;rsquo;re sampling 16 bytes at a time. The entire buffer could have been rewritten thousands of times between commands.&lt;/p&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;The Matrix Mode console has keyboard shortcuts to browse memory quickly. After issuing an &lt;code&gt;m&lt;/code&gt; or &lt;code&gt;M&lt;/code&gt; command, use the &lt;kbd&gt;F1&lt;/kbd&gt; and &lt;kbd&gt;F3&lt;/kbd&gt; (or &lt;kbd&gt;Cursor up&lt;/kbd&gt; and &lt;kbd&gt;Cursor down&lt;/kbd&gt;) to browse the next region of memory with increasing or decreasing addresses, respectively. These keyboard shortcuts are only available through Matrix Mode, though the results are also sent over the serial connection.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;inspecting-memory-as-machine-code&#34;&gt;Inspecting memory as machine code&lt;/h2&gt;
&lt;p&gt;Similar to the MEGA65 monitor, the debugger can do rudimentary disassembly, displaying memory interpreted as assembly language instructions. Small &lt;code&gt;d&lt;/code&gt; followed by an address disassembles one instruction. Capitol &lt;code&gt;D&lt;/code&gt; followed by an address disassembles 16 instructions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;d 20d4

D 20d4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As with viewing memory, you can enter &lt;code&gt;d&lt;/code&gt; or &lt;code&gt;D&lt;/code&gt; without an address to continue disassembly from where it left off.&lt;/p&gt;
&lt;h2 id=&#34;inspecting-registers&#34;&gt;Inspecting registers&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s try peeking at the registers. Enter the &lt;code&gt;r&lt;/code&gt; command—or just press &lt;kbd&gt;Return&lt;/kbd&gt;/&lt;kbd&gt;Enter&lt;/kbd&gt; at the prompt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;r&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I get this response:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.PC  A  X  Y  Z  B  SP   MAPH MAPL LAST-OP In     P  P-FLAGS   RGP uS IO ws h RECA8LHC
2129 20 01 50 00 16 01EF 8300 E000 B1FB    00     20 ..E..... ...P 4A -  00 - ..c..lhc
,07772129  C9 51     CMP   #$51&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can recognize the program counter PC, the registers A X Y Z and B, and the stack pointer SP. Our friends the status flags are labeled here as &lt;code&gt;P&lt;/code&gt; (the flags as an 8-bit number) and &lt;code&gt;P-FLAGS&lt;/code&gt; (a visual rendering); if set, their letter appears (&lt;code&gt;NVEBDIZC&lt;/code&gt;). That third line is the disassembly of the instruction at the program counter.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;MAPH&lt;/code&gt; and &lt;code&gt;MAPL&lt;/code&gt; are the Hypervisor MAP register, a 32-bit value. This powers the memory mapping mechanism of the 45GS02 that allows up to 1 megabyte of address space to be accessible with a 16-bit address bus. I hope to cover MEGA65 memory management in its own article, but suffice it to say that this is a powerful feature, and once you get into it it&amp;rsquo;s crazy important to be able to peek at this value.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RECA8LHC&lt;/code&gt; at the end are ROM banking flags, as controlled by the bits at &lt;code&gt;$D030&lt;/code&gt;. This becomes useful to see when you start diving into memory banking. See &amp;ldquo;CPU Memory Banking&amp;rdquo; in appendix F of &lt;a href=&#34;https://files.mega65.org/manuals-upload/&#34;&gt;the book&lt;/a&gt; and related references for more information. I don&amp;rsquo;t actually know if all eight bits of &lt;code&gt;$D030&lt;/code&gt; appear here, but this is how they are defined according to the manual:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;R&lt;/code&gt;: ROM page E (ROME): &lt;code&gt;$3E000-$3FFFF&lt;/code&gt; → &lt;code&gt;$E000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;E&lt;/code&gt;: Character set ROM (CROM9): &lt;code&gt;$29000-$29FFF&lt;/code&gt; → &lt;code&gt;$D000&lt;/code&gt; (&amp;ldquo;Select between C64 and C65 charset&amp;rdquo;?)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C&lt;/code&gt;: ROM page C (ROMC): &lt;code&gt;$2C000-$2CFFF&lt;/code&gt; → &lt;code&gt;$C000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt;: ROM page A (ROMA): &lt;code&gt;$3A000-$3BFFF&lt;/code&gt; → &lt;code&gt;$A000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;8&lt;/code&gt;: ROM page 8 (ROM8): &lt;code&gt;$38000-$39FFF&lt;/code&gt; → &lt;code&gt;$8000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;L&lt;/code&gt;: Use palette ROM (0) or RAM (1) for colors 0-15 (PAL)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;H&lt;/code&gt;: Enable external video sync (genlock), not really a thing and unrelated to ROM banking (EXTSYNC)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C&lt;/code&gt;: Color RAM (CRAM2K): map 2nd KB of color RAM to &lt;code&gt;$DC00&lt;/code&gt; (full range &lt;code&gt;$D800-$DFFF&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The rest are only interesting if you&amp;rsquo;re hacking on the MEGA65 Hypervisor code or the FPGA. As best as I can figure out from &lt;a href=&#34;https://github.com/MEGA65/mega65-core/blob/development/src/monitor/monitor.a65&#34;&gt;the assembly code for the Matrix Mode monitor&lt;/a&gt;, &lt;a href=&#34;https://github.com/MEGA65/mega65-core/blob/master/src/vhdl/gs4510.vhdl&#34;&gt;the VHDL for the 45GS02 processor&lt;/a&gt;, and some light experimentation, the remaining values are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;LAST-OP&lt;/code&gt; : The hexadecimal machine code of the last instruction executed. Note that this is the machine code itself as bytes, not the address of the instruction.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;In&lt;/code&gt; : &amp;ldquo;Instruction.&amp;rdquo; I&amp;rsquo;m only seeing this show up as &lt;code&gt;00&lt;/code&gt;, so I don&amp;rsquo;t know what it is.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RGP&lt;/code&gt; : Mysterious flags! Actually &lt;code&gt;MRGP&lt;/code&gt;. I don&amp;rsquo;t know why the M isn&amp;rsquo;t in the legend (but there&amp;rsquo;s space for it).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uS&lt;/code&gt; : The internal processor state. Mostly useful for FPGA troubleshooting. See &lt;a href=&#34;https://github.com/MEGA65/mega65-core/blob/master/src/vhdl/gs4510.vhdl#L858&#34;&gt;&lt;code&gt;processor_state&lt;/code&gt; in gs4510.vhdl&lt;/a&gt; if you&amp;rsquo;re curious.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IO&lt;/code&gt; : &amp;ldquo;I/O fast mode,&amp;rdquo; &lt;code&gt;W&lt;/code&gt; for write, &lt;code&gt;R&lt;/code&gt; for read, &lt;code&gt;-&lt;/code&gt; for none.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ws&lt;/code&gt; : &amp;ldquo;Wait states,&amp;rdquo; a byte value, only useful for FPGA troubleshooting.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;h&lt;/code&gt; : Hypervisor mode: &lt;code&gt;H&lt;/code&gt; if the CPU is running in Hypervisor mode, or &lt;code&gt;-&lt;/code&gt; if running in user mode. You can see this set to &lt;code&gt;H&lt;/code&gt; if you use a serial console while in the Configuration menu, for example.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;m pestering the MEGA65 team to help provide better explanations. If I learn more I&amp;rsquo;ll update this article. But that&amp;rsquo;s more than enough for everyday assembly language programming.&lt;/p&gt;
&lt;h2 id=&#34;executing-code-one-step-at-a-time&#34;&gt;Executing code one step at a time&lt;/h2&gt;
&lt;p&gt;Computers are just too fast for peeking at the system state while the system is running. We need to slow things down if we&amp;rsquo;re going to learn anything useful.&lt;/p&gt;
&lt;p&gt;With GoL running, enter these commands in the debugger:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;t1
i1
r&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you entered &lt;code&gt;t1&lt;/code&gt;, the GoL program froze in its tracks. If you&amp;rsquo;re using Matrix Mode, you should be able to see this through the translucent display. If you&amp;rsquo;re using a serial console, the frozen display is in full view.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;t1&lt;/code&gt; command initiates &lt;em&gt;trace mode&lt;/em&gt;. In this mode, the MEGA65 main CPU does not execute instructions until we tell it to through the debugger. We can examine every instruction as it gets executed, including how it changes memory and registers.&lt;/p&gt;
&lt;p&gt;Press &lt;kbd&gt;Enter&lt;/kbd&gt; (serial console) or &lt;kbd&gt;Return&lt;/kbd&gt; (Matrix Mode) to advance by one instruction. (In M65Connect, you have to type &lt;code&gt;t&lt;/code&gt; as a command (no arguments) to advance.) The instruction is executed, and registers are re-displayed. Notice the change in the program counter (&lt;code&gt;PC&lt;/code&gt;) and any anticipated effects in the other registers. To execute a bunch of instructions to fast forward to an interesting part, you can hold the &lt;kbd&gt;Enter&lt;/kbd&gt; key down while keeping an eye on the program counter.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;i1&lt;/code&gt; command disables interrupts. You can see this in the debugger&amp;rsquo;s register output, under &lt;code&gt;P-FLAGS&lt;/code&gt;: previously, the &lt;code&gt;I&lt;/code&gt; flag was set (interrupts were enabled), now it is unset (interrupts are disabled). It is useful to disable interrupts before entering trace mode so you&amp;rsquo;re not spending your time stepping through system interrupt handlers when you want to be stepping through your (non-interrupt) code.&lt;/p&gt;
&lt;p&gt;Re-enable interrupts, then disable trace mode to return to full speed execution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;i0
t0&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&#34;callout note&#34;&gt;
&lt;p&gt;When you&amp;rsquo;re in the Matrix Mode console, you won&amp;rsquo;t be able to exit the console while in trace mode. Disable trace mode, then exit the console with &lt;kbd&gt;Mega&lt;/kbd&gt;+&lt;kbd&gt;Tab&lt;/kbd&gt;. If you want to see the full screen while in trace mode, use a serial console to access the debugger.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;There&amp;rsquo;s a third possible state for trace mode that you can activate with the command &lt;code&gt;tc&lt;/code&gt;. This causes the CPU to run continuously while also dumping register output with every instruction. This is so much data that it&amp;rsquo;s not useful from a console. It is better used with testing tools that connect via serial, issue the command, and harvest the data for analysis or real-time display.&lt;/p&gt;
&lt;p&gt;Impressively, it seems to do this without slowing down the machine. GoL runs at 100 fps with &lt;code&gt;tc&lt;/code&gt; mode enabled.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;stopping-somewhere-specific&#34;&gt;Stopping somewhere specific&lt;/h2&gt;
&lt;p&gt;With our GoL program, chances are pretty good that when you typed &lt;code&gt;t1&lt;/code&gt; the CPU stopped somewhere outside of the GoL code (&lt;code&gt;$20d4-$2290&lt;/code&gt;), maybe at an address that began with &lt;code&gt;E&lt;/code&gt; or &lt;code&gt;F&lt;/code&gt;. This is because our GoL program uses a main loop written in BASIC. The CPU spends a lot of time in the BASIC interpreter code, and comparatively less time in our actual machine code algorithm.&lt;/p&gt;
&lt;div class=&#34;callout exercise&#34;&gt;
&lt;p&gt;You could make a simple change to the GoL program so that execution stays in our machine language code once it is running, at the expense of disabling our timing code. How would you do it? (Hint: replace a single instruction.)&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Instead of stopping the CPU wherever it is when we type &lt;code&gt;t1&lt;/code&gt;, it&amp;rsquo;d be much nicer to stop when the program counter has reached a specific address. For example, with our BASIC outer loop, we might want to stop specifically at the start of our machine code, &lt;code&gt;$20d4&lt;/code&gt;, so we can step through it without getting lost in the BASIC ROM.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;b&lt;/code&gt; command sets a &lt;em&gt;breakpoint&lt;/em&gt; at an address. The debugger watches the CPU&amp;rsquo;s program counter, and when it reaches the given address, it enters trace mode.&lt;/p&gt;
&lt;p&gt;With the GoL program running, tell the debugger to enter trace mode at the first instruction of our machine code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;b 20d4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The program should freeze immediately, because it starts this routine 100 times a second. In your console, the debugger prints the registers at the stopping point.&lt;/p&gt;
&lt;p&gt;Notice that the program counter is now at &lt;code&gt;$20d6&lt;/code&gt;. The debugger allowed the instruction at &lt;code&gt;$20d4&lt;/code&gt; to execute, then took control and entered trace mode. The next instruction (&lt;code&gt;STA $00&lt;/code&gt;) is displayed, along with all of the other registers.&lt;/p&gt;
&lt;p&gt;You are now free to use all of the monitor commands to inspect memory and registers, and make potential modifications.&lt;/p&gt;
&lt;p&gt;Try resuming the program with &lt;code&gt;t0&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;t0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The GoL pattern iterates by one step, then the program freezes again because the breakpoint is still set at the top of the routine. To clear the breakpoint, enter the &lt;code&gt;b&lt;/code&gt; command without arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;b&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can exit trace mode with &lt;code&gt;t0&lt;/code&gt;, and execution will proceed uninterrupted.&lt;/p&gt;
&lt;p&gt;The debugger only supports one breakpoint at a time. The address must be the starting address of an instruction; try to stop on someone&amp;rsquo;s operand and it&amp;rsquo;ll blow right past it. You can use your symbol list to find the starting addresses of your labeled subroutines. You can also use the debugger&amp;rsquo;s disassembler to find the address of a specific unlabeled instruction.&lt;/p&gt;
&lt;p&gt;The debugger also knows how to pause the program when a specific memory address has changed. The &lt;code&gt;w&lt;/code&gt; command sets up a &lt;em&gt;watch&lt;/em&gt; on an address. For example, we can set up a watch on &lt;code&gt;row_ct&lt;/code&gt; so it pauses after each row.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;w 228d&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A watch enters trace mode every time the value at the address is updated, even if it is updated with the same value it already has. It triggers no matter what code made the update—and you can see who made the update by examining the program counter.&lt;/p&gt;
&lt;p&gt;When I set a watch on &lt;code&gt;row_ct&lt;/code&gt; just now, it stopped with the PC at &lt;code&gt;$2170&lt;/code&gt;, which I can see from my symbol list is a few instructions after &lt;code&gt;last_col&lt;/code&gt;. I can check which row it stopped on by examining the value at &lt;code&gt;row_ct&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;m 228d&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As with the breakpoint, there can be only one address watch. You can clear it by giving the &lt;code&gt;w&lt;/code&gt; command with no arguments. (Don&amp;rsquo;t forget to exit trace mode with &lt;code&gt;t0&lt;/code&gt; when you&amp;rsquo;re ready.)&lt;/p&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;Take a moment to appreciate that not only can we now pause our Game of Life program without rewriting it to contain &lt;code&gt;brk&lt;/code&gt; statements, we can execute monitor commands without overwritng the GoL game board on the screen!&lt;/p&gt;
&lt;p&gt;This can be especially important when developing games. You may not even be able to display the MEGA65 monitor on the game screen with redefined character sets or non-text video modes. Even if you could, the things you&amp;rsquo;re troubleshooting are probably on-screen game elements, and the MEGA65 monitor would spoil the investigation like a puppy at a crime scene. With the debugger, the game can run freely, you can pause it without corrupting the display or any memory, and you can advance and continue at any time.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;jumping-to-an-address&#34;&gt;Jumping to an address&lt;/h2&gt;
&lt;p&gt;You can change the program counter to cause the CPU to start executing at a different address, with the &lt;code&gt;g&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;g 2185&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the CPU running, this is functionally equivalent to a &lt;code&gt;jmp&lt;/code&gt; instruction. If the CPU is in trace mode, this sets the program counter so execution will continue at that address either at the next step or when you leave trace mode.&lt;/p&gt;
&lt;p&gt;There is no equivalent to the MEGA65 monitor&amp;rsquo;s &lt;code&gt;J&lt;/code&gt; command. It&amp;rsquo;s not so easy to test subroutines in the debugger as it is from the MEGA65 monitor.&lt;/p&gt;
&lt;h2 id=&#34;setting-memory-values&#34;&gt;Setting memory values&lt;/h2&gt;
&lt;p&gt;To set values in memory, use the &lt;code&gt;s&lt;/code&gt; command. It takes a starting address and one or more byte values as hexadecimal values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;s c000 00 01 02&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;s&lt;/code&gt; command takes a 28-bit absolute address and assumes a &lt;code&gt;000&lt;/code&gt; prefix if you only give four digits. To set values relative to the CPU memory mapping settings, use &lt;code&gt;S&lt;/code&gt; (&lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;S&lt;/kbd&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S c000 AB CD EF&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To fill a region of memory with a value, use the &lt;code&gt;f&lt;/code&gt; command. The ending address must be one past the actual last address to fill.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f 21ec 228d 00&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Matrix Mode debugger does &lt;em&gt;not&lt;/em&gt; offer an assembler. If you need to change machine code in memory, you&amp;rsquo;ll have to figure out the byte values yourself, though that&amp;rsquo;s probably never worth the effort. I&amp;rsquo;d much rather edit the original assembly code, cross-assemble, and re-upload, at least to add a &lt;code&gt;brk&lt;/code&gt; statement (&lt;code&gt;00&lt;/code&gt;) and use the MEGA65 monitor instead.&lt;/p&gt;
&lt;p&gt;There is no way to set the register values directly with a debugger command.&lt;/p&gt;
&lt;div class=&#34;callout note&#34;&gt;
&lt;p&gt;Unlike the MEGA65 monitor, the debugger only accepts hexadecimal values for addresses and bytes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;The debugger has a cool feature that allows a tool to load binary data directly into memory addresses. The tool can issue the &lt;code&gt;l&lt;/code&gt; (&amp;ldquo;load&amp;rdquo;) command with a start and end+1 address, then immediately send the appropriate number of bytes as binary over the serial connection.&lt;/p&gt;
&lt;p&gt;There is no use for this command at a console, but it&amp;rsquo;s nice to know about if someday you need to write such a tool. This is how tools like the &lt;code&gt;m65&lt;/code&gt; command send PRG files.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;writing-custom-tools-that-use-the-serial-connection&#34;&gt;Writing custom tools that use the serial connection&lt;/h2&gt;
&lt;p&gt;I won&amp;rsquo;t spend a lot of time on this, but I wanted to briefly demonstrate the utility of the serial interface for writing custom tools. Here is a Python program using &lt;a href=&#34;https://pyserial.readthedocs.io/en/latest/pyserial.html&#34;&gt;PySerial&lt;/a&gt; that executes the &lt;code&gt;h&lt;/code&gt; command and prints the response.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import serial

DEVICE = &amp;#39;/dev/cu.usbserial-251633006E0EA&amp;#39;

with serial.Serial(DEVICE, 2000000, timeout=1) as ser:
    ser.write(b&amp;#39;h\n&amp;#39;)
    while True:
        line = ser.readline()
        if not line:
            break
        line = line.strip()
        print(str(line, encoding=&amp;#39;utf-8&amp;#39;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PySerial includes a function that attempts to list available serial ports and devices. Here is Python code to get device paths for all detected devices, similar to the list that M65Connect has in its Connection settings:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import serial.tools.list_ports

devices = [p.device for p in serial.tools.list_ports.comports()]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You could use this to scan all the ports and issue &lt;code&gt;h&lt;/code&gt; commands until one responds, so you don&amp;rsquo;t have to hard-code or pass in the serial device to the tool. Be sure to set &lt;code&gt;timeout&lt;/code&gt; so a failed connection knows to move on.&lt;/p&gt;
&lt;p&gt;Wanna see something cool? Download this Python script:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;goldisplay.py&#34;&gt;goldisplay.py.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Load Game of Life onto your MEGA65, run this Python script in a terminal window on your PC, then run GoL, draw a pattern, then press &lt;kbd&gt;Return&lt;/kbd&gt; to start it. This script renders the Game of Life game board in the terminal window! Try to figure out how it works.&lt;/p&gt;
&lt;figure&gt;
    &lt;a href=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/goldisplay.png&#34;&gt;
    &lt;img 
        srcset=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/goldisplay.png 263w, https://dansanderson.com/lab-notes/mega65-matrix-mode/goldisplay_hu_a6f99ce330fa8b43.png 600w, https://dansanderson.com/lab-notes/mega65-matrix-mode/goldisplay_hu_e06ef2633347235c.png 400w&#34;
        sizes=&#34;(max-width: 400px) 400px,
               (max-width: 600px) 600px,
               800px&#34;
        src=&#34;https://dansanderson.com/lab-notes/mega65-matrix-mode/goldisplay.png&#34;
        alt=&#34;The MEGA65 Game of Life game board in a terminal window&#34;&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;
The MEGA65 Game of Life game board — in a terminal window??
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;div class=&#34;callout tip&#34;&gt;
&lt;p&gt;PySerial comes with a little serial console program, similar to picocom. For use with the MEGA65 debugger, run it from a terminal window like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 -m serial.tools.miniterm /dev/cu.usbserial-251633006E0EA 2000000&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;Today we looked at the MEGA65 Matrix Mode debugger, a powerful facility for understanding and manipulating the MEGA65 while it is running &lt;em&gt;without&lt;/em&gt; having to insert debugging code into our program. The Matrix Mode console makes this command interface accessible directly on the MEGA65. The same command interface is available on your PC over a JTAG or serial connection, which you can use from the M65Connect app or any serial console program.&lt;/p&gt;
&lt;p&gt;&amp;hellip; What? You want more? More debugging power? More expressiveness in your MEGA65 development workflow? OK, sure, the Matrix Mode debugger command interface may seem a little spare compared to the MEGA65 monitor. Perhaps a more compelling debugging app could run on the PC, using the Matrix Mode debugger command interface behind the scenes.&lt;/p&gt;
&lt;p&gt;Sure enough, there are at least two dead sexy MEGA65 debugging applications for your PC. They connect to your MEGA65 over serial, and can even connect to the Xemu emulator if that&amp;rsquo;s where you&amp;rsquo;re doing your development. We&amp;rsquo;ll explore these tools next time.&lt;/p&gt;</content:encoded>
      
    </item>
    
  </channel>
</rss>
