<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TeacherNerd.Com</title>
	<atom:link href="https://teachernerd.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://teachernerd.com/</link>
	<description></description>
	<lastBuildDate>Sat, 19 Jul 2025 02:11:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.2</generator>
	<item>
		<title>Cloudy with a Chance of Static</title>
		<link>https://teachernerd.com/2025/07/18/cloudy-with-a-chance-of-static/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Fri, 18 Jul 2025 05:37:11 +0000</pubDate>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[containerization]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[serverless computing]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?p=1962</guid>

					<description><![CDATA[For my latest post, I’m going to talk a little bit about, well, this blog! Specifically, I’d like to share my recent project to convert it from a dynamic, WordPress-based application hosted on a traditional web server to a collection of (mostly) static pages living in…[insert magical hand wave here]…The Cloud.]]></description>
										<content:encoded><![CDATA[
<p>For my latest post, I’m going to talk a little bit about, well, <em>this blog</em>! Specifically<em>, </em>I’d like to share my recent project to convert it from a dynamic, WordPress-based application hosted on a traditional web server to a collection of (mostly) static pages living in…[insert magical hand wave here]…<em>The Cloud.</em></p>



<p>When I first launched &#8220;teachernerd.com&#8221; in the summer of 2019, I did what I was used to and turned to a managed hosting provider. The thing about managed hosting, however, is that “managed” is just another way of saying “locked down,” which is not the funnest setup for tinkerers like me. (Yes, I said “funnest.”) Also, all that “management” you’re supposedly paying for comes at a cost—a cost that (surprise!) tends to increase over time. At some point I got to thinking, “Why not just do this myself?” So I used a much cheaper service from that same provider to spin up a virtual machine and then proceeded to set up a classic <a href="https://aws.amazon.com/what-is/lamp-stack/" target="_blank" rel="noreferrer noopener">LAMP stack</a>.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img fetchpriority="high" decoding="async" width="640" height="480" src="https://teachernerd.com/wp-content/uploads/2025/07/lamp.jpeg" alt="An articulating desk lamp, centered in the frame against a white wall." class="wp-image-1977" style="width:235px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/07/lamp.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/07/lamp-300x225.jpeg 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">A lamp.</figcaption></figure></div>


<p>Of course, given that I am not a cybersecurity expert, I eventually started to worry about keeping this self-managed system safe. So…I configured my virtual machine’s network gateway to close off all inbound access from the public internet.&nbsp;</p>



<p>Blocking all ingress to your server like this is kind of a problem, though, if you’re trying to host a <em>public</em> website. Enter Cloudflare Zero Trust, an enterprise-oriented offering that also includes a very generous free tier. By setting up a secure tunnel, I was able to use Cloudflare’s global network of data centers as my front door (rather than a public IP address), which meant I could rely on <em>their</em> expertise and infrastructure to wall off all the private parts of my system.</p>



<p>This all <em>kind of </em>worked for a while, except that it also made it much more complicated for <em>me </em>to access everything!</p>



<p>I finally decided it was time to get out of the server self-management business.</p>



<h2 class="wp-block-heading">The Problem</h2>



<p>What makes WordPress (and content management systems like it) so special is that it generates pages on demand. For the most part, all of your text is stored in a database while your media lives in an uploads directory on the server. To display a particular page, the server executes a script that makes a bunch of calculations in order to insert the correct content into the correct locations within a series of templates. The actual pages seen in the browser don’t technically exist until they are requested. Thus, the content is considered <strong><em>dynamic</em></strong>.</p>



<p>This is a far cry from the World Wide Web of the early 90s, when what you saw in your browser was largely <strong><em>static</em></strong>. Although server-side scripting was still a thing even back then, <em>in general</em>, content was stored in its “final” form on the server and simply fed over the internet (that mythical series of tubes) to the end user.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="640" height="480" src="https://teachernerd.com/wp-content/uploads/2025/07/wmata.jpeg" alt="A photograph taken from the platform of a Metro station in Washington, D.C. looking down the track. The iconic waffle-like arched design of the Metro system is clearly visible, with the straight lines converging toward a vanishing point." class="wp-image-1980" style="width:304px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/07/wmata.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/07/wmata-300x225.jpeg 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">A tube.</figcaption></figure></div>


<p>We’ve come a long way since then in terms of interactivity (JavaScript!), security (encryption!) and so forth, but one of the biggest liabilities remains all the moving parts that go into serving up dynamic content. Whether powered by PHP, Node.js, or some other language/platform, websites are now essentially <em>software</em>, which of course leaves plenty of room for bugs—to say nothing of all the software running behind the scenes on each individual server.</p>



<p>In many ways, this is just progress: sophistication breeds complication. <strong>Still, wouldn’t it be nice if there were a way to get the best of both worlds?</strong> What if you could use a fancy system like WordPress to simplify content creation (rather than having to painstakingly craft every single page by hand) but still somehow serve it all from static, inherently more mundane files? Heck, what if you could eliminate all the overhead of running a web server altogether?</p>



<p>All of these things, it turns out, are possible thanks to the oxymoronically named concept of <strong>static site generation</strong>.</p>



<p>A static site generator is basically a tool that does all the stuff a CMS does (i.e. combine content, templates, and logic) but instead of delivering the results to a browser on demand, it saves every possible page in advance as <em>static</em> HTML files, which you can then upload to a traditional web server or, even better, one of numerous “serverless” providers that now make it possible to “abstract away” the entire web hosting concept.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="640" height="425" src="https://teachernerd.com/wp-content/uploads/2025/07/treebike.jpeg" alt="An image of a flowering crepe myrtle tree with a young woman reading a book sitting on the ground beside it. A bicycle with a red basket is positioned next to the woman. The photograph has been passed through a filter that substantially distorts the image and stylizes the edges." class="wp-image-1983" style="width:387px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/07/treebike.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/07/treebike-300x199.jpeg 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">So abstract.</figcaption></figure></div>


<p>There’s a catch, however. (There’s <em>always </em>a catch!) Some website components simply cannot be done statically, the most obvious examples being <em>forms</em>. With forms, you have to be able to <em>collect</em> the information and then <em>do </em>something with it—the exact opposite of remaining static!</p>



<p>I knew the solution to my website maintenance challenge was to migrate to a static blog, but to do so without <em>any</em> loss in functionality, I would eventually have to find a way to deal with not one but <em>two</em> contact forms as well as numerous places where a search form appears.</p>



<h2 class="wp-block-heading">The Objective</h2>



<p>For me to feel satisfied, a statically generated blog would have to meet the following criteria:</p>



<ol class="wp-block-list">
<li>Be able to replicate the exact look and feel of my original WordPress blog.</li>



<li>Be able to do this repeatedly (i.e. any time I might choose to update the site).</li>



<li>Not require me to learn a new platform (at least not right now).</li>



<li>Have somewhere to live on the public internet.</li>



<li>Have some way of handling contact forms.</li>



<li>Continue to offer a search engine.</li>



<li>Be as inexpensive as possible. (Bonus points, as always, if it could be done for free!)</li>
</ol>



<h2 class="wp-block-heading">The Solution</h2>



<h3 class="wp-block-heading">Gimme, Gimme Some HTML</h3>



<p>Let’s start with those first three goals: easy, repeatable replication without using a new platform. For this, I turned to a WordPress plugin called <a href="https://wordpress.org/plugins/simply-static/" target="_blank" rel="noreferrer noopener">Simply Static</a>. With just a modicum of configuration required, this plugin was able to save a perfect copy of the output for nearly every single page of my site to a specified directory on my web server.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="547" src="https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.30.27-AM-1024x547.png" alt="Screen shot of the Activity Log from the Simply Static plugin, showing that 2206 of 2206 pages/files have ben processed." class="wp-image-1985" style="width:539px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.30.27-AM-1024x547.png 1024w, https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.30.27-AM-300x160.png 300w, https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.30.27-AM-768x410.png 768w, https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.30.27-AM-1536x820.png 1536w, https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.30.27-AM-2048x1093.png 2048w, https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.30.27-AM-1600x854.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Simply Static. (Side note: I&#8217;m very curious if the random, macOS-inspired decorations on the Activity Log are replaced with Windows-style decorations if you view this page on a PC. I guess I could check the plugin&#8217;s source code&#8230;)</figcaption></figure></div>


<p>Now, hold up a minute! Isn’t the goal here to <em>avoid</em> running a server? Well, yes, but I still want to use WordPress to generate my site. And that means I still need a server <em>somewhere</em>. My goal was to ditch my <em>public</em> web server; I don’t mind a private server on my own local machine.</p>



<h3 class="wp-block-heading">A Trip to the Docks</h3>



<p>Look, despite all my complaining, web servers are not rocket science, but they <em>can</em> be annoying to set up. Actually, there are lots of systems you might want to put on a computer that can get tricky real fast, especially if you want them all to play nice together. This is precisely why <strong>containerization</strong><em> </em>was invented!</p>



<p>It’s way beyond the scope of this post to truly explain containerization, and I don’t think I’d do a very good job of it anyway. But put very simply, containers work a little bit like virtual machines in that they bundle together all of the software and configurations you need to run a particular <em>thing</em> (a web server, a database server, a home automation system…) while relying on resources provided by the containerization platform and host machine to actually execute it.</p>



<p>One of the biggest names in containerization is Docker, and one of the things that Docker is very good at is <em>composition—</em>that is to say, allowing you to build an entire <em>system</em> out of multiple pre-compiled components.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1024" height="624" src="https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.33.16-AM-2.png" alt="Screen shot from the Docker Desktop application running on a Mac. Several activated containers are visible in the interface." class="wp-image-1990" style="width:525px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.33.16-AM-2.png 1024w, https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.33.16-AM-2-300x183.png 300w, https://teachernerd.com/wp-content/uploads/2025/07/Screenshot-2025-07-18-at-12.33.16-AM-2-768x468.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Docker Desktop. In this screenshot, you can see the containers for the present website plus a couple others that I work on.</figcaption></figure></div>


<p>This is starting to veer into the territory of something known as <strong>infrastructure as code</strong><em>, </em>but you can basically create a file that describes each of the pieces you need and how they should work together. Then, with a single terminal command, you can tell Docker to download/assemble all those bits and launch the system.</p>



<p>You can see my own Docker composition <a href="https://gist.github.com/teachernerd/d21b14b90ed40d1648fc6bc2d9463463" data-type="link" data-id="https://gist.github.com/teachernerd/d21b14b90ed40d1648fc6bc2d9463463" target="_blank" rel="noreferrer noopener">here</a>. In a nutshell, what this file does is tell Docker to create a complete WordPress setup out of four pre-built application “images”: one for the WordPress core; one for the separately packaged WordPress command line tool; one for a MySQL server (for databases); and one for phpMyAdmin, a GUI for working with those databases. The file also provisions some virtual drives and makes certain folders on my computer available to the container so that I can use my own theme, plugin, and media files.</p>



<p>Docker allows me to start up my local WordPress server whenever I need to work on the site and instantly tear it down when I’m done, freeing up memory and CPU cycles for whatever else I might want to do on the computer. Once I’ve finished editing the content, I can use the Simply Static plugin to re-render my site so that I can upload the static files to my hosting provider.</p>



<h3 class="wp-block-heading">Stuck in the Clouds</h3>



<p>Speaking of hosting providers, let’s talk about Criterion #4: giving this site a home. There are lots of options out there, but I eventually settled on yet another solution offered by Cloudflare, largely because their platform also provided a way to deal with Criterion #5 (the contact form).</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="640" height="427" src="https://teachernerd.com/wp-content/uploads/2025/07/0W5A1914.jpeg" alt="Dark clouds silhouetted against an amber-colored sky." class="wp-image-1993" style="width:400px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/07/0W5A1914.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/07/0W5A1914-300x200.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">Clouds, with flare.</figcaption></figure></div>


<p>Cloudflare, you see, offers a tool called Workers. A Worker is really just a script, but rather than storing and running it on a specific machine, you just sort of, well, upload it to Cloudflare. When called upon, Cloudflare launches what is essentially a virtual machine, runs the script, and then tears it all down. It’s kind of like Docker in a way, except that everything is replicated and distributed across an array of data centers (the so-called cloud of Cloud Computing), which theoretically means that Cloudflare can select the best location for the job for any given request based on distance to the user and available resources.</p>



<p>That’s a cool sales pitch and all, but it’s really not what was important to me. What I liked about Workers was that in addition to executing scripts, the system can also (wait for it!) <em>host static websites</em>. In other words, I could use Cloudflare, which I had already been relying on for caching and security, to handle the whole shebang. And best of all, Cloudflare doesn’t charge to host (or serve) assets like HTML or reasonably sized media (Criterion #7). You can even run your Worker scripts for free—so long as your traffic is relatively light (which should not be a problem for my contact forms).</p>



<h3 class="wp-block-heading">Following the Script</h3>



<p>With all this figured out, I set about writing a script that I could run inside a Worker to process my contact form and turn each submission into an email. </p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="640" height="571" src="https://teachernerd.com/wp-content/uploads/2025/07/IMG_7124.jpeg" alt="" class="wp-image-1995" style="width:393px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/07/IMG_7124.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/07/IMG_7124-300x268.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">This is not how you create an email. But it <em>is</em> electronic!</figcaption></figure></div>


<p>Workers supports <a href="https://developers.cloudflare.com/workers/languages/" data-type="link" data-id="https://developers.cloudflare.com/workers/languages/" target="_blank" rel="noreferrer noopener">a few different languages</a>, but plain old JavaScript felt most approachable for this. As for the script itself, it mostly involved validating inputs and then inserting the data into a message template. I used a library called <a href="https://github.com/muratgozel/MIMEText" data-type="link" data-id="https://github.com/muratgozel/MIMEText" target="_blank" rel="noreferrer noopener">MIMEText</a> to help with that latter part, mostly because it was used in <a href="https://developers.cloudflare.com/email-routing/email-workers/send-email-workers/" data-type="link" data-id="https://developers.cloudflare.com/email-routing/email-workers/send-email-workers/" target="_blank" rel="noreferrer noopener">one of Cloudflare&#8217;s own tutorials</a>. For delivery of the messages, I was able to take advantage of Cloudflare’s <a href="https://www.cloudflare.com/developer-platform/products/email-routing/" data-type="link" data-id="https://www.cloudflare.com/developer-platform/products/email-routing/" target="_blank" rel="noreferrer noopener">email routing service</a>. (It&#8217;s not <em>exactly</em> designed for this use case, but it <em>is</em> evidently possible.) Meanwhile, Cloudflare&#8217;s CAPTCHA tool, known as <a href="https://www.cloudflare.com/application-services/products/turnstile/" data-type="link" data-id="https://www.cloudflare.com/application-services/products/turnstile/" target="_blank" rel="noreferrer noopener">Turnstile</a>, gave me a way to protect the form from bots. (Have I put too many of my eggs in one basket at this point? Only time will tell!)</p>



<p>The final piece of the puzzle was the search engine, which I almost thought would thwart my plan—or force me to rely on Google (yuck!)—until I came across <a href="https://stackoverflow.com/questions/59004164/how-to-add-search-functionality-to-a-static-website" target="_blank" rel="noreferrer noopener">this thread</a> on Stack Overflow.&nbsp;</p>



<p>One of the replies mentioned a JavaScript-based search engine called <a href="https://github.com/lucaong/minisearch" target="_blank" rel="noreferrer noopener">MiniSearch</a>.</p>



<p>MiniSearch is intended to be lightweight enough to run entirely in memory—and even entirely within a browser. As long as I could find a way to feed all my data into it, I could perform searches on the client side rather than having to tax my Worker and risk maxing out Cloudflare’s free service tier. My effective, albeit slightly ridiculous, solution was to create a template that outputs the full content of every single post in JSON (a structured data format that works well with JavaScript) and tell Simply Static to generate this “page” along with the rest of the site.</p>



<p>Next, I created a new search page for the site that uses some client-side scripting (a/k/a JavaScript in the browser, where it typically lives) to fetch that big chunk of JSON, feed it into MiniSearch to generate an index, and then query MiniSearch&#8217;s index for whatever the user has typed into the search bar. Once it finds some results, the script formats the output via a templating library called <a href="https://handlebarsjs.com/" data-type="link" data-id="https://handlebarsjs.com/" target="_blank" rel="noreferrer noopener">Handlebars</a> (so-named because it makes extensive use of mustache-like curly braces), eventually presenting post previews to the user almost identically to how they would have appeared on my WordPress theme’s native results page. (Woo!)</p>



<h2 class="wp-block-heading">The Outcome</h2>



<p>I think it’s fair to say that the outcome for this project is self explanatory: you’re looking at it! You can browse every corner of this blog just like you could before the switch. Every post, page, and archive is still intact. On top of that, the contact forms are now home grown and no longer rely on a third-party plugin with aggressive upselling tactics. (This plugin shall remain nameless in protest!) This part of the project also gave me an opportunity to follow a great tutorial on <a href="https://cloudfour.com/thinks/progressively-enhanced-form-validation-part-1-html-and-css/#cons" target="_blank" rel="noreferrer noopener">progressively enhanced form validation</a>.</p>



<p>Meanwhile, I’m excited to use my experience with the Workers platform to help in my day job, where we’ve recently begun to experiment with Amazon’s cloud computing tools (a/k/a Amazon Web Services, which, if you haven’t heard, basically runs <em>everything </em>these days).</p>



<p>Finally, while the search bar is definitely not the most <em>important</em> component of this website, I do think it’s kind of neat that it actually still works. I never thought of search as something you could do entirely on the front end until now. (It does help that this blog isn’t actually that large and you can download all the text in about a second.)</p>



<p>While we&#8217;re on this topic, I think for a future project I’d like to update the search interface to use either <a href="https://react.dev/" data-type="link" data-id="https://react.dev/" target="_blank" rel="noreferrer noopener">React</a> or <a href="https://vuejs.org/" data-type="link" data-id="https://vuejs.org/" target="_blank" rel="noreferrer noopener">Vue</a> (which I’ve written about <a href="https://teachernerd.com/2020/10/01/a-summer-full-of-code/" data-type="post" data-id="646">here</a>). These “reactive” frameworks are really good at handling interfaces that need to update frequently or respond to events (like when you perform a new search or need to switch to the next page of results). Handlebars is <a href="https://handlebarsjs.com/guide/installation/when-to-use-handlebars.html" target="_blank" rel="noreferrer noopener">quite explicitly</a><em> not</em> intended for that sort of thing. (Oops!)</p>



<h2 class="wp-block-heading">The Takeaway</h2>



<p>Misapplied templating tools aside, I still think the search page is a neat hack, so here&#8217;s the <a href="https://gist.github.com/teachernerd/7dcee18e407dc003eff88d2fcd35ca6d" data-type="link" data-id="https://gist.github.com/teachernerd/7dcee18e407dc003eff88d2fcd35ca6d" target="_blank" rel="noreferrer noopener">full code</a> for anyone who’s interested!</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Sound of Plastic: Turning a Lego Radio into a Wireless Speaker</title>
		<link>https://teachernerd.com/2025/02/02/the-sound-of-plastic-turning-a-lego-radio-into-a-wireless-speaker/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Sun, 02 Feb 2025 23:49:54 +0000</pubDate>
				<category><![CDATA[Projects]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?p=1887</guid>

					<description><![CDATA[I think I can say with near-absolute confidence that I get just as much joy out of building Lego now as I did decades ago. My latest project was the Lego Icons Retro Radio (Item #10334). This model has a clever feature that lets you pop a phone inside to mimic a real device. But what if, instead of using my phone, I could put some dedicated electronics inside to create my very own wireless speaker?]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="640" height="480" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0228-1.jpeg" alt="" class="wp-image-1913" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0228-1.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_0228-1-300x225.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<p>Let me begin this post by quoting the New York Times:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>“Lego building is now as ubiquitous a leisure activity for adults as doing puzzles.”</p>
<cite>Joshua Lyon, writing for “Wirecutter”</cite></blockquote>



<p>With that…clarification?…excuse to use a pull quote?…out of the way, I think I can say with near-absolute confidence that I get just as much joy out of building Lego now as I did decades ago. And while I’m not the sort of <abbr title="Adult Fan of Lego">AFOL</abbr> who builds <abbr title="My Own Creations">MOCs</abbr> or nerds out at conventions, I will still happily spend minutes/hours/days assembling a brand new set.</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img loading="lazy" decoding="async" width="300" height="300" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_2785-300x300.jpeg" alt="" class="wp-image-1892" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_2785-300x300.jpeg 300w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_2785-150x150.jpeg 150w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_2785.jpeg 640w" sizes="auto, (max-width: 300px) 100vw, 300px" /><figcaption class="wp-element-caption">As a child, I was never a part sorter. My partner convinced me to start doing this&#8230;</figcaption></figure></div>


<p>My favorites are the so-called <a href="https://www.lego.com/en-us/adults-welcome/article/beginners-guide-modular" data-type="link" data-id="https://www.lego.com/en-us/adults-welcome/article/beginners-guide-modular" target="_blank" rel="noreferrer noopener">Modular Building Series</a>.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="301" height="305" src="https://teachernerd.com/wp-content/uploads/2025/02/64297775003__BD771CA2-F88C-4F99-BC27-9BC13C75C29C.jpeg" alt="" class="wp-image-1893" srcset="https://teachernerd.com/wp-content/uploads/2025/02/64297775003__BD771CA2-F88C-4F99-BC27-9BC13C75C29C.jpeg 301w, https://teachernerd.com/wp-content/uploads/2025/02/64297775003__BD771CA2-F88C-4F99-BC27-9BC13C75C29C-296x300.jpeg 296w" sizes="auto, (max-width: 301px) 100vw, 301px" /><figcaption class="wp-element-caption">The Lego bookstore was an obvious choice back in my English teacher days. Here it is atop a bookshelf—naturally—in my classroom.</figcaption></figure></div>


<p>But I’ve also enjoyed putting together official Lego renditions of familiar objects such as a <a href="https://www.lego.com/en-us/product/lego-ideas-fender-stratocaster-21329" data-type="link" data-id="https://www.lego.com/en-us/product/lego-ideas-fender-stratocaster-21329" target="_blank" rel="noreferrer noopener">Fender guitar</a> or a classic <a href="https://www.lego.com/en-us/product/typewriter-21327" data-type="link" data-id="https://www.lego.com/en-us/product/typewriter-21327" target="_blank" rel="noreferrer noopener">manual typewriter</a>.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="558" height="470" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_6953.jpeg" alt="" class="wp-image-1895" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_6953.jpeg 558w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_6953-300x253.jpeg 300w" sizes="auto, (max-width: 558px) 100vw, 558px" /><figcaption class="wp-element-caption">Seen here on my dining room table shortly after completion, this also used to be proudly displayed in my classroom. It now adorns a corner of the desk in my office inside a newsroom (perhaps even more appropriately).</figcaption></figure></div>


<p>Most recently, I had the opportunity to build <a href="https://www.lego.com/en-us/product/retro-radio-10334" data-type="link" data-id="https://www.lego.com/en-us/product/retro-radio-10334" target="_blank" rel="noreferrer noopener">Item #10334</a>, also known as the Lego Icons Retro Radio.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="538" height="640" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0236.jpeg" alt="" class="wp-image-1911" style="width:278px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0236.jpeg 538w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_0236-252x300.jpeg 252w" sizes="auto, (max-width: 538px) 100vw, 538px" /><figcaption class="wp-element-caption">The radio&#8217;s &#8220;retro&#8221; looks fit in quite well with the upholstered stool below it that once belonged to my grandmother.</figcaption></figure></div>


<p>It’s a very cool set in its own right, but what lands it a spot here on my blog is the opportunity it provided to embark on a nifty electronics/computing project.</p>



<h2 class="wp-block-heading"><strong>The Problem</strong></h2>



<p>Clocking in at just over 900 pieces, the Retro Radio would seem to be one of Lego&#8217;s less intense undertakings when you consider the plethora of parts and intricate techniques typically involved in, say, the Modular Buildings; at first glance, one might even argue that the model is little more than a pretentious box.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="640" height="480" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0224.jpeg" alt="" class="wp-image-1899" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0224.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_0224-300x225.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">Get it? It&#8217;s some Lego pieces. On a box!</figcaption></figure></div>


<p>However, as it turns out, there is a surprisingly elaborate contraption under the hood made up of Lego Technic parts.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="640" height="126" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0242.jpeg" alt="" class="wp-image-1914" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0242.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_0242-300x59.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">Axles and couplers and gears, oh my!</figcaption></figure></div>


<p>This series of axles and gears and such allows the tuning knob to really move a needle back and forth along the frequency dial. Meanwhile, the on/off knob, which features a delightfully tactile “click,” engages and disengages a secondary mechanism that repeatedly pushes a button on a “sound brick” as you move the needle. Each push of the button activates one of several randomized, pre-recorded sound clips. This adds a great “play” element to the model (in multiple senses of the word), but it also got me wondering: </p>



<p><strong>Could there be a way to turn this thing into something closer to an <em>actual</em> radio?</strong></p>



<p>Well, <em>technically</em>, Lego kind of already solved that problem. Removing the model’s back panel reveals a sort of spring-loaded cradle that you can clip a phone into. So all you have to do is pull up a playlist on Spotify (or Apple Music or whatever), pop in your phone, and boom! You’ve got yourself a “radio”!</p>



<p>That’s clever and all, but it does mean having to sacrifice access to your phone for the duration of your listening session, which is less than ideal if you want to, say, skip a song, switch to a new playlist, or send a text to your friend about your cool new toy.</p>



<h2 class="wp-block-heading"><strong>The Objective</strong></h2>



<p>As I thought about it some more, an idea began to crystallize. What if, instead of using my phone, I could semi-permanently mount some dedicated electronics inside to handle the music playback?</p>



<p>I quickly came across a blog post by U.K. freelance writer Sean McManus, who did just that using a Raspberry Pi. His particular innovation was to <a href="https://www.sean.co.uk/raspberry_pi/lego_retro_radio.shtm">replace the sound brick</a> with a similarly shaped contraption built out of normal Lego pieces onto which he glued a simple push-button. He wired the button to the Pi, along with a tiny sound card and speaker, positioned the button in the exact spot the sound brick had occupied, and then wrote a Python program that played his own, personalized selection of music and sound effects each time the model’s existing button-pushing mechanism happened to do its thing.</p>



<p>I considered at first trying to emulate this project but ultimately decided to go my own route. While I really appreciated how McManus managed to integrate the existing Lego control knobs with the electronics, I didn’t feel like dealing with glue or a soldering iron—or trying to find the necessary Lego pieces to build my own sound brick.</p>



<p>Plus, what I really wanted was the ability to play <em>any </em>music at all, not just a predetermined collection of clips. So, what I finally set out to create was a <strong>pint-sized wireless speaker system</strong>.</p>



<p>As for my <strong>criteria</strong>, the system needed to be:</p>



<ul class="wp-block-list">
<li>Tiny enough to hide inside the Retro Radio (ideally without removing any parts)</li>



<li>Easy to connect to remotely from a phone or computer for the sole purpose of streaming music or other audio</li>



<li>Buildable without glue or solder</li>



<li>Self-contained (no need to repeatedly open up the Lego model to access the electronics or to &#8220;log in&#8221;  to any components for administrative tasks)</li>
</ul>



<h2 class="wp-block-heading"><strong>The Solution</strong></h2>



<p>Although my main goal diverged from McManus’s project, his write-up gave me a great place to start. In fact, like McManus, I chose to use a Raspberry Pi as the “brains” of the operation and an add-on board from “Maker Goods” purveyor Pimoroni to provide the audio capabilities. But where McManus opted for a full-sized Raspberry Pi and a separate speaker, I decided to go for a more compact solution.</p>



<p>The model of Pi I chose (the flavor, if you will) was the <a href="https://www.raspberrypi.com/products/raspberry-pi-zero-2-w/" data-type="link" data-id="https://www.raspberrypi.com/products/raspberry-pi-zero-2-w/" target="_blank" rel="noreferrer noopener">Zero 2 W</a>. While the original Pi form factor is roughly the size of a credit card, the Zero line is advertised as only 65mm x 30mm (that’s approximately 2.6” x 1.2” for us Americans). In other words, it’s <em>small</em>!</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="700" height="463" src="https://teachernerd.com/wp-content/uploads/2025/02/zero-2-wh.png" alt="" class="wp-image-1901" style="width:640px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/02/zero-2-wh.png 700w, https://teachernerd.com/wp-content/uploads/2025/02/zero-2-wh-300x198.png 300w" sizes="auto, (max-width: 700px) 100vw, 700px" /><figcaption class="wp-element-caption">Look at the cute little guy! (Source: <a href="https://github.com/raspberrypi/documentation" target="_blank" rel="noreferrer noopener">Raspberry Pi Documentation</a>, © Raspberry Pi Ltd. Reproduced under Creative Commons license – <a href="https://creativecommons.org/licenses/by-sa/4.0/" data-type="link" data-id="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noreferrer noopener">CC BY-SA 4.0</a>)</figcaption></figure></div>


<p>It may not be as powerful as its larger brethren, but the Zero 2 W still includes built-in WiFi and Bluetooth, perfect for streaming music from one device to another. And because I would not need to log in and run any sort of desktop environment, I suspected I could get by just fine with the Zero’s diminutive 1Ghz processor and 512MB of RAM.</p>



<p>To handle the sound output, I selected the <a href="https://shop.pimoroni.com/products/pirate-audio-mini-speaker?variant=31189753692243" target="_blank" rel="noreferrer noopener">Pimoroni Pirate Audio Speaker</a>. It’s a clever device that packs all the necessary components for audio output—a <abbr title="Digital-to-Analog Converter">DAC</abbr>, amplifier, and 1W speaker—onto a single board the exact same size as the Pi Zero.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="640" height="425" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0241.jpeg" alt="" class="wp-image-1918" style="width:438px" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0241.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_0241-300x199.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">I don&#8217;t know what a &#8220;temperate monkey&#8221; is, but I do appreciate this fun new toy&#8217;s globetrotting ways!</figcaption></figure></div>


<p>The board also includes a 1.3” color LCD and four tactile buttons. While I wouldn’t be needing any of those for this project, I figured they could come in handy in the future (if only I hadn’t managed to break the screen less than a week after buying it).</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="438" height="329" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0240-edited.jpeg" alt="" class="wp-image-1917" style="width:438px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0240-edited.jpeg 438w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_0240-edited-300x225.jpeg 300w" sizes="auto, (max-width: 438px) 100vw, 438px" /><figcaption class="wp-element-caption">Behold the wonderfully &#8220;smol&#8221; Pirate Audio board attached to the similarly &#8220;smol&#8221; Raspberry Pi Zero. (Bonus points if you can see the large, radially oriented crack in the bottom right corner of the LCD screen.)</figcaption></figure></div>


<p>The Pirate Audio board attaches to the Raspberry Pi via its 40-pin GPIO interface and requires only a teensy bit of configuration to get it working. (The Pi Zero typically comes without the GPIO header attached; I bought one from my local electronics shop that had it pre-soldered to the device to help meet my aforementioned specifications.)</p>



<p>With all the hardware in place, the last piece of the puzzle (or pie?) is the software. Ideally, I wanted to be able to connect my phone or computer to the speaker setup using Bluetooth or, since I’m an iPhone/Mac guy, the AirPlay protocol, which operates over WiFi. I experimented with this sort of thing years ago, so I already knew that there were open source tools out there for handling this. For AirPlay support, the gold standard seems to be a project called Shairport Sync, which provides a mostly all-in-one, reverse engineered implementation of Apple’s proprietary protocol. For Bluetooth, perhaps because it’s a more open standard, the options are a bit more varied, but they all ultimately require cobbling together several different utilities to get the job done. (More on this later, if you’re interested.)</p>



<p>Finally, because it’s what I am most familiar with, I chose to install all of this on top of the standard Raspberry Pi OS (a Debian-based Linux distribution). I went with the Lite version to keep space and resource requirements to a minimum.</p>



<h2 class="wp-block-heading"><strong>The Outcome</strong></h2>



<p>Strangely enough, one of the most challenging parts of the operation was attaching the sound card. I expected the Pi’s GPIO pins to slide right into the sockets on the Pirate Audio board’s header. Instead, this operation required a fair bit of force, which likely contributed to my having accidentally cracked the panel (a misfortune to which I believe I alluded in an earlier parenthetical—alas!)</p>



<p>The only other physical task was to fit the assembled device into the Lego model, which turned out to be quite easy thanks to its small size. There&#8217;s even already a convenient gap in the back panel through which you can route the power cord. (You just have to reposition a single, structurally insignificant piece, as McManus noted, to widen the space a bit.)</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="640" height="480" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0238.jpeg" alt="" class="wp-image-1919" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0238.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_0238-300x225.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">It&#8217;s almost like it was designed for this!</figcaption></figure></div>


<p>The rest of the project was a not-particularly-enthralling-in-verbal-form process of downloading, compiling, installing, configuring, and testing various software components until finally, a working Bluetooth/AirPort speaker was born. (Don’t worry, I’ll share all the gory details in the next section for those who are still interested.)</p>



<p>The actual results were, well, pretty much what I expected. Even at maximum volume, the sound from the 1W speaker is meek at best. I would describe it as “serviceable” when playing rock and pop songs, but if you try like I did to throw something at it with a wider dynamic range, such as <a href="https://en.wikipedia.org/wiki/Symphony_No._9_(Dvořák)" target="_blank" rel="noreferrer noopener">Dvořák’s Symphony No. 9</a>, you may have to strain to hear the quieter sections. That said, the quality, lacking in anything resembling bass or oomph, seems somehow appropriate when emanating from what is, essentially, a toy made entirely out of plastic, so I kind of consider that to be a feature rather than a bug.</p>



<p>I expected to have the most trouble getting AirPlay to work, but Shairport Sync ended up working incredibly well. My fiancée encountered some hiccups with the sound periodically cutting out when she tried it from her own phone, but I think this might have been an issue with the WiFi signal in our apartment rather than a problem with any of the software.</p>



<p>Bluetooth playback, meanwhile, seemed to be less spotty—when we could get our devices to connect in the first place. The very first time either of us would try to pair a computer or phone to the Pi, everything would go great. But if we disconnected a device and then tried to <em>re-</em>connect, that’s when things started to go wrong. It’s a mild annoyance that can thankfully be solved by resetting the Pi and telling the relevant phone/computer to forget the speaker.</p>



<p>…Or we can just use AirPlay!</p>



<p>I doubt this tone- and volume-challenged Lego creation is something I’ll use as a speaker all that regularly, but I do appreciate how a model that could be a great conversation starter in its own right has had its novelty factor cranked up to 11!</p>



<h2 class="wp-block-heading"><strong>The Takeaway</strong></h2>



<p>If you’d like to try recreating this project yourself, this section is for you! I’m not going to go into <em>all</em> the minutiae, but I’ll walk you through the process I followed, point out a few challenges I ran into, and link to some step-by-step guides for installing the necessary software.</p>



<p><em>To streamline this as best I can, I will assume you are already reasonably familiar with the Raspberry Pi and have spent some time on a Linux command line before.</em></p>



<p>If you&#8217;re really only here for the bird&#8217;s eye view, feel free to just move right along!</p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary>Read More&#8230;</summary>
<p></p>



<h3 class="wp-block-heading"><strong>Initial Setup</strong></h3>



<p>As with any Raspberry Pi project, the first step is to flash an OS to a micro-SD card. There are, of course, a number of ways to do this, but I particularly like the official <a href="https://www.raspberrypi.com/software/" data-type="link" data-id="https://www.raspberrypi.com/software/" target="_blank" rel="noreferrer noopener">Raspberry Pi Imager</a> because it lets you do some basic setup ahead of time, including giving the Pi a hostname, configuring WiFi, and setting it up to accept SSH connections.</p>



<p>After the device finishes booting up for the first time, you&#8217;ll want to log in over SSH and make sure that all the latest updates are installed. (You could theoretically hook up a keyboard and monitor to access the Pi directly, but I find the remote connection to be more convenient.)</p>



<p>As for hardware configuration, this is just a matter of adding three lines to <code>/boot/firmware/config.txt</code>—one to make the audio board recognizable by the Pi’s firmware, one to turn on a GPIO pin used to activate the onboard amp, and another to turn off the Pi’s built-in audio (to avoid any issues with software choosing the wrong output device).</p>



<pre class="wp-block-code"><code>dtoverlay=hifiberry-dac
gpio=25=op,dh
dtparam=audio=off</code></pre>



<p>(See the <a href="https://github.com/pimoroni/pirate-audio">Pirate Audio GitHub repository</a> for more information, but be forewarned that some of the instructions are a bit out of date, and most of them are about using the LCD screen or Pimoroni’s suggested audio playback software, neither of which are required for this project.)</p>



<p>It&#8217;s best to reboot the Pi after making these changes. As for me, when it was done rebooting, I took a moment to run the <code>raspi-config</code> tool to expand the SD card’s file system. The tool also allowed me to make sure the &#8220;snd_rpi_hifibery_dac&#8221; component was detected and set as the default audio device.</p>



<h3 class="wp-block-heading"><strong>Sound Test</strong></h3>



<p>Once all the hardware is configured and OS maintenance is complete, you can test whether the speaker works by running the following command: <code>speaker-test -c 1 -t wav</code>. This, thankfully, worked for me on first try. My dog was a bit concerned about the disembodied voice proclaiming, “Left speaker…left speaker…,” on loop, but otherwise, all was good!</p>



<h3 class="wp-block-heading"><strong>AirPlay Support</strong></h3>



<p>Now, it&#8217;s <em>finally</em> time to start installing some software. A lot of it needs to be compiled yourself, but the process requires fairly minimal manual effort.</p>



<p>As I mentioned earlier, the key to AirPlay support is an open source solution called Shairport Sync. This project is <em>very</em> well documented, with detailed, step by step <a href="https://github.com/mikebrady/shairport-sync/blob/master/BUILD.md">build instructions</a> that walk you through all the commands that need to be run. I ran into one tiny snag, which was that I needed to add `libglib2.0-dev` to the list of dependencies to install.</p>



<p>After that, the instructions are fairly straightforward, especially if you choose to omit support for the AirPlay 2 protocol and avoid adding any configuration flags other than the ones used in the default walkthrough.</p>



<p><em>My first time through, I went with the basic approach. For the sake of experimentation, I later went back and added all the bells and whistles, which meant compiling and installing a helper daemon called <a href="https://github.com/mikebrady/nqptp.git" target="_blank" rel="noreferrer noopener">NQPTP</a> (required for some sort of fancy timing system that is evidently integral to AirPlay 2), a library providing <a href="https://github.com/mikebrady/alac.git" target="_blank" rel="noreferrer noopener">support for the Apple Lossless codec</a> (totally overkill for a tone-challenged 1W speaker, but hey, why not?), and another library called <a href="https://github.com/libsndfile/libsndfile">libsndfile</a> (necessary for some more very much unnecessary fanciness). Again, none of that is strictly necessary.</em></p>



<p>One configuration flag that you <em>don’t</em> want to leave out is <code>--with-systemd</code>. This ensures that the Shairport daemon can be easily started at boot time without the need for logging in or any other user intervention. All you have to do is run <code>systemctl enable shairport-sync</code> at the conclusion of the install process.</p>



<p>Once I had this all compiled and installed, within a few moments of rebooting the Raspberry Pi, “Lego” showed up as a speaker option on all of my Apple devices, all of which were able to connect without any fuss. The only real issue I encountered was that I could barely hear anything at first. I was able to resolve this, however, by—wait for it—raising the speaker’s volume via the connected device! (You may wish to spend some time, as I did, exploring the <a href="https://github.com/mikebrady/shairport-sync/blob/master/ADVANCED%20TOPICS/InitialConfiguration.md">additional options</a> available in Shairport Sync’s configuration file, but once again, based on my experience, this should not be strictly necessary.)</p>



<h3 class="wp-block-heading"><strong>Bluetooth Woes—I Mean, Support</strong></h3>



<h4 class="wp-block-heading">Audio</h4>



<p>The final challenge is Bluetooth. This part is definitely a little more complicated. The most important component is a project called the Bluetooth Audio ALSA Backend (BlueALSA for short). This is probably an oversimplification, but BlueALSA is essentially a bit of glue that gets the software components that support the Bluetooth hardware to talk to the software components that support the audio hardware.</p>



<p>As with Shairport Sync, BlueALSA needs to be compiled from source before installing, but it too has a <a href="https://github.com/arkq/bluez-alsa/wiki/Installation-from-source" target="_blank" rel="noreferrer noopener">step-by-step walkthrough</a>. There are a <em>lot</em> of configuration flags you can play with, but I ended up skipping all of them except for <code>--enable-systemd</code>. As with Shairport, this option makes it easy to run BlueALSA as a background service without having to be logged in.</p>



<p>This isn’t mentioned in the official walkthrough, but to actually enable Bluetooth audio support at startup you need to run <code>sudo systemctl enable bluealsa</code> followed by <code>sudo systemctl enable bluealsa-aplay</code>. This activates two system services that work together to forward incoming Bluetooth audio over to the sound system.</p>



<h4 class="wp-block-heading">Authentication</h4>



<p>But of course, even <em>that’s</em> not enough to get this all working. There also needs to be a way to handle the Bluetooth authentication process—the complicated handshake that we all know so well, mostly thanks to how often it fails. (Have you ever had to have one Bluetooth-enabled device “forget” another Bluetooth-enabled device?)</p>



<p>There seem to be a number of ways to handle this, but I liked the <a href="https://forums.raspberrypi.com/viewtopic.php?t=235519">solution</a> documented by none other than a user going by “DrFunk” on the Raspberry Pi forums. Basically, you need to install an “agent” that hangs out and waits for Bluetooth connections. Once it detects one, it automates the process of accepting/trusting that connection so that you don’t have to log into the Pi and do so manually.</p>



<p>My advice: just skip all the way to Step 4 and follow the instructions to install &#8220;bluez-tools&#8221; (not to be confused with a certain beloved children&#8217;s television show) and create a service to start the unsurprisingly named <code>bt-agent</code> at runtime. If you’d like some extra security (instead of blindly auto-trusting all connections), you can also follow Step 5 to add a PIN. I also recommend following Step 7.1, which disables a volume control protocol that could add some additional complications.</p>



<p>Once I did all that, I was, in fact, able to use the Pi Zero as a Bluetooth speaker in addition to an AirPort speaker—with some caveats.</p>



<h4 class="wp-block-heading">Annoyance</h4>



<p>One unfortunate complication that I never quite figured out was that I ran into trouble any time I tried to disconnect a device from the Pi and then reconnect. The only way to fix this was to have both the source device and the Pi forget one another and then re-start the pairing process, so Bluetooth on this device continues to be a work in progress.</p>



<h4 class="wp-block-heading">Turning the Music Down—er, Off</h4>



<p>Even with AirPlay working nicely and Bluetooth kinda-sorta working, there was still one final problem to overcome: the Raspberry Pi does not have an on/off switch, and even if it did, the goal is to keep the thing hidden inside an enclosed Lego model. In a perfect world, I should be able to just pull the plug like I would with a normal radio, but doing that to a running computer, which at any moment might be writing to its storage medium, could lead to data corruption and eventual system failure.&nbsp;</p>



<p>To overcome <em>that</em>, I decided to use a nifty feature in the <code>raspi-config</code> utility that automates the process of setting up an &#8220;overlay&#8221; filesystem. This is a clever trick that makes the Pi’s memory card effectively read-only by putting a temporary RAM disk in between the fixed storage and the operating system. Any changes to the file system are written to the RAM disk instead of the underlying storage (i.e. the SD card) and are simply lost when you pull the plug. The SD card, meanwhile, theoretically remains in the exact same state during all subsequent boots as it was prior to enabling the overlay.</p>



<p>In addition to insulating the SD card from damage due to hard shutdowns, this also helps work around some of the Bluetooth finickiness since the Pi can now instantly forget all devices that have previously connected to it over Bluetooth as soon as the plug is pulled, preventing you (or me) from having to ever log back in to do this by hand.</p>



<h3 class="wp-block-heading">Final Assembly</h3>



<p>The last step, if you haven&#8217;t done this already, is to fit the Pi inside the Lego model.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="640" height="480" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0242-1.jpeg" alt="" class="wp-image-1920" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0242-1.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_0242-1-300x225.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<p>If you route the power cord the same way McManus describes in his blog post, the tension created by the cord and the phone cradle will help keep the Pi in place. It&#8217;s not exactly a <em>snug</em> fit, but it&#8217;ll do. (If you&#8217;re feeling clever, you can probably whip up a more secure mechanism with your own Lego parts.)</p>



<p>With the Pi in place, you can put the back cover back on the model, fully enclosing the electronics and completing the illusion that this is a real A/C-powered radio.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="640" height="480" src="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0237.jpeg" alt="" class="wp-image-1938" style="width:640px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2025/02/IMG_0237.jpeg 640w, https://teachernerd.com/wp-content/uploads/2025/02/IMG_0237-300x225.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">That&#8217;s it! Time to play some tunes!</figcaption></figure></div></details>



<h2 class="wp-block-heading"><strong>Wrapping Up</strong></h2>



<p>I hope this project has inspired you to dig some old Lego sets out of your basement or just learn more about the awesome world of AFOLs and MOCs. Or perhaps you’re ready to find your own unexpected object to turn into a tiny speaker. As always, if you come up with a cool idea of your own, or you found this write-up helpful, <a href="https://teachernerd.com/contact/">I’d love to hear about it</a>.</p>



<p>Until next time, thanks for following along!&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Polishing the Chrome: Installing Google&#8217;s OS on a Rusty, Technically Incompatible MacBook Pro</title>
		<link>https://teachernerd.com/2024/07/30/polishing-the-chrome-installing-googles-os-on-a-rusty-technically-incompatible-macbook-pro/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Tue, 30 Jul 2024 02:27:17 +0000</pubDate>
				<category><![CDATA[Projects]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?p=1868</guid>

					<description><![CDATA[When the computing needs of an older relative of ours recently outgrew an aging Android tablet, my fiancée and I turned to a brand new, easy-to-support Chromebook.

But if anything went wrong, how would we be able to help without a Chromebook of our own to follow along on? If only I could figure out how to successfully boot ChromeOS on a 14-year-old MacBook Pro with an incompatible video card...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="640" src="https://teachernerd.com/wp-content/uploads/2024/07/Screenshot-2024-07-28-5.50.54-PM-1-1024x640.png" alt="" class="wp-image-1874" srcset="https://teachernerd.com/wp-content/uploads/2024/07/Screenshot-2024-07-28-5.50.54-PM-1-1024x640.png 1024w, https://teachernerd.com/wp-content/uploads/2024/07/Screenshot-2024-07-28-5.50.54-PM-1-300x188.png 300w, https://teachernerd.com/wp-content/uploads/2024/07/Screenshot-2024-07-28-5.50.54-PM-1-768x480.png 768w, https://teachernerd.com/wp-content/uploads/2024/07/Screenshot-2024-07-28-5.50.54-PM-1.png 1440w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>I’m not exactly a fan of Google having access to all our information ever, nor do I feel great about how, through its substantial dominance of the Internet, Google gets to quasi-unilaterally dictate all manner of policies regarding web standards, privacy, and security.</p>



<p>But even I have to give Alphabet, Inc. credit where credit is due: if you’re a user with pretty basic needs looking for a modern, easy-to-use, easy-to-maintain, and stable computing platform, there is nothing quite like Google’s <a href="https://chromeos.google/" data-type="link" data-id="https://chromeos.google/"><strong>ChromeOS</strong></a>.</p>



<p>When ChromeOS was first announced, the idea seemed pretty absurd. Could a platform originally designed to run just a single application—the Chrome web browser—actually be of any use? Well, over a decade later, with Chromebooks continuing to grace the shelves of big box retailers and increasingly being adopted by school systems and businesses looking for low-cost yet reliable machines, the answer is clear.</p>



<h2 class="wp-block-heading"><strong>The Problem</strong></h2>



<p>ChromeOS has evolved over the years and can technically do more these days than just run Chrome. The latest Chromebooks support software built for Linux and Android, and enterprise users can even run Windows applications by way of virtualization. But ChromeOS’s bread and butter is the way it gives users access to all the powers and possibilities of modern web apps without all the complicated layers of configuration, software updates, and other UX distractions that might otherwise get in the way.</p>



<p>For all these reasons, when the computing needs of an older relative of ours recently outgrew an aging Android tablet, my fiancée and I felt pretty confident that a Chromebook would get the job done while minimizing our need to assist with long-term tech support.</p>



<p>There was just one catch: even though ChromeOS is fairly intuitive, it would be reasonable to assume that a brand new user might need at least a <em>little</em> hand holding at first. Unfortunately, while we both consider ourselves adept computer users, neither of us has had all that much experience working with Chromebooks.</p>



<h2 class="wp-block-heading"><strong>The Objective</strong></h2>



<p>Providing support – especially over the phone – when you have no idea what the environment actually looks like is definitely no fun.</p>



<p>To make this work, it would be a lot easier to have a Chromebook of our own to experiment with and follow along on—if only that wouldn’t require buying a <em>second</em> new computer. Frankly, we already have too many computers lying around, so this whole situation would be much more palatable if we could just install ChromeOS on a machine we already own.</p>



<p>Because ChromeOS is actually based on an open source project called ChromiumOS, it has been theoretically possible to create a makeshift Chromebook for almost as long as real Chromebooks have been around.</p>



<p>Google, historically, has never made ready-to-go ChromiumOS images directly available to the public, but the source code has always been freely available. With enough skill and determination, you could compile that code yourself into working executables, add in any missing device drivers, and then figure out how to get it all onto a compatible device. This process is not exactly straightforward, but luckily, there have always been a handful of folks out there in cyberspace, including someone who goes by <a href="https://arnoldthebat.co.uk/wordpress/chromium-os/">Arnold the Bat</a>, willing to take on this challenge for us mere mortals.</p>



<p>I have successfully followed Arnold’s instructions before, so that was definitely a possible route to take here. One downside, however, is that this process has not always gone smoothly when I’ve tried it. More crucially, ChromiumOS is not an <em>exact</em> clone of ChromeOS; Google adds some of its own proprietary features on top of the open source core. While there are “ways” of adding back some of these missing features, my preference would be to avoid that can of worms and start with something much more closely resembling the real thing.</p>



<h2 class="wp-block-heading"><strong>The Solution</strong></h2>



<p>Enter <strong><a href="https://chromeos.google/products/chromeos-flex/" target="_blank" rel="noreferrer noopener">ChromeOS Flex</a></strong>. Announced in 2022, this product marked the first time that Google itself, rather than a third party, would provide a way to install not just ChromiumOS but the full-fledged (well, <em>nearly</em> full-fledged) ChromeOS on user’s own hardware. (Some features, such as Android app support, are still not included.)</p>



<p>I successfully installed Flex on an old custom-built desktop when it was first released, but this time around, for maximum “flex”-ibility, I wanted to use it on an old laptop I had dug out of my closet: a MacBook Pro “Mid-2010” model (i.e. a <a href="https://everymac.com/ultimate-mac-lookup/?search_keywords=MacBookPro6%2C2" target="_blank" rel="noreferrer noopener">MacBookPro6,2</a> if you’re familiar with Apple’s internal nomenclature).</p>



<p>This is where things get tricky.</p>



<h2 class="wp-block-heading"><strong>The Outcome</strong></h2>



<p>Google provides a pretty thorough <a href="https://support.google.com/chromeosflex/answer/11552529?hl=en&amp;sjid=17012851602595199056-NA&amp;visit_id=638577915560158214-1796010922&amp;ref_topic=11551271&amp;rd=1">installation guide</a>, so I’m not going to get into all the particulars here. Suffice it to say, I followed their directions to create a bootable USB stick, plugged it into the computer, and used Apple’s OS picker (accessible by holding down the “Option” key while booting) to boot ChromeOS instead of macOS.</p>



<p>To my momentary delight, the ChromeOS logo appeared, and then…</p>



<p>Nothing. I could move a mouse cursor around the screen, but otherwise, all I could ever see was the logo.</p>



<p>Interestingly, at some point Google’s built-in accessibility tool kicked in and started reading the screen to me—except that the screen it was reading was definitely <em>not</em> there! The screen reader would even tell me about the invisible things I was evidently clicking on and the keypresses that it was evidently detecting.</p>



<p>Something was clearly amiss. Given that everything else seemed to be working, my hypothesis was that this was related to graphics drivers (as the weirdest computer issues so often are, in my experience).</p>



<p>I knew from the get-go that this computer was not on Google’s <a href="https://support.google.com/chromeosflex/answer/11513094?hl=en">certified models list</a>. Nevertheless, not one to be easily discouraged when someone tells me a computer can’t do something, I decided to keep digging, despite the post I found on Reddit confirming that support for NVIDIA chipsets like the graphics hardware in this computer was spotty at best.</p>



<p>You are much more likely to find success, the collective wisdom of the internet explained, running ChromeOS Flex on a computer with <strong>integrated graphics </strong>(i.e. when video hardware is built into a machine’s main processor rather than existing as part of a “discrete” card or chipset).</p>



<p>The thing is, despite that pesky NVIDIA processor my laptop was saddled with, the MacBookPro6,2<em> </em>just so happens to <em>also</em> have Intel’s integrated graphics technology built in. It&#8217;s just that in this particular model, it plays second fiddle in order to enable, among other things, a power-saving mode. But maybe, I thought, I could find some way to <em>force</em> ChromeOS to use the Intel graphics and somehow ignore the NVIDIA chip.</p>



<p>The first thing I tried was to install a third-party boot manager called <a href="https://www.rodsbooks.com/refind/">rEFInd</a>, a powerful albeit esoteric open source project (with a website stuck in the 90s) familiar to people like myself who like to boot alternative operating systems on their Macs. I’ll spare you all the details of the Extensible Firmware Interface and boot procedures. What matters right now is that rEFInd has a feature that can trick a Mac into thinking that it’s running macOS even when it isn’t, thereby getting the firmware to enable certain components, such as the integrated graphics functionality, that it otherwise might not.</p>



<p>Unfortunately, this did not solve the graphics glitch.</p>



<p>It was therefore time for a more drastic measure. I knew from previous experience that there are sometimes ways to forcibly disable the discrete graphics chipset on Apple laptops like mine. This was known to be one of the methods, for instance, by which you could “repair” certain models when the dedicated graphics chipset began to fail.</p>



<p>After some more Googling, I tracked down a thread on <a href="https://apple.stackexchange.com/questions/166876/macbook-pro-how-to-disable-discrete-gpu-permanently-from-efi">Stack Exchange</a> with the trick that I was pretty sure existed: namely, a near-incomprehensible terminal command (`sudo nvram fa4ce28d-b62f-4c99-9cc3-6815686e30f9:gpu-power-prefs=%01%00%00%00) that sets a variable in the system’s firmware that, in turn, tells the machine <em>not</em> to enable the dedicated graphics on bootup. My theory was that if I could get this to work, then maybe ChromeOS would see (and thus use) the integrated graphics instead.</p>



<p>So I booted the machine into recovery mode to ensure that none of Apple’s system protections could get in the way and ran the command. To my pleasant surprise, it actually worked! The next time I tried to boot off of the ChromeOS USB stick, the user interface finally displayed correctly, allowing me to finish setting things up and even try to get some work done. (I typed out my entire first draft of this blog post in Google Docs running on ChromeOS on my 14-year-old MacBook Pro.)</p>



<h2 class="wp-block-heading"><strong>Wrapping Up</strong></h2>



<p>Truth be told, this is not a computer I have all that much interest in actually <em>using</em>. While I still really appreciate its form factor, with a 15” screen and spacious keyboard, the thing is <em>heavy</em>. I also really miss the “retina” display on Apple’s newer laptops. And most concerningly, I forgot just how <em>hot</em> this computer runs; it quite literally burns my legs if I try to use it on my lap for more than a few minutes.</p>



<p>That said, the point was for my partner and I to be able to familiarize ourselves with ChromeOS and have access to a model setup that we could use for helping our relative. And in that way, the project has been a resounding success. It took a little extra effort, but we now have exactly what we needed without having had to spend a penny more!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Deep Dive – Evolving Standards</title>
		<link>https://teachernerd.com/series/deep-dive-evolving-standards/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Sat, 25 May 2024 02:53:32 +0000</pubDate>
				<category><![CDATA[Essays]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?post_type=sitepoint-postseries#038;p=1826</guid>

					<description><![CDATA[<!-- wp:paragraph -->
<p>I spent years teaching students the fundamentals of journalism so that they could create high-quality newspapers, magazines, and yearbooks. Before that, I was a student journalist myself, writing for my high school and college newspapers, eventually becoming editor-in-chief of the former and an associate editor for the latter. Now, I'm part of a small team developing code and providing digital support for a nationwide network of news websites.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>While I've mostly used <em>this </em>website (which, I should note, represents only my own personal opinions and <em>not</em> those of my employer) to talk about tech, I think I've made it clear that I <em>love</em> participating in and thinking about journalism. So today, I'd like to present the first of what I hope to be a continuing series of Media Deep Dives, where we'll take a look together at something out there in the news sphere—an article, photograph, etc.—and consider what makes it tick or examine its broader implications for the practice of journalism.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For this inaugural installment, which I've decided to split into two parts, I'd like to do both while sharing a story from The Washington Post about <a href="https://wapo.st/3V6hP3l">police departments that have found ways to skirt local bans on the use of facial recognition technology</a>. While the story initially caught my eye thanks to my interest in AI ethics, I'm going to mostly set those issues aside. Instead, I'd like to start by exploring what this article shows us about the evolving nature of <strong>headlines</strong>. Then, in part 2, we can take a look at how this story exemplifies some of the debates around <strong>objectivity </strong>in journalism.</p>
<!-- /wp:paragraph --><ol class='sitepoint-post-series'><li><a href='https://teachernerd.com/2024/05/19/headlines-in-the-digital-age/'>Headlines in the Digital Age</a></li><li><a href='https://teachernerd.com/2024/05/25/objectivity-vs-neutrality/'>Objectivity vs. Neutrality</a></li></ol>]]></description>
										<content:encoded><![CDATA[
<p>I spent years teaching students the fundamentals of journalism so that they could create high-quality newspapers, magazines, and yearbooks. Before that, I was a student journalist myself, writing for my high school and college newspapers, eventually becoming editor-in-chief of the former and an associate editor for the latter. Now, I&#8217;m part of a small team developing code and providing digital support for a nationwide network of news websites.</p>



<p>While I&#8217;ve mostly used <em>this </em>website (which, I should note, represents only my own personal opinions and <em>not</em> those of my employer) to talk about tech, I think I&#8217;ve made it clear that I <em>love</em> participating in and thinking about journalism. So today, I&#8217;d like to present the first of what I hope to be a continuing series of Media Deep Dives, where we&#8217;ll take a look together at something out there in the news sphere—an article, photograph, etc.—and consider what makes it tick or examine its broader implications for the practice of journalism.</p>



<p>For this inaugural installment, which I&#8217;ve decided to split into two parts, I&#8217;d like to do both while sharing a story from The Washington Post about <a href="https://wapo.st/3V6hP3l">police departments that have found ways to skirt local bans on the use of facial recognition technology</a>. While the story initially caught my eye thanks to my interest in AI ethics, I&#8217;m going to mostly set those issues aside. Instead, I&#8217;d like to start by exploring what this article shows us about the evolving nature of <strong>headlines</strong>. Then, in part 2, we can take a look at how this story exemplifies some of the debates around <strong>objectivity </strong>in journalism.</p>
<ol class='sitepoint-post-series'><li><a href='https://teachernerd.com/2024/05/19/headlines-in-the-digital-age/'>Headlines in the Digital Age</a></li><li><a href='https://teachernerd.com/2024/05/25/objectivity-vs-neutrality/'>Objectivity vs. Neutrality</a></li></ol>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Extra Credit: Displaying the top score in a popular word game</title>
		<link>https://teachernerd.com/2023/12/21/extra-credit/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Thu, 21 Dec 2023 20:43:33 +0000</pubDate>
				<category><![CDATA[Projects]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?p=1657</guid>

					<description><![CDATA[For good reasons, the New York Times does not openly publish the total possible points for its daily Spelling Bee puzzle. But when my partner and I play the game, we like to figure it out anyway and then see how close we can get. This is a well-defined task with well-defined inputs, so I decided to find a way to calculate and display the "Queen Bee" threshold automatically.]]></description>
										<content:encoded><![CDATA[
<p>The New York Times Company shocked the casual gaming world in January 2022 with its surprise purchase of Wordle, the trendy daily word puzzle that had recently taken the internet by storm, for an undisclosed but reportedly <a href="https://www.nytimes.com/2022/01/31/business/media/new-york-times-wordle.html" data-type="link" data-id="https://www.nytimes.com/2022/01/31/business/media/new-york-times-wordle.html" target="_blank" rel="noreferrer noopener">quite large</a> sum of money.</p>



<p>While the deal—for a barely three-month-old piece of intellectual property—undoubtedly turned plenty of heads, Wordle cannot be deemed the <em>most</em> buzz-worthy word game in the New York Times lineup. That title, naturally, will forever belong to <a href="https://www.nytimes.com/puzzles/spelling-bee" data-type="link" data-id="https://www.nytimes.com/puzzles/spelling-bee" target="_blank" rel="noreferrer noopener">Spelling Bee</a>.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="412" height="298" src="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.30.28 PM.png" alt="" class="wp-image-1665" style="width:238px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.30.28 PM.png 412w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.30.28 PM-300x217.png 300w" sizes="auto, (max-width: 412px) 100vw, 412px" /></figure></div>


<p>A quick run-down of the rules for the uninitiated: Each day, the game features a new set of seven unique letters arranged in a honeycomb-like grid. Players must use these letters—and <em>only</em> these letters—to create as many words as possible, earning points based on their length. Every word has to be at least four letters long and must include the central, highlighted letter at least once. Other than that, individual letters may be used as many (or as few) times as needed.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="654" height="766" src="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.33.22 PM.png" alt="" class="wp-image-1669" style="width:220px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.33.22 PM.png 654w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.33.22 PM-256x300.png 256w" sizes="auto, (max-width: 654px) 100vw, 654px" /></figure></div>


<p>One other interesting quirk: The solution to each Spelling Bee puzzle includes at least one word that incorporates all seven letters. These bonus words, known as &#8220;pangrams,&#8221; earn the player extra points. This is significant because the game assigns its players a series of ranks each day based on the number of points they have earned, culminating in the coveted status of &#8220;Genius.&#8221;</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="529" src="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.32.33 PM-1024x529.png" alt="" class="wp-image-1668" style="width:360px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.32.33 PM-1024x529.png 1024w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.32.33 PM-300x155.png 300w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.32.33 PM-768x396.png 768w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.32.33 PM.png 1236w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>


<h2 class="wp-block-heading">The Problem</h2>



<p>Assuming the posts on <a href="https://www.reddit.com/r/NYTSpellingBee/comments/khpx59/how_often_do_you_get_queen_bee/" data-type="link" data-id="https://www.reddit.com/r/NYTSpellingBee/comments/khpx59/how_often_do_you_get_queen_bee/">this Reddit board</a> are indicative of the typical Spelling Bee enthusiast, most players are happy to achieve Genius and move on. However, there exists one more, hidden rank reserved for the intrepid few who manage to find <em>every</em> word on a given day: Queen Bee.</p>



<p>These days, my fiancée and I play the Bee together most mornings during breakfast, trying to earn as many points as we can before heading off to work. (We&#8217;re just so wholesome!) Because we <em>really</em> enjoy word games and are almost guaranteed to reach Genius if we work together, our goal (though we rarely achieve it) is always Queen Bee.</p>



<p>The thing about pushing for Queen Bee, however, is knowing when to quit. Although the Times does not officially tell you this, we figured out a long time ago that the daily threshold for Genius is always 70% of the highest possible score.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="889" src="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.40.09 PM-1024x889.png" alt="" class="wp-image-1672" style="width:344px" srcset="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.40.09 PM-1024x889.png 1024w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.40.09 PM-300x260.png 300w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.40.09 PM-768x667.png 768w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.40.09 PM.png 1168w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>So we&#8217;ll usually do the math at some point and then use that number as either a motivator or a reason to cut our losses before the game stops being fun anymore.</p>



<p>The math, of course, is easy. We just open the calculator app on one of our phones, put in the value for Genius, and divide it by 0.7. But given that this is a well-defined task with well-defined inputs that we end up having to do every single time we play, doesn&#8217;t this sound like yet another perfect opportunity for some automation?</p>



<h2 class="wp-block-heading">The Objective</h2>



<p>I understand why The New York Times does not openly publish the number of points necessary to reach Queen Bee on any given puzzle. That would make perfection seem like the goal of the game—a goal that is too hard to reach on a daily basis to keep the game fun and casual.</p>



<p>But because of the way my partner and I play, it <em>would</em> be rather useful to have this number available to us at a glance. (This is especially true because we&#8217;re always forgetting the max score and having to find it again.)</p>



<p>My goal for a Spelling Bee automation project would therefore be to devise a way to have the Queen Bee score injected directly into the game&#8217;s user interface without our ever having to leave the browser—and ideally without any user intervention required.</p>



<h2 class="wp-block-heading">The Solution</h2>



<p>Arbitrarily modifying the appearance of a relatively static webpage is not, in principle, very hard to accomplish. </p>



<p>In fact, thanks to the demise of proprietary plugins like Adobe Flash, even the sleekest looking pages are typically rendered using plain text for, well, text; HTML tags for structure; and human-readable CSS rules for appearance/presentation. </p>



<p>And that means there&#8217;s very little that website owners can do to stop you from altering (on your own computer) a page&#8217;s information, design, or layout. </p>



<p>Things get a little harder if the page uses certain components of the HTML5 standard—particularly those designed for fancy graphics, multimedia, or interactive content—that are usually controlled via JavaScript. But otherwise, go to your favorite website, open up your browser&#8217;s developer panel, and you can tweak the text, HTML, and CSS to your heart&#8217;s content!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="243" src="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.41.59 PM-1024x243.png" alt="" class="wp-image-1673" srcset="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.41.59 PM-1024x243.png 1024w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.41.59 PM-300x71.png 300w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.41.59 PM-768x182.png 768w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.41.59 PM-1536x364.png 1536w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.41.59 PM-2048x485.png 2048w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.41.59 PM-1600x379.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Spelling Bee does use plenty of JavaScript code behind the scenes to do things like configure the game board or judge whether a guessed word is a valid answer. However, it turns out that a lot of the basic layout—including the scoring legend—is still handled via plain old, easily manipulatable HTML and CSS.</p>



<p>That&#8217;s great, but the only way to actually <em>do</em> this manipulation (without having to hand-edit the source code every single time) would be to write some JavaScript of my own.</p>



<p>With that in mind, to achieve the goals of this project, I would ultimately have to do the following:</p>



<ul class="wp-block-list">
<li>Figure out where Spelling Bee stores its scoring information.</li>



<li>Write some JavaScript to either (a) grab the Queen Bee score from wherever it might be hiding or (b) grab the Genius score and do the math to convert it to Queen Bee.</li>



<li>Write some more JavaScript to format the Queen Bee score to look like all the other ranks in the scoring legend and then insert it into the list.</li>



<li>Figure out an easy/reliable way to execute all this JavaScript—preferably without user intervention.</li>
</ul>



<h2 class="wp-block-heading">The Outcome</h2>



<p>The actual solution was pretty simple—around 70 lines of code, including comments and extra spaces for readability. However, there were a few interesting challenges.</p>



<p>For starters, even though I was able to figure out where Spelling Bee stores its answer key (something I definitely did <em>not</em> want to know ?), I could not find the maximum score encoded anywhere. So I would have to resort to having my code grab the Genius score and do the math. No biggie.</p>



<p>The second challenge, however, was that the scoring legend appears to be built dynamically whenever the user requests it. In other words, when the page is first loaded, neither the legend nor its data is anywhere to be found. And when the legend is dismissed, rather than simply making the box invisible, the underlying web app completely removes it from the page. This meant I would have to come up with a way to grab the Genius score, calculate Queen Bee, and then insert that new score <em>each time</em> the user opens up the legend—since then and only then is the content available for manipulation.</p>



<p>After doing some research, I learned that most browsers released in the past 10 years support a JavaScript feature called MutationObserver, which can trigger a block of code as soon as something about a particular element in the page structure changes. One such change is the addition of a new &#8220;child&#8221; to a container. In the case of Spelling Bee, I just had to configure a MutationObserver to watch a specific <code>&lt;div&gt;</code> element and call a function containing my code as soon as the legend appeared inside it.</p>



<p>The final problem to solve was the question of how to actually run this code. My first idea was something called a <em>bookmarklet</em>, which is essentially a bunch of JavaScript smushed into a hyperlink that you can keep in your browser&#8217;s toolbar or Bookmarks menu.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="186" height="60" src="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.43.12 PM.png" alt="" class="wp-image-1674" style="width:106px;height:auto"/></figure></div>


<p>When you click or tap on a bookmarklet, the browser executes the code in the context of the current webpage. This solution worked, but it came with a major downside: I would have to manually run the bookmarklet every single time I opened the Spelling Bee—and then re-run it if the browser decided to refresh the page.</p>



<p>What I really needed was a way to force some code to run <em>every time</em> a page loads, <em>as soon as</em> it loads. It eventually occurred to me that this is <em>exactly</em> one of the problems that browser extensions are intended to solve. These days, extensions are created using HTML, CSS, and JavaScript just like websites. Google created a model API for use in its Chrome browser; Mozilla, Microsoft, and Apple all eventually followed with the same or similar implementations.</p>



<p>I had never tried this before, but since I already had some working JavaScript, I figured it couldn&#8217;t be too much more trouble to bundle it into an extension. So I read some of Google&#8217;s <a href="https://developer.chrome.com/docs/extensions/mv3/" data-type="link" data-id="https://developer.chrome.com/docs/extensions/mv3/" target="_blank" rel="noreferrer noopener">documentation</a> and then, since I ultimately wanted this to work on my iPhone, I followed Apple&#8217;s <a href="https://developer.apple.com/documentation/safariservices/safari_web_extensions/creating_a_safari_web_extension" data-type="link" data-id="https://developer.apple.com/documentation/safariservices/safari_web_extensions/creating_a_safari_web_extension" target="_blank" rel="noreferrer noopener">instructions</a> for creating a Safari Web Extension.</p>



<p>Lo and behold, after installing my newly minted extension and giving it permission to access The New York Times, I <em>finally</em> had a solution that met all of my objectives.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="901" src="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.38.38 PM-1024x901.png" alt="" class="wp-image-1671" style="width:344px;height:auto" srcset="https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.38.38 PM-1024x901.png 1024w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.38.38 PM-300x264.png 300w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.38.38 PM-768x676.png 768w, https://teachernerd.com/wp-content/uploads/2023/11/Screenshot-2023-11-14-at-9.38.38 PM.png 1182w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>Now, whenever I am playing the Spelling Bee, I can open up the scoring legend and see what it will take to reach Queen Bee right at the top of the list. And in order to preserve some of the magic of the unadulterated game, my extension can even be configured to hide the maximum score until <em>after</em> genius has been achieved!</p>



<h2 class="wp-block-heading">The Takeaway</h2>



<p>Here&#8217;s the JavaScript for performing the necessary page manipulation. (Note: The code, as written below, will <em>always</em> show the Queen Bee score once it has been executed.)</p>



<pre class="wp-block-code"><code>// ==UserScript==
// @name        Bee Royal
// @match       *://www.nytimes.com/puzzles/spelling-bee
// @match       *://www.nytimes.com/puzzles/spelling-bee/*
// @grant       none
// @version     1.0
// @author      teacherdan
// @description Adds the number of points needed to reach \"Queen Bee\" status to the scoring legend when playing the Spelling Bee game from the New York Times.
// ==/UserScript==

// Function to add Queen Bee (e.g. total possible points) to the scoring legend
const addQueen = () => {
    // Grab the Genius score from the legend and use it to calculate Queen Bee
    const genius = document.querySelectorAll(".sb-modal-frame.ranks .sb-modal-ranks__rank-points")&#91;1].innerText;
    const queen = Math.round(genius / 0.7);
    
    // Grab the current score from the legend and use it to calculate points-to-go
    const current = document.querySelectorAll(".sb-modal-frame.ranks .current-score")&#91;0].innerText;
    const diff = queen - current;
    
    // Create a new table row containing the Queen Bee value
    let queenRow = document.createElement('tr');
    queenRow.innerHTML = '&lt;td class="sb-modal-ranks__rank-marker">&lt;div class="square">&lt;/div>&lt;/td>&lt;td class="sb-modal-ranks__rank-title">&lt;span class="current-rank">Queen Bee&lt;/span>&lt;/td>&lt;td class="sb-modal-ranks__spacer hr">&lt;/td>&lt;td class="sb-modal-ranks__rank-points">' + queen + '&lt;/td>';
    
    // Insert the new row at the top of the scoring legend
    let scoreList = document.querySelector(".sb-modal-frame.ranks tbody");
    scoreList.insertBefore(queenRow, scoreList.firstChild);
    
    // Update Genius subtext
    if (playerIsGenius()) {
        let subtext = document.querySelector(".sb-modal-frame.ranks .sub-text");
        subtext.innerText = diff + " points to go!";
        subtext.style.display = "block";
    }
}

// Checks whether current player is a genius
const playerIsGenius = () => {
    return document.querySelector(".current-rank").innerText == "Genius";
}

// MutationObserver callback function that will be executed whenever
// a new modal dialog (such as scoring legend) has been added to the UI
const newModalCallback = (mutationList, observer) => {
    
    // Loop through all the mutations we've received
    for (const mutation of mutationList) {
        
        // Only respond to child list mutations
        if (mutation.type === "childList") {
    
            // Do the manipulation!
            addQueen();
        }
    }
};

// Create a MutationObserver linked to the callback function
const modalObserver = new MutationObserver(newModalCallback);

// Find the DIV used by the game for displaying modal dialogs (including the scoring legend)
// and observe it for changes to its child list (e.g. dialogs appearing/disappearing)
window.onload = () => {
    const modalWrapper = document.querySelector(".sb-modal-wrapper");
    console.log(modalWrapper);
    modalObserver.observe(modalWrapper, {
    childList: true
    });
}</code></pre>



<p>And here&#8217;s that same code as a bookmarklet you can drag to your toolbar or add to your Bookmarks menu: <a href="javascript:%22use%20strict%22;void%20function(){const%20a=()=%3E{var%20a=Math.round;const%20c=document.querySelectorAll(%22.sb-modal-frame.ranks%20.sb-modal-ranks__rank-points%22)[1].innerText,d=a(c/.7),e=document.querySelectorAll(%22.sb-modal-frame.ranks%20.current-score%22)[0].innerText;let%20f=document.createElement(%22tr%22);f.innerHTML=%22%3Ctd%20class=\%22sb-modal-ranks__rank-marker\%22%3E%3Cdiv%20class=\%22square\%22%3E%3C/div%3E%3C/td%3E%3Ctd%20class=\%22sb-modal-ranks__rank-title\%22%3E%3Cspan%20class=\%22current-rank\%22%3EQueen%20Bee%3C/span%3E%3C/td%3E%3Ctd%20class=\%22sb-modal-ranks__spacer%20hr\%22%3E%3C/td%3E%3Ctd%20class=\%22sb-modal-ranks__rank-points\%22%3E%22+d+%22%3C/td%3E%22;let%20g=document.querySelector(%22.sb-modal-frame.ranks%20tbody%22);if(g.insertBefore(f,g.firstChild),b()){let%20a=document.querySelector(%22.sb-modal-frame.ranks%20.sub-text%22);a.innerText=d-e+%22%20points%20to%20go!%22,a.style.display=%22block%22}},b=()=%3E%22Genius%22==document.querySelector(%22.current-rank%22).innerText,c=new%20MutationObserver(b=%3E{for(const%20c%20of%20b)%22childList%22===c.type%26%26a()}),d=document.querySelector(%22.sb-modal-wrapper%22);c.observe(d,{childList:!0})}();" data-type="link" data-id="javascript:void%20function(){const%20a=()=%3E{let%20a=document.querySelectorAll(%22.sb-modal-frame.ranks%20.sb-modal-ranks__rank-points%22)[1].innerText,b=Math.round(a/.7),c=document.createElement(%22tr%22);c.innerHTML=%22%3Ctd%20class=\%22sb-modal-ranks__rank-marker\%22%3E%3Cdiv%20class=\%22square\%22%3E%3C/div%3E%3C/td%3E%3Ctd%20class=\%22sb-modal-ranks__rank-title\%22%3E%3Cspan%20class=\%22current-rank\%22%3EQueen%20Bee%3C/span%3E%3C/td%3E%3Ctd%20class=\%22sb-modal-ranks__spacer%20hr\%22%3E%3C/td%3E%3Ctd%20class=\%22sb-modal-ranks__rank-points\%22%3E%22+b+%22%3C/td%3E%22;let%20d=document.querySelector(%22.sb-modal-frame.ranks%20tbody%22);d.insertBefore(c,d.firstChild)},b=new%20MutationObserver(b=%3E{for(const%20c%20of%20b)%22childList%22===c.type%26%26a()}),c=document.querySelector(%22.sb-modal-wrapper%22);b.observe(c,{childList:!0})}();">Bee Royal</a>. (If you&#8217;d prefer, for security reasons, to create your own bookmarklet, you can paste my code into a generator. <a href="https://chriszarate.github.io/bookmarkleter/" data-type="link" data-id="https://chriszarate.github.io/bookmarkleter/">This</a> is the one that I used.)</p>



<p>Now, I wish I could share my final product—the automatically activating, configurable extension. Unfortunately, Safari extensions can only be installed from Apple&#8217;s App Store, and this is just a hobby project that I&#8217;m not prepared to officially support. (Although there are workarounds, the other major browsers have similar restrictions these days.)</p>



<p>There is, however, one other option. Instead of using a bookmarklet, you could install something called a user script manager, which is basically an extension that allow you to automatically run arbitrary, third-party code, either on specific webpages (what we need here) or even potentially <em>all </em>pages. <a href="https://greasyfork.org/en" data-type="link" data-id="https://greasyfork.org/en" target="_blank" rel="noreferrer noopener">Greasy Fork</a> links to a few options you might consider. I can&#8217;t vouch for any of these extensions&#8217; safety, privacy, or security practices, but I did confirm that they are able to run my JavaScript solution.</p>



<p>Instructions for using a script manager are beyond the scope of this article, but you are welcome to copy and paste my code into your chosen extension. I&#8217;ve even already included the necessary metadata to make sure things go as smoothly as possible!</p>



<h2 class="wp-block-heading">Wrapping Up</h2>



<p>As always, thank you for following along on this journey toward orthographic royalty. I look forward to additional automation and/or scripting projects in the future!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Constructing Reality, or Breaking the Rules?</title>
		<link>https://teachernerd.com/2023/10/28/constructing-reality-or-breaking-the-rules/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Sat, 28 Oct 2023 22:28:43 +0000</pubDate>
				<category><![CDATA[Essays]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[photojournalism]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?p=1632</guid>

					<description><![CDATA[AI-powered photo editing tools built into some of the latest smartphones, including the newly released Google Pixel 8 series, give us the ever-increasing ability to showcase our own versions of reality. Photography, as an extension of portraiture, has always been a “constructed” medium, so what makes these features feel so problematic? Is it all a bit of an overreaction? Let’s explore!]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="683" src="https://teachernerd.com/wp-content/uploads/2023/10/0W5A0542-2.jpg" alt="" class="wp-image-1640" srcset="https://teachernerd.com/wp-content/uploads/2023/10/0W5A0542-2.jpg 1024w, https://teachernerd.com/wp-content/uploads/2023/10/0W5A0542-2-300x200.jpg 300w, https://teachernerd.com/wp-content/uploads/2023/10/0W5A0542-2-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>My fiancée and I watch very little live television. One major exception, however, is the MLB postseason—provided that either the Phillies, New York Mets, or Washington Nationals have made it to the playoffs. Truth be told, this doesn’t happen all that frequently, so even then we watch very little live TV.</p>



<p>But when the stars do line up just right, not only do we get to experience the excitement (yes, I said it!) of <em>multiple</em> games of baseball; we also get to feast our eyes, ears, and brains on that most surreal form of secondary entertainment known as <em>commercials.</em></p>



<p>Two things stood out as I watched this year’s fare: (1) Musical numbers (some knowingly tongue-in-cheek and others missed-the-memo earnest) are apparently in vogue, and (2) smartphones—and in particular, smartphone cameras—are becoming increasingly creepy.</p>



<p>I’m speaking, of course, about the Pixel 8 series, which Google <a href="https://www.theverge.com/2023/10/4/23895660/google-pixel-8-event-news-roundup" data-type="link" data-id="https://www.theverge.com/2023/10/4/23895660/google-pixel-8-event-news-roundup">launched</a> in early October, just as the Wild Card round was getting started. As the commercials were happy to inform us—backed up by cool, techno vibes—these phones are packed full of AI-enhanced photo editing features.</p>



<h2 class="wp-block-heading">Cause for Alarm?</h2>



<p>Now, I should pause for a moment and note that artificial intelligence and machine learning have played a role in digital image processing for some time now. Apple, for instance, uses “<a href="https://www.apple.com/newsroom/2019/09/apple-introduces-dual-camera-iphone-11/">Deep Fusion</a>” to optimize photos; Canon does something similar with “<a href="https://global.canon/en/technology/dl-iptechnology-2023.html">deep learning</a>.&#8221; For the most part, we don’t dwell on the calculations our phones and cameras perform under the hood. But the thing that kept freaking me out, commercial break after commercial break, was a new user-facing feature that Google has named “<a href="https://www.androidauthority.com/google-photos-best-take-3380022/" data-type="link" data-id="https://www.androidauthority.com/google-photos-best-take-3380022/">Best Take</a>.”</p>



<p>As demonstrated in the advertisements, the feature allows you to take several photos in short succession and then create one “perfect” image by choosing the best face for each subject. It’s a great way to correct for family members that won’t stay still or that one friend who was blinking in every photo except for the one where you’re mid-sneeze. Instagram never looked so good!</p>



<p><em>The Washington Post</em>’s Geoffrey A. Fowler <a href="https://www.washingtonpost.com/technology/2023/10/11/ai-face-google-best-take/">sums up my discomfort</a> when he asks, “Is this a line we want to cross?” He explains the deeper issue like this:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>As much as I enjoyed using [Best Take], there’s an uneasy casualness about letting AI edit the faces in the smartphone photos we rely on to archive our memories. It’s allowing AI to help standardize ideas about what happiness looks like—an escalation of the cultural pressure we’ve been grappling with on social media to curate smiling faces and perfect places that don’t always reflect reality.</p>
</blockquote>



<p>The column goes on to grapple, somewhat ambivalently, with the question of “How fake is too fake?” Like me, Fowler considers the role that software and algorithms have long played in photography, but he also raises fair concerns about slippery slopes and sexism, ultimately wondering aloud what the purpose of a photograph should even be. Is it a “record of a moment,” as Fowler puts it, or something else?</p>



<h2 class="wp-block-heading">The Classroom Perspective</h2>



<p>As someone who has taught photojournalism to high school students for around 13 years, I could not help but let this question sit with me for a while. Why <em>do</em> we create and share photos, let alone publish them in newspapers?</p>



<p>When I pose this question to my students, the consensus they usually settle on is that photos allow us to capture the reality of a particular point in time in a way that feels somehow “more real” or, at the very least, <em>augments</em> the written/spoken word.</p>



<p>We’ll look at Pulitzer Prize-winning photos together—moments of victory, tragedy, and everything in between—and talk about how the angle, the framing, the lighting, or even just being in the right place at the right time and having the wherewithal to push the button leads to a scene packed with the kind of imagery—action and emotion—that an English major could only dream of conveying.</p>



<p>But therein lies the rub. These most celebrated of images are each a bundle of choices—even if the only conscious choice was to plant oneself in a particular spot on a particular day. Ultimately, as much as we like to talk about “capturing” a scene, photos are (and have always been) something we <em>create.</em></p>



<p>In subsequent classes, I’ll teach my students about the exposure triangle—how they can use the combination of shutter speed, aperture, and sensitivity to control things like the perception of motion, how much of a scene is in focus, and how light or dark an image is. An expert photographer might adjust these settings manually. A beginner may choose to shoot on “fully automatic” mode, but that doesn’t make the choices go away. The decisions are just being delegated to the machine. (Even an old-school, disposable film camera without a single piece of electronics inside has had the exposure parameters predetermined at the time of manufacture, and those parameters will still shape the appearance of the developed photo.)</p>



<p>One might try to imagine a world where there are no such mechanical considerations to be made—where what you see is simply what you get. Besides the fact that even our own eyes don’t work that way, that notion quickly fades once my students and I begin to discuss <em>composition</em>—how photographers (deliberately or not) make use of techniques like the rule of thirds and leading lines that subtly tell viewers what to look at, how, and when. We’ll talk about how the location of the camera—things like bird’s eye and worm’s eye view—can change our perception of a person’s size or power.</p>



<p>I love photography, so I could go on and on. (Don’t my students know it!) The point is that even when done in the service of journalism, a pursuit for which the central conceit is the primacy of truth, photography is at its heart artificial.</p>



<h2 class="wp-block-heading">Creative Visions</h2>



<p>We haven’t even begun to talk about portraiture. From the first moment some cave dweller smudged some dirt on a wall, we humans have been creating <em>representations </em>of the world around us. Walk through any art museum, and you’ll see paintings created to showcase this or that aspect of a person or a scene through the choice of medium, pigments, brushstrokes, and so forth, not to mention the complete control the artist has over what we see, what we don’t see, how large to make a person’s hip, etc., etc.</p>



<p>Portrait photography is really not so different. Whether in a studio or at a party, the photographer’s job is to capture the essence of one or more individuals and/or the scene around them. A wedding portrait may have the couple positioned just so with the lighting just right to portray their everlasting love for one another. A photo of a bunch of kids saying, “Cheese!” at a birthday party perhaps wishes to capture how gosh darn fun it is to be 7!</p>



<p>So is it really such a crime to use an algorithm to blend five images together so that everyone is happily looking at the camera if the whole point is to capture not just what the moment looks like but what it <em>feels</em> like—or even what we may <em>want</em> it to feel like?</p>



<p>Fowler’s column lingers on the opportunities for abuse, if not of this technology then its successors. But then again, as Jay Peters at <em>The Verge</em> <a href="https://www.theverge.com/2023/10/7/23906753/google-pixel-8-pro-photo-editing-tools-ai">points out</a>, we’ve been manipulating photos almost as long as there have been photos to manipulate. (AI makes it a lot easier now, but the risk has always been there.)</p>



<p>What is it, then, that makes “Best Take” feel so different to me? Perhaps it’s the implied act of dissemblance—this sense that rather than just passing an image through a filter, we’re being given permission to <em>pretend</em> that a scene that we constructed from discrete parts (much like a LEGO model) equates to what we actually remember seeing in the viewfinder. What may be entirely natural to do with paint on canvas seems, in the end, subversive in a photograph.</p>



<p>Or, as Matt Bai <a href="https://www.washingtonpost.com/opinions/2023/10/31/google-pixel-ad-campaign-smartphone-misinformation-reality/" data-type="link" data-id="https://www.washingtonpost.com/opinions/2023/10/31/google-pixel-ad-campaign-smartphone-misinformation-reality/">puts it</a> in his own <em>Washington Post</em> column, &#8220;It matters how we portray truth.&#8221; Writing about the entire range of &#8220;fun&#8221; new AI features users have access to, Bai goes on to point out the impracticality of trying to stop this technology. However, he adds, ominously:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>But to make the explicit selling point of that phone the notion that imperfect truths don’t need to exist anymore—that what’s real is both fungible and subjective—strikes me as reckless. It romanticizes the most destabilizing trend in society and invites us all to revel in it.</p>
</blockquote>



<p>Any neuroscientist will tell you that memory is malleable—even fallible. If our own perception of past reality can—and likely will—change over time, then there&#8217;s a part of me (albeit small) that wonders whether achieving a level of memorial perfection in photography even matters. Physicists, meanwhile, will tell you about the “observer effect”—the notion that the very act of observing a system will inherently change it. Bai&#8217;s larger political point notwithstanding, this poses a far deeper question: is it even <em>possible</em> to capture an “accurate” moment in time?</p>



<p>Maybe, as new tech often has the potential to do, what the Pixel 8 really inspires within me and the writers I&#8217;ve cited above is just good old fear of change—combined, in my own case, with my household’s disappointment over the Phillies’ loss in Game 7 of the NLCS.</p>



<p>I’m still undecided (about “Best Take,” not the unfairness of the baseball universe). But it is at least comforting to remember that, in a way, artificial intelligence in visual media is nothing new. Portraiture and photography have <em>always</em> been rooted in artifice. For better or for worse, we creators just have a lot more tools at our disposal now.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>On the Merge of Something Awesome</title>
		<link>https://teachernerd.com/2023/09/23/on-the-merge-of-something-awesome/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Sat, 23 Sep 2023 22:58:12 +0000</pubDate>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[scripting]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?p=1581</guid>

					<description><![CDATA[I recently detailed a technique for auto-generating a slideshow in Adobe InDesign using data from a spreadsheet. (This is great for awards ceremonies!) But wouldn't it be cool if there were a way to do this completely within the "free" Google ecosystem? By using a tool called Google Apps Script, I determined that you can, in fact, accomplish the same thing with Google Sheets and Google Slides.]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">The Background</h2>



<p>Just a few days ago, I posted a <a href="https://teachernerd.com/2023/09/19/how-to-generate-an-awards-slideshow-using-a-spreadsheet-and-indesign/" data-type="link" data-id="https://teachernerd.com/2023/09/19/how-to-generate-an-awards-slideshow-using-a-spreadsheet-and-indesign/">tutorial</a> explaining how you can use a spreadsheet app combined with Adobe InDesign to generate a slideshow based on a template.</p>



<p>I had previously used this technique when I had to create a presentation featuring the name and photo of 100+ students to play during a virtual induction ceremony for my school&#8217;s National Honor Society chapter.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/excel-to-indesign-1024x530.png" alt="" class="wp-image-1589" style="width:308px;height:159px" width="308" height="159" srcset="https://teachernerd.com/wp-content/uploads/2023/09/excel-to-indesign-1024x530.png 1024w, https://teachernerd.com/wp-content/uploads/2023/09/excel-to-indesign-300x155.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/excel-to-indesign-768x397.png 768w, https://teachernerd.com/wp-content/uploads/2023/09/excel-to-indesign-1536x794.png 1536w, https://teachernerd.com/wp-content/uploads/2023/09/excel-to-indesign-1600x827.png 1600w, https://teachernerd.com/wp-content/uploads/2023/09/excel-to-indesign.png 1980w" sizes="auto, (max-width: 308px) 100vw, 308px" /></figure></div>


<p>Rather than having to create all 100+ slides by hand, I could automate the most tedious part of the job by making use of InDesign&#8217;s built-in <em>Data Merge</em> feature.</p>



<p>Similar to a <a href="https://teachernerd.com/2020/06/23/how-to-send-personalized-mass-emails-in-microsoft-office/" data-type="link" data-id="https://teachernerd.com/2020/06/23/how-to-send-personalized-mass-emails-in-microsoft-office/">mail merge</a> in Microsoft Word, this feature allows you to create a template, import a data table from your spreadsheet, and then link each of the table&#8217;s columns to a placeholder on the template. Then, with the click of a button, InDesign can create a new file containing a page (or, in this case, a slide) for each row of the table.</p>



<h2 class="wp-block-heading">The Problem</h2>



<p>One of the coolest aspects of InDesign&#8217;s Data Merge is that it can handle image frames in addition to text boxes, so it really is perfect for my particular use case (i.e. awards slideshows).</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-12.05.01-PM.png" alt="" class="wp-image-1552" style="width:218px;height:227px" width="218" height="227" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-12.05.01-PM.png 504w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-12.05.01-PM-287x300.png 287w" sizes="auto, (max-width: 218px) 100vw, 218px" /></figure></div>


<p>That said, there is one major downside: as cool as I think the technique may be, it does still require Adobe InDesign—and for many people, that&#8217;s going to be a showstopper.</p>



<p>For those who may be unfamiliar, InDesign is a professional desktop publishing app. I&#8217;ve been using it (and teaching students how to use it) for over a decade, so the interface is second nature to me, but it can definitely be overwhelming for someone whose word processing and graphic design experience is limited to the Microsoft or Google office suites.</p>



<p>InDesign also requires a<a rel="noreferrer noopener" href="https://www.adobe.com/creativecloud/plans.html" data-type="link" data-id="https://www.adobe.com/creativecloud/plans.html" target="_blank"> subscription</a> if you want to use it beyond the seven-day free trial. Regular users have to pay $20.99 per month while students and teachers can access the entire Adobe Creative Suite for $19.99 per month. That&#8217;s actually a pretty good deal if you also need access to things like Photoshop or Lightroom, but that&#8217;s still not exactly cheap. </p>



<p>Meanwhile, Google Slides (along with the rest of Google&#8217;s office suite) is easy to use, ubiquitous, and essentially free for personal use. (I say &#8220;essentially&#8221; because, well, it&#8217;s Google. You&#8217;re &#8220;paying&#8221; for their services by giving up tons and tons of data and personal information&#8230;but I digress&#8230;) It&#8217;s also already being used by tons of school systems as part of a seemingly diabolical plan to&#8230;er, let&#8217;s just move on&#8230;</p>



<h2 class="wp-block-heading">The Objective</h2>



<p>I won&#8217;t quite call it the Holy Grail of slideshow automation, but I do think it would be even more cool if there were a way to auto-generate a slide deck from a spreadsheet <em>without</em> resorting to InDesign—bonus points if it could be done completely within the &#8220;free&#8221; Google ecosystem.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/sheets-to-slides-1024x530.png" alt="" class="wp-image-1590" style="width:308px" width="308" srcset="https://teachernerd.com/wp-content/uploads/2023/09/sheets-to-slides-1024x530.png 1024w, https://teachernerd.com/wp-content/uploads/2023/09/sheets-to-slides-300x155.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/sheets-to-slides-768x397.png 768w, https://teachernerd.com/wp-content/uploads/2023/09/sheets-to-slides-1536x794.png 1536w, https://teachernerd.com/wp-content/uploads/2023/09/sheets-to-slides-1600x827.png 1600w, https://teachernerd.com/wp-content/uploads/2023/09/sheets-to-slides.png 1980w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<h2 class="wp-block-heading">The Solution</h2>



<p>Let&#8217;s get this out of the way right now: Google Slides does not have a built-in data merge feature. However, because Google would very much like to sell subscriptions of its non-free, enterprise-grade Google Workspace service to all the world&#8217;s businesses, they <em>have</em>, in fact, developed a number of powerful automation features. They&#8217;re just not particularly obvious to mere mortals.</p>



<p>One of these features is something called <a rel="noreferrer noopener" href="https://www.google.com/script/start/" data-type="link" data-id="https://www.google.com/script/start/" target="_blank">Google Apps Script</a>, a system for writing your own sort of mini-applications that live in the cloud and can interact with the various components of the Google suite.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-23-at-6.05.56-PM.png" alt="" class="wp-image-1597" style="width:473px" width="473" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-23-at-6.05.56-PM.png 2890w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-23-at-6.05.56-PM-300x207.png 300w" sizes="(max-width: 2890px) 100vw, 2890px" /></figure></div>


<p>Solutions written in Google Apps Script are kind of like <em>macros</em>, automations that have long been part of Microsoft Office and similar desktop applications.</p>



<p>(Fun fact: Macros have picked up something of a bad reputation in recent decades since they are a prime attack vector for distributing viruses and other malware. Even though Microsoft Office now blocks them by default in files downloaded from the internet, they remain a significant tool available to power users and enterprises.)</p>



<p>Whereas a macro for Microsoft Word or Excel can be written in a language called Visual Basic for Applications, Google Apps Scripts are written in a language based on JavaScript. And since JavaScript is <em>the</em> language for front-end web development, it should be pretty easy for someone with a little bit of modern programming knowledge to jump right into Apps Script development! (Oh boy, I&#8217;m starting to sound like a salesperson. Maybe that diabolical plan is really working&#8230;)</p>



<p>As it turns out, I do have some prior experience using Google Apps Script to generate files from a template, so I definitely had a hunch that something similar could be done to merge data into Google Slides.</p>



<p>Then, while doing some research for my InDesign blog post, I came across a website called <a rel="noreferrer noopener" href="https://spreadsheet.dev/" target="_blank">Spreadsheet Dev</a>. Written by a guy who, much like me, <a rel="noreferrer noopener" href="https://spreadsheet.dev/about" data-type="link" data-id="https://spreadsheet.dev/about" target="_blank">identifies</a> as both a developer and a teacher, the site&#8217;s goal is to &#8220;teach spreadsheet users to code using Google Sheets and Apps Script.&#8221; This author has written some great tutorials, but the one that really caught my eye was this: &#8220;<a rel="noreferrer noopener" href="https://spreadsheet.dev/convert-each-row-google-sheets-into-slide-google-slides-apps-script" data-type="link" data-id="https://spreadsheet.dev/convert-each-row-google-sheets-into-slide-google-slides-apps-script" target="_blank">Convert each row in Google Sheets into a slide in Google Slides using Apps Script</a>.&#8221;</p>



<p>As you may be able to tell from the title, the script from this tutorial does almost <em>exactly</em> what I&#8217;ve set out to do here. The author also did a great job adding comments to his code so that you can understand the purpose of each line. That tutorial and all the earlier ones it links to are honestly a great way to learn about Google app automation. If you have any interest in this subject, I encourage you to take a look!</p>



<p>But, useful though that article may have been for my research, it was not <em>exactly</em> what I wanted for my solution. For one thing, I realized that all the field names were hard-coded into the example script. This meant that the script would have to be revised, based on the specific nature of the data, each time someone wanted to use it for a new project. A reference to the slideshow being used as the template was also hard-coded; a piece of the template&#8217;s URL would have to be pasted in for each new presentation. And perhaps most significantly, the script was not designed to handle a data merge with images, which meant it would not be usable for any future award ceremony slideshows.</p>



<p>Nevertheless, by reading that article, I now had a basic outline for how to handle data merges in Google-land. The process didn&#8217;t seem too off-the-wall, so I felt pretty confident that it would be possible to write my <em>own</em> script that could handle both text and images while also being flexible enough to work with all kinds of templates and data sets. </p>



<h2 class="wp-block-heading">The Outcome</h2>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-23-at-6.42.12-PM-1024x707.png" alt="" class="wp-image-1598" style="width:473px" width="473" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-23-at-6.42.12-PM-1024x707.png 1024w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-23-at-6.42.12-PM-300x207.png 300w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>I spent some time reading the Google Apps Script <a rel="noreferrer noopener" href="https://developers.google.com/apps-script/reference" data-type="link" data-id="https://developers.google.com/apps-script/reference" target="_blank">documentation</a>, mostly to figure out whether it&#8217;s even possible to manipulate images in Google Slides via script (it is), and subsequently, how to actually do it.</p>



<p>However, an interesting challenge that I ran into is that Google Slides doesn&#8217;t really allow you to add an empty image frame to a slide. I also wasn&#8217;t sure at first how I could designate a particular image to be replaced by a particular column from the spreadsheet. The solution I eventually came to was to just put a dummy image on the page and then add the field name from the spreadsheet as the image&#8217;s ALT text. (It&#8217;s a hack, but it works. See below for more info.)</p>



<p>I also discovered that Google Apps Script does not have a convenient, built-in way to display a document picker to the user. So in order to maintain my goal of not having any specific files or locations hard-coded into the script, I had to resort to using <em>predictable</em> files/folders rather than <em>pickable</em> files/folders. (It just means you have to give things certain names and put them in the right place. I still think that&#8217;s easier than editing the script each time.)</p>



<p>These small limitations notwithstanding, the script I created works almost exactly like my InDesign-based solution. You start by creating a template slide with {{placeholder}} tags wherever you need dynamic data. Then, you put all your data into a spreadsheet with column names that match those tags. Finally, you run the script and—<em>voilà</em>—you have a slideshow!</p>



<h2 class="wp-block-heading">The Takeaway</h2>



<p>If using custom code to get a job done feels a little unsettling, even if all you need to do is copy and paste that code without editing it, fear not: there are pre-written add-ons available in the <a rel="noreferrer noopener" href="https://workspace.google.com/u/1/marketplace" data-type="link" data-id="https://workspace.google.com/u/1/marketplace" target="_blank">Google Workspace Marketplace</a> that can handle data merges and presumably do other fancy things, no coding required.</p>



<p>Personally, I like using my own code whenever possible because I can see exactly what it does and not have to wonder what the app/developers might be doing with my data behind the scenes. So even if there are free add-ons out there that have <em>already</em> been written by other people, I&#8217;m more comfortable using my home-brewed solution. And if you&#8217;d like to use it too, then I invite you to keep reading!</p>



<h3 class="wp-block-heading">The Script</h3>



<p>So, first things first, here&#8217;s the actual script I created:</p>



<pre class="wp-block-code"><code>// This function loops through each row of the sheet and performs the data merge
function createDeckViaDataMerge() {

  // Get the folder containing the spreadsheet
  let sheetId = SpreadsheetApp.getActive().getId()
  let parentFolder = DriveApp.getFileById(sheetId).getParents().next()
  
  // Get the template file from the folder
  let templateFile = getTemplateFile(parentFolder)

  // Exit the script if we couldn't find a template
  if (templateFile == null) {
    Logger.log("Error: Could not find template!")
    return
  }

  // Create a new file and retrieve the template slide from it
  let templateSlide = getTemplateFromNewFile(templateFile)

  // Exit the script if we couldn't retrieve a template (i.e. file contained no slides)
  if (templateSlide == null) {
    Logger.log("Error: Template is empty!")
    return
  }

  // Retrieve the contents of the spreadsheet
  let spreadsheetData = SpreadsheetApp.getActive().getDataRange().getValues()

  // Separate the column labels from the rest of the sheet
  let columnLabels = spreadsheetData.shift();

  // Reverse the order of the remaining rows so that slideshow appears in correct order
  let rows = spreadsheetData.reverse();

  // For every row, create a new slide by duplicating the template slide
  // and replace the template variables with data from that row.
  rows.forEach(function (row) {

    // Create a duplicate of the template slide at the beginning of deck
    let slide = templateSlide.duplicate();
    
    // Loop through the fields to make replacements
    columnLabels.forEach(function (fieldName, index) {
      
      // Process field based on whether its column holds text or a photo filename
      if (isPhotoField(fieldName)) {
        
        // It looks like this is a photo field, so grab the filename from this column
        // of the current row.
        let fileName = row&#91;index]
        
        // Now, let's drop the image prefix ("#") from the field name
        let fieldNameWithoutPrefix = fieldName.substring(1)
        
        // Use the new filename and modified field name to attempt an image subsitution
        processFieldAsImage(slide, parentFolder, fieldNameWithoutPrefix, fileName)
      }

      else {
        // It looks like this is a regular text field, so grab the substitution text from this column of current row
        let newText = row&#91;index]

        // Now use that text to perform a substitution
        processFieldAsText(slide, fieldName, newText)
      }
    })    
  });

  // Remove the template slide from the final output
  templateSlide.remove()
}

// This function finds a file named "TEMPLATE" in the given folder and returns it
function getTemplateFile(folder) {
  
  // Look for slide decks with the name "TEMPLATE"
  let templateFiles = folder.getFilesByName("TEMPLATE")
  
  // If we found any template files, use them
  if (templateFiles.hasNext()) {
    
    // Return the first found template file
    return templateFiles.next()
  }

  // Return nothing if we couldn't find a template
  else {
    return null
  }
}

// This function duplicates the given template file and returns the first
// slide (i.e. the template slide)
function getTemplateFromNewFile(templateFile) {

  // Duplicate the template file  
  let newFile = templateFile.makeCopy()
  newFile.setName("Generated Slide Deck")

  // Open the new file
  let newDeck = SlidesApp.openById(newFile.getId())

  // Get the slides from this deck
  let slides = newDeck.getSlides()
  
  // If the deck has any slides, return the first one
  if (slides.length &gt; 0) {
    return slides&#91;0]
  }
  else {
    return null
  }
}

// This function replaces any text on the given slide that matches the field name
function processFieldAsText(slide, fieldName, newText) {
  
  // Use the fieldname to build the placeholder text (e.g. "{{fieldName}}") that we'll look for on the slide
  let placeholderText = "{{" + fieldName + "}}"

  // Do the replacement
  slide.replaceAllText(placeholderText, newText)
}

// This function checks whether the field name is preceded by a # symbol,
// in which case that field's column will be assumed to contain the names of image files.
function isPhotoField(fieldName) {
  return fieldName.substring(0,1) == "#"
}

// This function looks for a folder alongside the spreadsheet that matches the given field,
// and if it finds one, it tries to start the image replacement process.
function processFieldAsImage(slide, parentFolder, fieldName, fileName) {
  
  // Look for a folder inside the spreadsheet's folder that matches the given field name
  let matchingImageFolders = parentFolder.getFoldersByName(fieldName)

  // Proceed ONLY if we were able to find a match
  if (matchingImageFolders.hasNext()) {
    
    // Get the first folder from the set
    let imageFolder = matchingImageFolders.next()

    // We're looking for an image whose ALT text matches "{{fieldName}}",
    // so let's create a variable to hold that search string
    let placeholderText = "{{" + fieldName + "}}"

    // Handle the image replacement
    handleImageReplacement(slide, imageFolder, placeholderText, fileName)
  }
}

// This function looks for an image on the given slide whose ALT text matches
// the given placeholder text. If it finds one, it attempts a substitution.
function handleImageReplacement(slide, imageFolder, placeholderText, fileName) {

  // Get all the images from the template slide
  let slideImages = slide.getImages()

  // Loop through each of the images we just got
  slideImages.forEach(function (image) {

    // Check whether the current image's ALT text matches the placeholder text
    if (image.getDescription() == placeholderText) {

      // We found a match, so attempt to replace it
      replaceImage(image, imageFolder, fileName)
    }
  })
}

// This function looks for an image with the given filename in the provided folder.
// If it finds one, it replaces the provided image with the new one.
function replaceImage(oldImage, newImageFolder, fileName) {
        
  // Look for a photo in the folder with the given filename
  let foundImages = newImageFolder.getFilesByName(fileName)
  
  // Check whether we actually found any images that match the fileName
  if (foundImages.hasNext()) {
    
    // We foud a match, so let's get just the first one from the set
    let newImage = foundImages.next()

    // Replace the placeholder image with the new image
    oldImage.replace(newImage)
  }
}

function addMenuToSheet() {
  let menu = SpreadsheetApp.getUi().createMenu("Data Merge")
    .addItem("Do Merge", "createDeckViaDataMerge")
    .addToUi()
}

function onOpen() {
  addMenuToSheet()
}</code></pre>



<h3 class="wp-block-heading">What to do with it&#8230;</h3>



<p>Now, if you&#8217;d like to actually <em>use</em> that script, here&#8217;s how:</p>



<ol class="wp-block-list">
<li>Create a folder for your project in Google Drive. Call it whatever you&#8217;d like!</li>



<li>Create a Google Slides document with just a single slide. You can use a built-in design or a third-party template. Just make sure to put the document in that folder you created. And make sure the document is named <strong>TEMPLATE</strong>. (This is case-sensitive, so make sure it&#8217;s in all-caps.)</li>



<li>When designing your slide, any elements that will look the same on every slide (logos, boilerplate text, etc.) can be added the same way you would for a normal slide.</li>



<li>To add text that will change on each slide (like a student&#8217;s name or grade), create a placeholder tag like one of these: <strong><code>{{Name}}</code></strong> or <strong><code>{{First}} {{Last}}</code></strong> or <strong><code>{{Grade}}</code></strong>. (Your column names will vary depending on what your data looks like. Just make sure to include those curly braces.)</li>



<li>To add a photo or other image that will change on every slide, start by adding literally any image you want to the slide to serve as a dummy/placeholder. Just make sure to crop it to the actual shape/size you want on the final slides. (You could use one of your actual photos if you want to be certain the dimensions are correct.)
<ul class="wp-block-list">
<li>Now click on that image and choose &#8220;Format Options&#8221; from the toolbar. A sidebar should appear on the right side of the window. At the very bottom is a section labeled &#8220;Alt Text,&#8221; and in that section is a box labeled &#8220;Description.&#8221; Type a placeholder tag (e.g. <strong><code>{{Photo}}</code> </strong>or <strong><code>{{Portrait}}</code> </strong>or some other relevant name) into that box. Be sure to include the curly braces!</li>



<li>Next, create a folder in Google Drive with the same name as the placeholder tag (e.g. <strong><code>Photo</code></strong> or <strong><code>Portrait</code></strong>—but this time no curly braces). Make sure this folder is in the same parent folder as the template. Then, add, move, or upload the relevant images into that folder. (You can create more than one folder if you have multiple placeholders.)</li>
</ul>
</li>



<li>If you already have a data spreadsheet, upload it or move it into the folder. Otherwise, create a new one. Make sure the column names for any dynamic text, like student names or grades, match your placeholder tags exactly (but without the curly braces).</li>



<li>If your template includes any placeholders for images, make sure they each have a column in your spreadsheet. 
<ul class="wp-block-list">
<li>For the column name, use a pound sign (<strong>#</strong>) followed by the name of the folder you added the relevant images to. So, for example, if I had a placeholder in my presentation labeled <strong><code>{{Photo}}</code></strong>, then I would upload the images to a folder named <strong><code>Photo</code></strong> and make sure to have a column in my spreadsheet labeled <strong><code>#Photo</code></strong>.</li>



<li>For your rows in this column, all you need are the <em>file names</em> for those images, e.g. <strong>123456.jpg</strong>. (You do NOT need the paths/locations.) Make sure the names appear exactly as they do in Google Drive.</li>
</ul>
</li>



<li>When your table is all set up, click on the &#8220;Extensions&#8221; menu and choose &#8220;Apps Script.&#8221; A new tab should open containing an editor interface.</li>



<li>Delete the default script from the editor and paste in the one from the box above. Then, click the &#8220;Save&#8221; button in the toolbar. (It looks like an old floppy disk because <em>everyone</em> in 2023 knows what one of those is for&#8230;)</li>



<li>Go back to the tab with your spreadsheet and refresh the page. A few seconds after it&#8217;s done reloading, you should see a new item labeled &#8220;Data Merge&#8221; appear in the Google Sheets menu bar.</li>



<li>Click on that new &#8220;Data Merge&#8221; menu and then select &#8220;Do Merge.&#8221; A status notification will appear at the top of your window. Wait for it to indicate that the script has finished. (The longer your spreadsheet, the longer this will take.)</li>



<li>Go back to your folder on Google Drive. You should see a new slideshow named &#8220;Generated Slide Deck.&#8221; Open it up. If all went well, you will see a slide for each row of the spreadsheet. Each of your placeholders should have been filled in with the appropriate text or image!</li>
</ol>



<h2 class="wp-block-heading">Wrapping Up</h2>



<p>Thanks for following along on my Google Apps scripting adventure. Hopefully, you&#8217;ve enjoyed the opportunity to learn about this powerful automation tool, and perhaps you&#8217;ll even find a way to incorporate my slideshow generator into your own workflow!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Generate an Awards Slideshow Using a Spreadsheet and InDesign</title>
		<link>https://teachernerd.com/2023/09/19/how-to-generate-an-awards-slideshow-using-a-spreadsheet-and-indesign/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Tue, 19 Sep 2023 23:44:17 +0000</pubDate>
				<category><![CDATA[How-Tos]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?p=1412</guid>

					<description><![CDATA[During the pandemic, virtual ceremonies often replaced in-person graduations, inductions, and other award ceremonies.

Creating a slideshow with awardees' names and photos could add some visual interest, but depending on the size of the group, they could also take a long time to build.

In this tutorial, I walk readers through a method to automate this process using a spreadsheet and Adobe InDesign. The same techniques could also be used for any other resources, like certificates or photo directories, that require merging text and images from a list into a pre-made template.]]></description>
										<content:encoded><![CDATA[
<p>For several years, one of the many hats I wore as a teacher was that of National Honor Society adviser. Among the responsibilities that came with this role was organizing an annual induction ceremony.</p>



<p>Some NHS inductions (like the one I experienced as a teenager) involve an elaborate candle-lighting ritual. Our school opted for a streamlined approach.</p>



<p>Each of the society&#8217;s officers would deliver some prepared remarks, a guest speaker would give an inspirational keynote, and we&#8217;d announce each inductee&#8217;s name as if it were a graduation. We&#8217;d conclude the event with a recitation of the NHS pledge and then wish all the proud families a good night. All told, it took about 90 minutes.</p>



<p>Normally, when announcing the names, we&#8217;d invite each student up onto the auditorium stage to receive a certificate. But then&#8230;the pandemic happened.</p>



<p>Like <em>everything</em> else, the ceremony went virtual. But let&#8217;s face it: no one comes to the NHS induction for the speeches (even though we did continue including them in the ceremony). What the parents in attendance <em>really</em> want is to hear their kids&#8217; names and see them walk across that stage. The solution? An induction slideshow! </p>



<p>Sharing a slideshow over Zoom is easy enough, but you know what I did <em>not</em> want to do? Create all those slides, each with a student&#8217;s name and photo, by hand. This wouldn&#8217;t be a big deal for, say, a dozen students, but our chapter inducted over 100 each year!</p>



<p>After some investigation, I determined that this problem could be solved with two tech tools I already used quite frequently in my journalism classroom: <strong>Microsoft Excel</strong> and <strong>Adobe InDesign</strong>. </p>



<h2 class="wp-block-heading">Objective</h2>



<p>In the following tutorial, I&#8217;ll walk you through how to create an awards slideshow suitable for a graduation, induction ceremony, or other event where you want to individually project each recognized individual&#8217;s name and face. These same techniques could also be used for other resources, like certificates or photo directories, that require merging text and images from a list into a pre-made template.</p>



<h2 class="wp-block-heading">Materials</h2>



<p>This tutorial should work on any Mac or Windows-powered PC capable of running Adobe InDesign.</p>



<p>To follow along, you&#8217;ll need the following tools:</p>



<ul class="wp-block-list">
<li><strong>Adobe InDesign: </strong>This desktop publishing app may not be your first thought when trying to create a slideshow. In fact, there are dedicated apps like Keynote, Google Slides, and PowerPoint that are far more suited to the task, but none of them has built-in data-merge capabilities. InDesign does! This tutorial assumes you are already familiar with creating a document and adding simple elements like text boxes and image frames to the page.</li>



<li><strong>Adobe Acrobat Reader: </strong>The easiest way, in my opinion, to share the finished slideshow is as a PDF, and Adobe Reader makes it very easy to display the PDF like a slideshow. But really, any PDF viewer that can display single pages in full-screen format will do the trick.</li>



<li><strong>Microsoft Excel</strong> or <strong>Google Sheets</strong>: You&#8217;ll need to use your favorite spreadsheet app to do some basic data manipulation and create the info file necessary for InDesign to do its magic. I&#8217;ll mostly be using Excel for my examples, but Google Sheets works just as well. Plus, any formula that works in one app will usually also work in the other.</li>



<li><strong>List of student information</strong>: The list can be in any format that you can easily open, import, or paste into your spreadsheet app. (You can either create this yourself or obtain it from your school&#8217;s student information system.) At minimum, you&#8217;ll want columns for each student&#8217;s name. If there is any additional information you want to include on the slide, such as the student&#8217;s grade or teacher, you&#8217;ll want to have columns for those things, too. And if there are any details (e.g. an ID number) that might help you match a student&#8217;s name to the relevant photo, it would be helpful to include that information as well.</li>



<li><strong>A folder of student images</strong>: For this to work as efficiently as possible, the images need to have a predictable naming format. Something like <code>[lastName]_[firstName].jpg</code> or <code>[idNumber].jpg</code> would be ideal. If that&#8217;s not possible, you <em>can</em> still follow this procedure with randomly named files. You&#8217;ll just have to manually enter each of the filenames into the spreadsheet, which of course, does somewhat defeat the purpose of automation.</li>
</ul>



<h2 class="wp-block-heading">Step 1: Gather and Format Your Data</h2>



<p>If you&#8217;re working with an existing Excel file or Google Sheets document, go ahead and open it in whichever app you are using. Otherwise, do what you need to do to import or paste the data into a new document.</p>



<p>Once you&#8217;ve gotten your data in front of you, delete any columns you don&#8217;t need and perform any manipulations necessary to clean up the data.</p>



<p>For example, let&#8217;s say my initial spreadsheet, which has been exported from the student information system, looks something like this:</p>



<figure class="wp-block-table"><table><thead><tr><th> </th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th></tr></thead><tbody><tr><td><strong>1</strong></td><td><strong>Name</strong></td><td><strong>Grade</strong></td><td><strong>ID Number</strong></td><td><strong>Address</strong></td><td><strong>Teacher</strong></td></tr><tr><td><strong>2</strong></td><td>Henderson, Kaitlyn</td><td>10</td><td>123456</td><td>123 Somewhere St.</td><td>Ms. A</td></tr><tr><td><strong>3</strong></td><td>Murray, Jaxon</td><td>9</td><td>123457</td><td>456 Anywhere St.</td><td>Mr. B</td></tr><tr><td><strong>4</strong></td><td>Wright, Lila</td><td>11</td><td>123458</td><td>789 Wherever Pl.</td><td>Mr. B</td></tr><tr><td><strong>5</strong></td><td>Garcia, Kian</td><td>12</td><td>123459</td><td>321 Nowhere Ct.</td><td>Mx. C</td></tr></tbody></table><figcaption class="wp-element-caption">Note: These are <em>not</em> real students&#8217; names. They were generated by the Bing search engine&#8217;s AI-powered chat feature.</figcaption></figure>



<p>I don&#8217;t need grades, addresses, or teacher names for my slideshow, so I&#8217;m going to delete those three columns. I also like to have the ID number at the very beginning. So now my spreadsheet looks like this:</p>



<figure class="wp-block-table"><table><thead><tr><th></th><th>A</th><th>B</th></tr></thead><tbody><tr><td><strong>1</strong></td><td><strong>ID Number</strong></td><td><strong>Name</strong></td></tr><tr><td><strong>2</strong></td><td>123456</td><td>Henderson, Kaitlyn</td></tr><tr><td><strong>3</strong></td><td>123457</td><td>Murray, Jaxon</td></tr><tr><td><strong>4</strong></td><td>123458</td><td>Wright, Lila</td></tr><tr><td><strong>5</strong></td><td>123459</td><td>Garcia, Kian</td></tr></tbody></table></figure>



<p>This is closer to what I need. Unfortunately, my school&#8217;s student information system often exports names in <em>&#8220;Last, First&#8221;</em> format, but I want the names in the slideshow to look like <em>&#8220;First Last.&#8221;</em> So I&#8217;m going to use the text-to-columns feature that I described <a href="https://teachernerd.com/2021/12/31/how-to-split-excel-data-into-multiple-columns-without-getting-it-all-jumbled-up/">here</a> to split up the names into two columns. (I&#8217;m also going to rename the ID column because things are always a bit easier, in my experience, when field names are just a single word.)</p>



<p>Now my data looks like this:</p>



<figure class="wp-block-table"><table><thead><tr><th></th><th>A</th><th>B</th><th>C</th></tr></thead><tbody><tr><td><strong>1</strong></td><td><strong>ID</strong></td><td><strong>Last</strong></td><td><strong>First</strong></td></tr><tr><td><strong>2</strong></td><td>123456</td><td>Henderson</td><td>Kaitlyn</td></tr><tr><td><strong>3</strong></td><td>123457</td><td>Murray</td><td>Jaxon</td></tr><tr><td><strong>4</strong></td><td>123458</td><td>Wright</td><td>Lila</td></tr><tr><td><strong>5</strong></td><td>123459</td><td>Garcia</td><td>Kian</td></tr></tbody></table></figure>



<p>This is just what I need to be able to put each student&#8217;s name on a slide.</p>



<h2 class="wp-block-heading">Step 2: Add the Image Filenames</h2>



<p>Rather than somehow try to put the images themselves into your spreadsheet, all you need to do is add the filenames. You can type or paste each of those filenames in manually if needed. However, ideally, as long as the filenames follow a predictable pattern, you can generate them automatically using a formula.</p>



<p>For example, when you export the photos from the student information system, let&#8217;s say the filenames look something like this: &#8220;HENDERSON_KAITLYN.JPG&#8221;</p>



<p>That&#8217;s a <em>predictable</em> format; it&#8217;s always the last name, followed by an underscore, followed by the first name, a period, and the file extension. Oh, and let&#8217;s not forget that everything is in all-caps!</p>



<p>I can recreate this filename in an empty cell at the end of Kaitlyn&#8217;s row using the following formula:</p>



<pre class="wp-block-code"><code>=UPPER(B2 &amp; "_" &amp; C2 &amp; ".jpg")</code></pre>



<p>If you need a refresher on Excel formulas, here&#8217;s a quick breakdown:</p>



<ul class="wp-block-list">
<li> The equals sign tells Excel that this is a <em>formula</em> and not a piece of data.</li>



<li><code>UPPER()</code> is a function that converts any text you give it into uppercase.</li>



<li>The letters and numbers (e.g. <em>B2</em>) refer to a particular cell by row and column, respectively.</li>



<li>Anything in quotation marks (like &#8220;_&#8221; and &#8220;.jpg&#8221;) is interpreted as a &#8220;string&#8221; of arbitrary text.</li>



<li>The ampersands are used to <em>concatenate</em> (or stick together) two pieces of text.</li>
</ul>



<p>So if you type all that into a cell and hit the <kbd><strong>Enter</strong></kbd> key, it should immediately display <code>HENDERSON_KAITLYN.JPG</code></p>



<p>Now, what if the image filenames follow a different pattern? For instance, my school&#8217;s photography vendor would label the photos by student ID number. This was actually really convenient for us because it made it very easy to import the images into our student information system. And because I already have the ID number for every student, it&#8217;s also very easy for me to add these filenames to the spreadsheet. Here&#8217;s the formula for the first row:</p>



<pre class="wp-block-code"><code>=A2 &amp; ".jpg"</code></pre>



<p>This is just a simple concatenation, which gives us the following result: <code>123456.jpg</code></p>



<p>I&#8217;ll leave it as an exercise to the reader to figure out how to calculate the appropriate filenames for different schools and situations. Hopefully, these two examples serve as a useful starting point.</p>



<p>Assuming you&#8217;ve gotten this far, there is still a minor problem here. The issue is that although we have successfully generated a filename, for this to work in the end we also need to know the <em>location</em> of the image in the computer&#8217;s file system. This means we need to adjust the formula to also indicate the file&#8217;s &#8220;path.&#8221;</p>



<p>To take care of this on your end, you&#8217;ll need to follow either <strong>Step 3a</strong> or <strong>Step 3b</strong> below, depending on which operating system you&#8217;re using.</p>



<h2 class="wp-block-heading">Step 3a: Add the Full Path to the Image (Windows)</h2>



<p>First, make sure all your images are in the same folder.</p>



<p>Then, if you&#8217;re using Windows, you can get that folder&#8217;s location by selecting one of the images in the computer&#8217;s file browser, right-clicking on that file, and choosing &#8220;Properties&#8221; from the context menu.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/image.png" alt="" class="wp-image-1425" style="width:368px;height:495px" width="368" height="495" srcset="https://teachernerd.com/wp-content/uploads/2023/09/image.png 726w, https://teachernerd.com/wp-content/uploads/2023/09/image-223x300.png 223w" sizes="auto, (max-width: 368px) 100vw, 368px" /></figure></div>


<p>In the Properties window that should appear, look for the &#8220;Location&#8221; field. In the example above, the location is displayed as <code>C:\Users\dan\Desktop\students</code>. You should be able to highlight this location with your pointer, right-click, and select &#8220;Copy.&#8221; Then, you can temporarily paste it somewhere in your spreadsheet or another document to refer to later.</p>



<p>One you&#8217;ve pasted that location somewhere, you&#8217;ll need to add an additional backslash to the very end. Now, it should look something like this: <code>C:\Users\dan\Desktop\students\</code></p>



<p>Now that you have properly formatted the location, you can use it to update the image formula in your spreadsheet. For example, when using Windows, my own updated formula looks like this:</p>



<pre class="wp-block-code"><code>="C:\Users\dan\Desktop\students\" &amp; A2 &amp; ".jpg"</code></pre>



<p>And when I hit <kbd><strong>Enter</strong></kbd>, the result will look like this: <code>C:\Users\dan\Desktop\students\123456.jpg</code></p>



<h2 class="wp-block-heading">Step 3b: Add the Full Path to the Image (macOS)</h2>



<p>First, make sure all your images are in the same folder.</p>



<p>Then, if you&#8217;re using a Mac, browse to that folder in the Finder. Next, click on any image from that folder, hold down the <strong><kbd>Option</kbd></strong> key, and select &#8220;Copy [filename] as Pathname&#8221; from the <strong>Edit</strong> menu. This will store the path to the image on the macOS clipboard. In order to use this stored path, you&#8217;ll need to temporarily paste it somewhere in your spreadsheet or another document. </p>



<p>In my case, when I paste the path from the clipboard, it looks like this: <code>/Users/dan/Desktop/students/123456.jpg</code>.  </p>



<p>This is actually more information than we need, and for it to work in InDesign, the formatting needs to be adjusted. To get this cleaned up, start by removing the filename (e.g. &#8220;123456.jpg&#8221;) from the end of the line. Then, remove the slash from the very beginning of the line. Finally, change all the remaining slashes into colons. In my example, the end result would look like this: <code>Users:dan:Desktop:students:</code></p>



<p><em>If you&#8217;ve done it correctly, there will always be a colon at the end of the line!</em></p>



<p>Now that you have properly formatted the location, you can use it to update the image formula in your spreadsheet. For example, when using macOS, my own updated formula looks like this:</p>



<pre class="wp-block-code"><code>="Users:dan:Desktop:students:" &amp; A2 &amp; ".jpg"</code></pre>



<p>And when I hit <kbd><strong>Enter</strong></kbd>, the result will look like this: <code>Users:dan:Desktop:students:123456.jpg</code></p>



<h2 class="wp-block-heading">Step 4: &#8220;Auto-Fill&#8221; the Image Formula</h2>



<p>Okay, sorry for the bifurcation of <strong>Step 3</strong>. From here on out, the steps are all the same, regardless of your computer.</p>



<p>So the next thing we need to do is take that formula we just created for our first row of data and copy it into the rest of the rows. To do that, just double-click the little box that appears in the bottom-right corner of the cell. (I&#8217;ve circled it in the screenshot below.)</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-11.43.49-AM.png" alt="" class="wp-image-1543" style="width:505px;height:73px" width="505" height="73" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-11.43.49-AM.png 640w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-11.43.49-AM-300x43.png 300w" sizes="auto, (max-width: 505px) 100vw, 505px" /><figcaption class="wp-element-caption">Note: This example features a Windows-style file path.</figcaption></figure></div>


<p>You can do the same thing in Google Sheets, but instead of a square, you&#8217;ll be double-clicking a little circle in the corner:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="528" height="92" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-11.48.26-AM.png" alt="" class="wp-image-1544" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-11.48.26-AM.png 528w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-11.48.26-AM-300x52.png 300w" sizes="auto, (max-width: 528px) 100vw, 528px" /><figcaption class="wp-element-caption">Note: This example features a macOS-style file path.</figcaption></figure></div>


<p>This convenient operation is called &#8220;Auto Fill,&#8221; and the end result should look something like this:</p>



<figure class="wp-block-table"><table><thead><tr><th></th><th>A</th><th>B</th><th>C</th><th>D</th></tr></thead><tbody><tr><td><strong>1</strong></td><td><strong>ID</strong></td><td><strong>Last</strong></td><td><strong>First</strong></td><td></td></tr><tr><td><strong>2</strong></td><td>123456.jpg</td><td>Henderson</td><td>Kaitlyn</td><td>C:\Users\dan\Desktop\students\123456.jpg</td></tr><tr><td><strong>3</strong></td><td>123457.jpg</td><td>Wright</td><td>Jaxon</td><td>C:\Users\dan\Desktop\students\123457.jpg</td></tr><tr><td><strong>4</strong></td><td>123458.jpg</td><td>Murray</td><td>Lila</td><td>C:\Users\dan\Desktop\students\123458.jpg</td></tr><tr><td><strong>5</strong></td><td>123459.jpg</td><td>Garcia</td><td>Kian</td><td>C:\Users\dan\Desktop\students\123459.jpg</td></tr></tbody></table><figcaption class="wp-element-caption">Note: This example features Windows-style file paths. As noted earlier, your data will look a little different if you&#8217;re using macOS.</figcaption></figure>



<h2 class="wp-block-heading">Step 5: Give the Photo Column a &#8220;Special&#8221; Title</h2>



<p>If you&#8217;re paying close attention, you may have wondered whether I &#8220;forgot&#8221; to label the column with my file paths. The truth is I decided to make this its own step because you need to do something a bit unusual here.</p>



<p>In order for InDesign to recognize a column as a list of image file paths (rather than ordinary text), the column&#8217;s label needs to begin with an &#8220;at sign&#8221; (e.g. &#8220;@Photos&#8221;). So in theory, our spreadsheet would need to look like this:</p>



<figure class="wp-block-table"><table><thead><tr><th>﻿</th><th>A</th><th>B</th><th>C</th><th>D</th></tr></thead><tbody><tr><td><strong>1</strong></td><td><strong>ID</strong></td><td><strong>Last</strong></td><td><strong>First</strong></td><td><strong>@Photos</strong></td></tr><tr><td><strong>2</strong></td><td>123456.jpg</td><td>Henderson</td><td>Kaitlyn</td><td>C:\Users\dan\Desktop\students\123456.jpg</td></tr><tr><td><strong>3</strong></td><td>123457.jpg</td><td>Wright</td><td>Jaxon</td><td>C:\Users\dan\Desktop\students\123457.jpg</td></tr><tr><td><strong>4</strong></td><td>123458.jpg</td><td>Murray</td><td>Lila</td><td>C:\Users\dan\Desktop\students\123458.jpg</td></tr><tr><td><strong>5</strong></td><td>123459.jpg</td><td>Garcia</td><td>Kian</td><td>C:\Users\dan\Desktop\students\123459.jpg</td></tr></tbody></table></figure>



<p>Google Sheets will have no problem with this, but Excel will get upset and pop up an error message if you try to do that.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-12.17.55-PM.png" alt="" class="wp-image-1431" style="width:333px;height:282px" width="333" height="282" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-12.17.55-PM.png 744w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-12.17.55-PM-300x255.png 300w" sizes="auto, (max-width: 333px) 100vw, 333px" /><figcaption class="wp-element-caption">The error looks different in Windows, but it&#8217;ll still be an error.</figcaption></figure></div>


<p>The problem is that the @ symbol has a special purpose in Excel. Thankfully, we can get around this by adding a single apostrophe to the very beginning of our entry: <code>'@Photos</code>. This apostrophe tells Excel to treat the entire cell as ordinary text. After you press <strong><kbd>Enter</kbd></strong>, the apostrophe will be hidden, and you&#8217;ll just see <code>@Photos</code>. At this point, your spreadsheet should resemble the example above.</p>



<h2 class="wp-block-heading">Step 6: Export Your Data</h2>



<p>Now that the data is all set up, we need to save it in a format readable by InDesign. </p>



<p>Unfortunately, InDesign can&#8217;t read native Excel files. So we&#8217;ll need to use something more generic: CSV, which stands for &#8220;Comma-Separated Values.&#8221; A CSV is just a plain text file representing a table of data where each row appears on its own line and each column is—you guessed it!—separated by a comma. The first row of a CSV typically includes the names for each column. And that&#8217;s really all there is to it.</p>



<p>Because this is such a basic file format, it&#8217;s actually rather easy to create a CSV using Excel or Google Sheets. In Excel, go to the <strong>File</strong> menu and choose <strong>Save As</strong>. The Save dialog will look a little different depending on what operating system you are using and what version of Excel you have. But somewhere in there, you should see an option to choose the file format.</p>



<p>What you see in the list of options may also vary, but one of them should be named something like &#8220;Comma Separated Values (.csv)&#8221; or &#8220;CSV (Comma delimited)&#8221; depending on your operating system, Excel version, and which type of Save As dialog you&#8217;re looking at. (As you&#8217;ll see in a moment, Microsoft&#8217;s conventions are remarkably inconsistent.)</p>



<p><em>Note: Don&#8217;t choose any option that looks like &#8220;CSV UTF-8 (Comma delimited) (.csv)&#8221;—even if it appears higher up in the list or is labeled a &#8220;Common Format.&#8221; It won&#8217;t work! InDesign can only read a standard, &#8220;old school&#8221; CSV file. And yes, I learned this the hard way.</em></p>



<p>Here&#8217;s what the selector—and the proper choice—looks like in Excel on my Mac: </p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="872" height="66" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.10.31-PM.png" alt="" class="wp-image-1491" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.10.31-PM.png 872w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.10.31-PM-300x23.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.10.31-PM-768x58.png 768w" sizes="auto, (max-width: 872px) 100vw, 872px" /></figure>



<p>And in Windows, it may look like either of the following:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="49" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.00.11-PM-1-1024x49.png" alt="" class="wp-image-1450" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.00.11-PM-1-1024x49.png 1024w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.00.11-PM-1-300x14.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.00.11-PM-1-768x37.png 768w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.00.11-PM-1.png 1122w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Note that in the version above, the setting is labeled &#8220;Save as type.&#8221;</figcaption></figure>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-3.58.38-PM.png" alt="" class="wp-image-1446" style="width:640px;height:39px" width="640" height="39" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-3.58.38-PM.png 900w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-3.58.38-PM-300x19.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-3.58.38-PM-768x48.png 768w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption class="wp-element-caption">And in this version, Microsoft decided they didn&#8217;t need to label it at all!</figcaption></figure>



<p>Regardless of what your Save As dialog looks like, give the file a name, make sure CSV is selected, and click &#8220;Save.&#8221;</p>



<p>If you&#8217;re using Google Slides, the process is a little more straightforward. First, go to the <strong>File</strong> menu. (Make sure you&#8217;re using the Google Sheets app&#8217;s File menu—the one that appears at the top left of the webpage itself—rather than your browser&#8217;s File menu. If you don&#8217;t see it, it&#8217;s possible that your menus are hidden. In that case, try clicking the little down arrow that appears at the end of the Google Sheets toolbar, or you can press <kbd><strong>Ctrl+Shift+F</strong></kbd> to toggle between hidden and unhidden states.)</p>



<p>With the File menu open, hover over <strong>Download</strong> and choose <strong>Comma Separated Values (.csv)</strong>. Depending on your web browser, the file should begin downloading right away, or you may be asked what you want to do with it. I trust that you know how downloads work in your browser, so do what you need to do.</p>



<h2 class="wp-block-heading">Step 7: Find or Create a Design for Your Slides</h2>



<p>We&#8217;re done with data and formulae. Now, it&#8217;s time to get creative! This step is all about figuring out the background for your slide. You don&#8217;t have to put any<em> </em>student information or photos on the slide yet; you just need to add any colors, designs, or boilerplate text (i.e. static information, like the school or organization name) that you want to appear in the same spot on every slide.</p>



<p>You can create your slide from scratch directly in InDesign, or you can use a pre-made design.</p>



<p>For example, when I created my NHS induction slideshow, I really wanted to use <a rel="noreferrer noopener" href="https://slidesgo.com/theme/custal-project-proposal" target="_blank">this template</a> from Slidesgo since I had used it for some previous NHS presentations. Unfortunately, Slidesgo templates only work in Google Slides and PowerPoint. My solution was to use the template to create a single slide in Google Slides with nothing on it except for the background design. Then, I downloaded that otherwise &#8220;blank&#8221; slide from Google Slides as a PDF. Finally, I created an InDesign file with the same dimensions as the PDF (10 × 5.63 in.) and just placed the PDF right onto the canvas.</p>



<p><em>Note: If you decide to do something like this, double-check the template&#8217;s license agreement to make sure you&#8217;re allowed to use the content in that way, and be sure to follow the content creator&#8217;s rules for attribution. For instance, Slidesgo requires non-paying  users to include their provided &#8220;Credits&#8221; slide at the end of the presentation.</em></p>



<p>Whether you create your own or start with someone else&#8217;s design, make sure (for now) that your InDesign file has only a single page. (If you need to add an attribution slide, you can do that later.)</p>



<p>For argument&#8217;s sake, let&#8217;s say that you decided to create your slide from scratch and that it looks something like the following&#8230;er&#8230;masterpiece:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="744" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-2.54.41-PM-1024x744.png" alt="" class="wp-image-1435" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-2.54.41-PM-1024x744.png 1024w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-2.54.41-PM-300x218.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-2.54.41-PM-768x558.png 768w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-2.54.41-PM-1536x1116.png 1536w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-2.54.41-PM-2048x1488.png 2048w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-2.54.41-PM-1600x1163.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>In this example, I want the blue-ish background, the star with the organization&#8217;s initials, and the event name to appear on every slide. So I&#8217;ve created a single-page InDesign document with just those details.</p>



<h2 class="wp-block-heading">Step 8: Import the Data into InDesign</h2>



<p>We&#8217;re getting pretty close to the end here, but before we can go any further, we need to import the spreadsheet data that we exported earlier. To do this, go to InDesign&#8217;s <strong>Window</strong> menu. Then, hover over <strong>Utilities</strong> and choose <strong>Data Merge</strong>. An unassumingly small—but <em>powerful</em>—panel should pop up. On my machine, it looks like this:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-12.07.03-PM.png" alt="" class="wp-image-1554" style="width:272px" width="272" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-12.07.03-PM.png 504w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-12.07.03-PM-287x300.png 287w" sizes="(max-width: 504px) 100vw, 504px" /><figcaption class="wp-element-caption">I&#8217;ve always wondered why Adobe put the instructions inside what looks like a text input box. Rest assured, despite its amateurish appearance, this tool works as advertised.</figcaption></figure></div>


<p>The panel pretty much tells you exactly what you need to do. But for now, let&#8217;s just follow Step 1: &#8220;Choose Select Data Source from the panel menu.&#8221; What it&#8217;s actually asking you to do is to click the button with the horizontal lines (sometimes referred to as a &#8220;hamburger menu&#8221;) in the top right corner of the panel. Then, you should see a menu option labeled &#8220;Select Data Source&#8230;&#8221; Choose that option. A file browser should appear. Use it to find the CSV file you created earlier, and finally click the &#8220;Open&#8221; button.</p>



<p>If the data was properly exported, the Data Merge panel should now look something like this:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-12.05.01-PM.png" alt="" class="wp-image-1552" style="width:272px" width="272" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-12.05.01-PM.png 504w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-20-at-12.05.01-PM-287x300.png 287w" sizes="(max-width: 504px) 100vw, 504px" /></figure></div>


<p>You should see a row for each of your fields. The &#8220;T&#8221; icon indicates a text field and the photo icon indicates, of course, a photo!</p>



<h2 class="wp-block-heading">Step 9: Turn Your Slide into a Template</h2>



<p>Back in Step 5, we took care of the static data—the stuff that appears on every slide without changing. Now, we need to add placeholders for dynamic data—the stuff (like student names and photos) that <em>change</em> on each slide.</p>



<p>To do this, you have to start by creating a text box for any piece of textual data you want to include. In my example, I only have one piece of textual data (the student&#8217;s name), so I&#8217;m just going to create a single text box. For the moment, you don&#8217;t need to put anything in your text boxes. They just need to exist.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.28.53-PM-1024x744.png" alt="" class="wp-image-1457" style="width:640px;height:465px" width="640" height="465" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.28.53-PM-1024x744.png 1024w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.28.53-PM-300x218.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.28.53-PM-768x558.png 768w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.28.53-PM-1536x1116.png 1536w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.28.53-PM-2048x1488.png 2048w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.28.53-PM-1600x1163.png 1600w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<p>Now, go back to the Data Merge panel, and use your mouse to click-and-drag each of your desired fields (i.e. each piece of dynamic data) into the appropriate text box.</p>



<p>I&#8217;m going to start by dragging the filed labeled &#8220;First&#8221; into the box. As soon as I let go of the mouse, it shows up inside the box as <code>&lt;&lt;First&gt;&gt;</code>. I also need to include the student&#8217;s last name in that box, so I&#8217;m going to drag in the &#8220;Last&#8221; field as well. Now, I have <code>&lt;&lt;First&gt;&gt;&lt;&lt;Last&gt;&gt;</code>. The final step (for me) is to add a space between these two fields so that the name isn&#8217;t all jumbled together. The result looks like this: <code>&lt;&lt;First&gt;&gt; &lt;&lt;Last&gt;&gt;</code>.</p>



<p><em>Note: Even though what you see on the screen may look like ordinary letters and angle brackets, you can&#8217;t just type in your field names. As Adobe explains in their own <a rel="noreferrer noopener" href="https://helpx.adobe.com/indesign/using/data-merge.html" target="_blank">tutorial</a>, you must drag the fields into the box.</em></p>



<p>After you&#8217;ve added your text fields, you can apply any formatting you&#8217;d like. I, for one, need to make the text much larger than the default font size and apply the proper color. You can do this the same way you&#8217;d style any other text in InDesign. One thing to keep in mind is to make the text box as wide as you think it will need to be to accommodate the longest names on your list.</p>



<p>Here&#8217;s what my text box looks like with the fields added and the appropriate formatting applied.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="744" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.40.06-PM-1024x744.png" alt="" class="wp-image-1459" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.40.06-PM-1024x744.png 1024w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.40.06-PM-300x218.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.40.06-PM-768x558.png 768w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.40.06-PM-1536x1116.png 1536w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.40.06-PM-2048x1488.png 2048w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.40.06-PM-1600x1163.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Once the text has been taken care of, you can add any photos you need to include. In my case, I just want to have a single image (the student&#8217;s portrait) on each slide.</p>



<p>Similar to before, the first step is to add an empty frame to the document.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="744" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.45.55-PM-1024x744.png" alt="" class="wp-image-1461" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.45.55-PM-1024x744.png 1024w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.45.55-PM-300x218.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.45.55-PM-768x558.png 768w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.45.55-PM-1536x1116.png 1536w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.45.55-PM-2048x1488.png 2048w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.45.55-PM-1600x1163.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>And again, just like before, you&#8217;ll drag your photo field from the Data Merge panel right into the frame.</p>



<p>One thing to be aware of is that if you are editing the document in InDesign&#8217;s &#8220;Preview&#8221; screen mode, you won&#8217;t get much obvious visual feedback to confirm that you&#8217;ve successfully linked the field to the frame. However, if you switch back to &#8220;Normal&#8221; mode, you should see the name of your field (e.g. <code>&lt;&lt;Photos&gt;&gt;</code>) appear inside the frame. </p>



<p>Also, regardless of which mode you&#8217;re using, a little &#8220;1&#8221; will appear next to the field name in the Data Merge panel to indicate that something on Page 1 has been linked to it.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.56.09-PM.png" alt="" class="wp-image-1470" style="width:272px" width="272" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.56.09-PM.png 504w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-4.56.09-PM-287x300.png 287w" sizes="(max-width: 504px) 100vw, 504px" /></figure></div>


<p>So feel free to look for either of those indicators to confirm that the photo field has been appropriately linked.</p>



<h2 class="wp-block-heading">Step 10: Preview the Dynamic Data</h2>



<p>Okay, time for the moment of truth. Let&#8217;s see if all of this worked!</p>



<p>Go back to the Data Merge panel and click the &#8220;Preview&#8221; checkbox in the bottom left corner. If all has gone according to plan, the placeholders on your slide should now show the actual text for the first person on your list. You should also, hopefully, see that person&#8217;s photo in your image frame.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.23.47-PM-1024x744.png" alt="" class="wp-image-1501" style="width:639px;height:464px" width="639" height="464" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.23.47-PM-1024x744.png 1024w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.23.47-PM-300x218.png 300w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.23.47-PM-768x558.png 768w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.23.47-PM-1536x1116.png 1536w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.23.47-PM-2048x1488.png 2048w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-7.23.47-PM-1600x1163.png 1600w" sizes="auto, (max-width: 639px) 100vw, 639px" /><figcaption class="wp-element-caption">Image credit: <a rel="noreferrer noopener" href="https://thenounproject.com/mim_studio" target="_blank">mim studio</a>, from <a rel="noreferrer noopener" href="https://en.wikipedia.org/wiki/The_Noun_Project" target="_blank">The Noun Project</a> (<a href="https://thenounproject.com/icon/person-2817719/" target="_blank" rel="noreferrer noopener">original source</a>; <a href="https://creativecommons.org/licenses/by/3.0/us/deed.en" target="_blank" rel="noreferrer noopener">CC BY US 3.0 license</a>)</figcaption></figure></div>


<p>You can use the forward and back arrows in the Data Merge panel to browse additional entries. This is a good way to make sure all the data fits correctly and that the correct photos have been associated with each name.</p>



<p>If it looks like one or more of the boxes are too small, you can make some adjustments right on the preview. (Note: If you&#8217;d rather not make a change to <em>everyone&#8217;s</em> slide, you can edit just that student&#8217;s slide when the whole process is complete. I&#8217;ll mention this later!)</p>



<p>If something doesn&#8217;t seem right (e.g. the data is mis-matched or the images don&#8217;t work), go back to your spreadsheet and see if you can figure out what went wrong. If you make any changes, just save the data as a CSV again using the same filename as before. Then, go back to InDesign, click on the hamburger menu in the Data Merge panel, choose &#8220;Update Data Source,&#8221; and see if everything links up correctly this time.</p>



<h2 class="wp-block-heading">Step 11: Generate the Slides from Your Template</h2>



<p>If you&#8217;re liking how things look in your preview, then it&#8217;s time to generate your slides.</p>



<p>You can start this process in either of two ways:</p>



<ul class="wp-block-list">
<li>Click on the hamburger menu in the Data Merge panel and choose &#8220;Create Merged Document&#8230;&#8221;</li>



<li>Click the button (with the little arrow and some squares) that appears right below the hamburger menu. (If you hover your cursor over the button before clicking, you should see a tooltip that says, &#8220;Create Merged Document.&#8221;)</li>
</ul>



<p>Regardless of which way you do it, a new dialog box should pop up.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-5.52.52-PM-975x1024.png" alt="" class="wp-image-1472" style="width:530px;height:557px" width="530" height="557" srcset="https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-5.52.52-PM-975x1024.png 975w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-5.52.52-PM-286x300.png 286w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-5.52.52-PM-768x806.png 768w, https://teachernerd.com/wp-content/uploads/2023/09/Screenshot-2023-09-19-at-5.52.52-PM.png 1120w" sizes="auto, (max-width: 530px) 100vw, 530px" /></figure></div>


<p>I was able to use the default settings. But just in case, make sure your settings look like the example above. Specifically, start by making sure the &#8220;Records&#8221; tab is selected at the very top. Next, under &#8220;Records To Merge,&#8221; make sure that &#8220;All Records&#8221; is selected. It is also vital that &#8220;Records per Document Page&#8221; be set to &#8220;Single Record.&#8221; (This setting is the one that ensures that we end up with a separate slide for each student.)</p>



<p>It&#8217;s not strictly necessary, but I also recommend checking the boxes labeled &#8220;Generate Overset Text Report with Document Creation&#8221; and &#8220;Alert When Images Are Missing.&#8221; These options will help you figure out if any of your slides will need some manual fixes (i.e. to remove overset text or deal with a missing photo).</p>



<p><em>Note: If you click on the &#8220;Options&#8221; tab, you can access a few additional settings concerning things like image placement, how to handle empty fields, and whether to limit the number of records per document. I stuck with the defaults for all of these, but you may want to take a look at the options just in case they&#8217;re relevant to your use case.</em></p>



<p>Once that&#8217;s all set up, go ahead and click &#8220;OK.&#8221; If you checked those two boxes I mentioned earlier, you might see a popup about missing images or overset text. Otherwise, when all is said and done, InDesign should have opened a new document, and each page of that document should be an individual student&#8217;s slide. Congratulations! You&#8217;ve generated your slideshow!</p>



<h2 class="wp-block-heading">Step 12: Clean Things Up and Export to PDF</h2>



<p>At this point, we&#8217;re basically done. However, you may need to make some individual adjustments to slides. For example, maybe you still have a student or two with a long name that got cut off. Now that you&#8217;ve generated the full slide deck, you can tweak those individual students&#8217; slides without affecting the others. Or perhaps you chose to use a commercially available template that requires an attribution slide at the end. Now would be a good time to add that in.</p>



<p>When everything looks good and the slideshow is ready to be shared, the last step is to export it to PDF. This way, you can still display it even if the computer connected to the projector (or to a Zoom call) doesn&#8217;t have InDesign. (It <em>would</em>, however, be very helpful if that computer has a copy of Adobe Acrobat Reader, though other PDF-compatible applications may also work.)</p>



<p>So anyhow, to export to PDF, you&#8217;ll click on the <strong>File</strong> menu, hover over <strong>Adobe PDF Presets</strong>, and choose <strong>High Quality Print</strong>. (If you have some other preset that you&#8217;d prefer to use, that&#8217;s totally fine.) Choose a filename and location when asked. If you chose &#8220;High Quality Print,&#8221; you probably don&#8217;t need to change any settings when the options dialog appears. But feel free to look things over to ensure they make sense for your use case.</p>



<p>When you&#8217;re ready, click the &#8220;Export&#8221; button.</p>



<h2 class="wp-block-heading">Wrapping Up</h2>



<p>While a dozen steps, complete with copy/pasted file paths and awkward Excel formulae may <em>seem</em> like a lot of work, this pales (in my personal opinion) in comparison to the drudgery that would otherwise be required to create each individual slide, copy over the template for each student, type out or paste in each student&#8217;s name, find each student&#8217;s photo, and finally drop each of those photos onto the appropriate slides—especially as the group gets larger and larger. (Remember, my NHS induction included over 100 kids!)</p>



<p>When the time comes to present your slideshow, I think the easiest thing to do is to open the PDF in Adobe Acrobat Reader. In the <strong>View</strong> menu, make sure that <strong>Page Display</strong> is set to &#8220;Single Page View.&#8221; Then, in the <strong>View</strong> menu again, select <strong>Full Screen Mode</strong>. (Alternatively, you can press <kbd><strong>Cmd+L</strong></kbd> on a Mac or <kbd><strong>Ctrl+L</strong></kbd> in Windows.)</p>



<p>Now, you should be able to page through the slideshow the same way you would in Google Slides, PowerPoint, or Keynote: just tap the spacebar, use the arrow keys, or click the mouse. Hopefully, whoever is in your audience will be <em>super impressed</em> by all the work you <em>obviously</em> must have done to create 100 carefully personalized slides!</p>



<h2 class="wp-block-heading">Postscript</h2>



<p>While doing some research for this blog post, I came across a Microsoft <a rel="noreferrer noopener" href="https://support.microsoft.com/en-au/office/mail-merge-in-powerpoint-625f3004-bc83-4c3c-8a5a-6f6bb7e3e751" target="_blank">support page</a> noting the existence of &#8220;two known add-ins for PowerPoint&nbsp;that can help you merge data from an&nbsp;Excel workbook into a presentation file.&#8221; That support page leads to a forum post from 2017 that ultimately links to the following two plugins:</p>



<ul class="wp-block-list">
<li><a rel="noreferrer noopener" href="http://www.pptalchemy.co.uk/Simple_merge.html" target="_blank">Simple Merge</a>, available for $19.99</li>



<li><a href="http://www.pptools.com/merge/index.html" target="_blank" rel="noreferrer noopener">PPT Merge</a>, available for $69.95</li>
</ul>



<p>I can&#8217;t vouch for either of these tools or the people/companies that appear to be selling them. They both come from websites that look to be super-outdated, and it&#8217;s a little unclear from some of the information provided as to whether these plugins still work in the latest versions of PowerPoint or on the latest Windows operating systems. (One thing that&#8217;s clear is that neither of them work on a Mac.) But since Microsoft itself made a reference to them, I thought I should include them here in the interest of completeness.</p>



<p>Additionally, I also found a <a rel="noreferrer noopener" href="https://spreadsheet.dev/generate-google-slides-from-google-sheets" target="_blank">trio</a> of <a rel="noreferrer noopener" href="https://spreadsheet.dev/mail-merge-from-google-sheets-to-google-slides" target="_blank">blog</a> <a href="https://spreadsheet.dev/convert-each-row-google-sheets-into-slide-google-slides-apps-script" target="_blank" rel="noreferrer noopener">posts</a> on a site called Spreadsheet Dev that discuss how to use Google Apps Script to merge data from Google Sheets into presentations in Google Slides. These solutions require some actual coding, so they&#8217;re definitely not for everybody. It also looks like they&#8217;re only designed to work with text, not images. That said, I fully intend to try out this guy&#8217;s techniques and then see if I can tack on the ability to handle images. I&#8217;ll report back on this project in a future blog post.</p>



<p>Until then, may you merge merily!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Rough Surf: Emulating MacOS 9 – in 2022!</title>
		<link>https://teachernerd.com/2022/10/01/rough-surf-emulating-macos-9/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Sat, 01 Oct 2022 23:31:21 +0000</pubDate>
				<category><![CDATA[Projects]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?p=1105</guid>

					<description><![CDATA[After successfully booting MS-DOS inside an emulator on my M1-powered MacBook Pro, I decided to try out another ancient operating system: MacOS 9.

In this post, I explore what it takes to get it running and what it's like to browse today's World Wide Web using a 20-year-old operating system.]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">The Background</h2>



<p>When Apple announced that it was transitioning its computers to &#8220;Apple Silicon&#8221; processors, there was a lot of angst in the tech community over what this meant for virtualization on the Mac.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="960" height="720" src="https://teachernerd.com/wp-content/uploads/2022/10/IMG_0600.jpg" alt="" class="wp-image-1112" srcset="https://teachernerd.com/wp-content/uploads/2022/10/IMG_0600.jpg 960w, https://teachernerd.com/wp-content/uploads/2022/10/IMG_0600-300x225.jpg 300w, https://teachernerd.com/wp-content/uploads/2022/10/IMG_0600-768x576.jpg 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /><figcaption class="wp-element-caption">So. Much. Angst.</figcaption></figure>



<p>Because Apple Silicon processors (such as the M1 and M2 series) are based on the <em>ARM</em> architecture, it&#8217;s impossible to run software compiled for the <em>x86</em> processors like those Intel and AMD are generally known for today. When Apple started releasing their new computers, this meant that retail versions of Windows, many Linux distributions, and other &#8220;legacy&#8221; operating systems could neither be installed natively on those machines via Boot Camp nor run via virtualization software such as Parallels.</p>



<p>The situation has improved somewhat since then. For one thing, the latest version of Parallels can <a rel="noreferrer noopener" href="https://kb.parallels.com/125375/" target="_blank">automatically install</a> a compatible version of Windows 11.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="673" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.35.44-PM-1024x673.png" alt="" class="wp-image-1114" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.35.44-PM-1024x673.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.35.44-PM-300x197.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.35.44-PM-768x505.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.35.44-PM.png 1303w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Meanwhile, an open source project called <a rel="noreferrer noopener" href="https://asahilinux.org/" target="_blank">Asahi Linux</a> has devised a method for natively booting an Arch Linux-based distribution on M1 and M2 Macs.</p>



<p>Over the past few months, I&#8217;ve successfully tested both of these solutions, but during this time, I also began to get curious about a seemingly less popular workaround to the virtualization problem: <em>emulation</em>.</p>



<p>Whereas virtualization allows multiple guest machines to share the hardware of the same host machine, emulation uses software to mimic a completely different set of hardware. This makes it possible to run <em>x86</em> software, for instance, on a computer with an <em>ARM</em> processor—albeit with a notable performance cost.</p>



<h2 class="wp-block-heading">The Problem</h2>



<p>My first experiment with emulation on an M1-based Mac was an attempt to run MS-DOS using an app called UTM, which is essentially a graphical front end for the venerable QEMU emulator.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.42.24-PM-1024x677.png" alt="" class="wp-image-1116" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.42.24-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.42.24-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.42.24-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.42.24-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.42.24-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.42.24-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>I documented this successful project in a <a href="https://teachernerd.com/2022/07/16/how-to-run-ms-dos-on-a-mac-with-intel-or-m-series-processor/">tutorial</a> and was even eventually able to run an old game, SimCity 2000, with fully functional sound and graphics.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="887" src="https://teachernerd.com/wp-content/uploads/2022/07/293438714_10229558526404607_2045286813468785675_n-1024x887.jpg" alt="" class="wp-image-1097" srcset="https://teachernerd.com/wp-content/uploads/2022/07/293438714_10229558526404607_2045286813468785675_n-1024x887.jpg 1024w, https://teachernerd.com/wp-content/uploads/2022/07/293438714_10229558526404607_2045286813468785675_n-300x260.jpg 300w, https://teachernerd.com/wp-content/uploads/2022/07/293438714_10229558526404607_2045286813468785675_n-768x665.jpg 768w, https://teachernerd.com/wp-content/uploads/2022/07/293438714_10229558526404607_2045286813468785675_n-1536x1331.jpg 1536w, https://teachernerd.com/wp-content/uploads/2022/07/293438714_10229558526404607_2045286813468785675_n.jpg 1570w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>After letting that project sit for a while, I decided to come back to it and try installing Windows 3.11 on top of DOS in the same emulated environment.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="858" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.43.11-PM-1024x858.png" alt="" class="wp-image-1115" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.43.11-PM-1024x858.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.43.11-PM-300x251.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.43.11-PM-768x643.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.43.11-PM.png 1504w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>As I expected, this worked just fine, but it got me wondering about what <em>other</em> fun blasts from the past I might be able to run on Apple Silicon via emulation.</p>



<p>For instance, is it still possible to run the &#8220;classic&#8221; MacOS, an operating system that runs on yet <em>another</em> processor architecture—namely, <em>PowerPC</em>?</p>



<p>I had accomplished this once or twice before on an older Mac using a purpose-built emulator called SheepShaver, but until now had not investigated whether the tools exist to do it on a newer machine.</p>



<h2 class="wp-block-heading">The Objective</h2>



<p>At bare minimum, for this project to be successful, I wanted to be able to boot <em>some</em> version of the classic Mac operating system. My preference would be a release from the MacOS 9.2.x series since these are the final and essentially most &#8220;complete&#8221; standalone editions of the software. (This is the same reason I went with MS-DOS 6.22 for my previous project.) That said, anything from the 9.x series would be acceptable.</p>



<p>Now, installing an operating system is useless if you can&#8217;t <em>do</em> anything with it. And while there&#8217;s plenty of abandoned Mac software available on the internet if you go searching for it, finding anything ultimately requires, well, the internet! So a secondary goal would be to actually be able to browse the web using this emulated machine.</p>



<h2 class="wp-block-heading">The Solution</h2>



<h3 class="wp-block-heading">Path #1: SheepShaver</h3>



<p></p>



<p>It turns out that not only is SheepShaver still around, but there&#8217;s actually a version out there compiled for Apple Silicon!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="818" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.47.11-PM-1024x818.png" alt="" class="wp-image-1117" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.47.11-PM-1024x818.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.47.11-PM-300x240.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.47.11-PM-768x614.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.47.11-PM-1536x1228.png 1536w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.47.11-PM-2048x1637.png 2048w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.47.11-PM-1600x1279.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>There&#8217;s really a community for just about anything out there <em>somewhere</em> on the internet, and classic MacOS emulation is apparently one of them. In this case, it&#8217;s <a rel="noreferrer noopener" href="http://dedicated/ to emulation of the classic Macintosh computer in MacOSX/macOS, Windows and Linux." target="_blank">E-Maculation</a>, a wiki and forum &#8220;dedicated to emulation of the classic Macintosh computer in MacOSX/macOS, Windows and Linux.&#8221;</p>



<p>The E-Maculation site hosts versions of SheepShaver built for &#8220;modern&#8221; editions of the Mac operating system dating back to version 10.4 and for all the different processor architectures these have ever worked on (i.e. <em>PowerPC</em>, <em>x86</em>, <em>x86_64</em>, and of course <em>ARM64</em>).</p>



<p>The latest builds are all linked to <a rel="noreferrer noopener" href="https://www.emaculation.com/forum/viewtopic.php?t=7360&amp;sid=87dec92a5b454d762da95797edb78cb2" target="_blank">this forum post</a>. (Here&#8217;s a <a rel="noreferrer noopener" href="https://www.emaculation.com/sheepshaver/SheepShaver_universal_20220913.zip" target="_blank">direct link</a> for the version I used.) That post also links to <a rel="noreferrer noopener" href="https://www.emaculation.com/doku.php/sheepshaver_mac_os_x_setup" target="_blank">this wiki page</a> with instructions on how to set it up, which is a bit more complicated than one might expect.</p>


<div class="wp-block-image">
<figure class="alignright size-full is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-8.07.15-PM.png" alt="" class="wp-image-1144" style="width:160px;height:158px" width="160" height="158" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-8.07.15-PM.png 438w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-8.07.15-PM-300x296.png 300w" sizes="auto, (max-width: 160px) 100vw, 160px" /></figure></div>


<p>For instance, in addition to downloading the application, you also must download a copy of the SheepShaver <a rel="noreferrer noopener" href="https://ronaldpr.home.xs4all.nl/sheepshaverforum/SheepShaver_folder.zip" target="_blank">folder</a>. (This is mentioned on the form post, but I missed it the first time.) Then, you have to put into that folder a copy of the SheepShaver application as well as a ROM file (i.e. an extracted copy of the firmware for an actual Mac compatible with whatever version of MacOS you are trying to run). Neither the forum nor the wiki provide links to download a ROM due to legal concerns, but the wiki page does provide some pretty clear instructions on where you are <em>likely</em> to find one. Finally—and this should be fairly obvious—you need a disk image for an actual MacOS installation disk. They don&#8217;t tell you where to find one of those either, but there are a number of websites that specialize in archiving old software. I&#8217;ve learned a lot about what&#8217;s out there via a site called WinWorld. Just sayin&#8217;&#8230;</p>



<p>One significant limitation of SheepShaver is that—at least according to all the documentation I&#8217;ve seen—it only works for versions of MacOS up to and including 9.0.4. I couldn&#8217;t get the emulator to boot from a 9.2.1 install image, so I&#8217;ll take that as confirmation.</p>



<p>However, as you&#8217;ll see in just a moment, it <em>is</em> possible run later versions of MacOS, such as the 9.2.x series, via a different emulator.</p>



<h3 class="wp-block-heading">Path #2: UTM</h3>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="806" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.53.24-PM-1024x806.png" alt="" class="wp-image-1120" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.53.24-PM-1024x806.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.53.24-PM-300x236.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.53.24-PM-768x604.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.53.24-PM-1536x1209.png 1536w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.53.24-PM-1600x1259.png 1600w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.53.24-PM.png 1942w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Despite the way I&#8217;ve laid out this article, I actually looked into UTM first, mostly because I had already spent a lot of time playing around with it while trying to install MS-DOS.</p>



<p>As I mentioned earlier, <a rel="noreferrer noopener" href="https://mac.getutm.app/" target="_blank">UTM</a> is basically a wrapper for QEMU, which would otherwise need to be configured using complicated and sketchily documented command line arguments. (I also understand, based on my research, that the UTM developers incorporate some tweaks/patches to QEMU itself when they feel it&#8217;s appropriate.)</p>



<p>The nice thing about QEMU is that it can emulate a <em>ton</em> of different hardware, with plenty of architectures, processors, computer types, and peripheral models to choose from. I had never seen anything before about using QEMU to emulate old, <em>PowerPC</em>-based Macs, but apparently it does have this trick up its sleeve. A quick web search, in fact, brought me to this <a rel="noreferrer noopener" href="https://etiennesprojects.blogspot.com/2021/09/mac-os-9-emulation-on-my-apple-m1-mac.html" target="_blank">blog post</a>, which provides a pretty thorough tutorial for how to configure UTM (and thus QEMU) to do it.</p>



<p>The tutorial works, with some caveats.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="858" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.49.11-PM-1024x858.png" alt="" class="wp-image-1118" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.49.11-PM-1024x858.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.49.11-PM-300x251.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.49.11-PM-768x643.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.49.11-PM.png 1504w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>First, because the post is about a year old (as of September 2022), the instructions and screenshots are based on an older version of UTM. Some of the options and configuration pages have changed. And while the screenshots accurately portray the necessary settings, some of them seem to be skipped or glossed over in the instructions, so I ended up missing a few things the first time through.</p>



<p>That blog, however, included a link to the E-Maculation forum (which is actually how I first found it). As the blogger himself notes, UTM has only a small presence there—just a single thread, as far as I could tell—whereas SheepShaver and QEMU itself get entire categories. Nevertheless, that single thread led me to a <a rel="noreferrer noopener" href="https://github.com/adespoton/utmconfigs" target="_blank">GitHub repository</a> with pre-configured UTM setups for every version of MacOS dating back to 9.1. It&#8217;s way easier to just download one of these and go from there. You just double-click the file, point UTM to your MacOS disk image (have I mentioned that WinWorld is a great source of information about old operating systems?), and click the run button.</p>



<p>You do have to make a small adjustment to the configuration after you finish installing, but the repository maintainer has set up the config files so that the instructions for this show up right there in UTM. Very clever!</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.54.38-PM-1024x634.png" alt="" class="wp-image-1121" style="width:458px;height:283px" width="458" height="283" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.54.38-PM-1024x634.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.54.38-PM-300x186.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.54.38-PM-768x475.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-4.54.38-PM.png 1092w" sizes="auto, (max-width: 458px) 100vw, 458px" /></figure></div>


<h2 class="wp-block-heading">The Outcome</h2>



<p>What I can conclude from this experiment is that there are at least two pretty viable ways to get classic MacOS to boot (inside an emulator) on a Mac powered by Apple Silicon. Thanks to the existence of pre-built configurations and the fact that you don&#8217;t need any special firmware files, UTM is a great choice, particularly if your goal is to run MacOS 9.1 or higher. Meanwhile, despite being a little finicky to set up, SheepShaver remains a reasonable option for running earlier versions.</p>



<p>But what about that second goal—the one about browsing the web? Well&#8230;it&#8217;s complicated.</p>



<p>What I learned is that whether you install MacOS 9.0.4 in SheepShaver or MacOS 9.2.1 in UTM, you <em>will</em> get access to ancient copies of Internet Explorer (versions 4.5 and 5.0, respectively) and even&#8230;<em>Netscape</em>, but neither of these gone-but-not-forgotten browsers are going to be of much use. They&#8217;re both so old that they can&#8217;t even <em>communicate</em> with most modern web servers. And the reason for this, interestingly enough, is security.</p>



<p>In the two decades or so since MacOS 9.2.1 was released, newer and better encryption protocols have been introduced to ensure that our connections to web severs remain sufficiently private. In the interest of backwards compatibility, even as server administrators adopted these newer protocols, they usually left many of the older ones in place—which could be beneficial if you happened to be using, say, a 25-year-old computer. However, now that we are firmly in the 21st century and very few people are <em>actually</em> still using 25-year-old computers, the oldest of those protocols are rarely still available—and many websites don&#8217;t even allow <em>un</em>-encrypted connections anymore!</p>



<p>Out of the box, both the setups I explored could connect to Google&#8217;s homepage without problems. (The rendering left something to be desired, but that&#8217;s beside the point.) </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="639" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.57-PM-1024x639.png" alt="" class="wp-image-1130" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.57-PM-1024x639.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.57-PM-300x187.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.57-PM-768x479.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.57-PM-1536x958.png 1536w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.57-PM-2048x1277.png 2048w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.57-PM-1600x998.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Internet Explorer 5</figcaption></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="639" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.26-PM-2-1024x639.png" alt="" class="wp-image-1134" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.26-PM-2-1024x639.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.26-PM-2-300x187.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.26-PM-2-768x479.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.26-PM-2-1536x958.png 1536w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.26-PM-2-2048x1277.png 2048w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.07.26-PM-2-1600x998.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Netscape Communicator 4.77, which <em>really</em> didn&#8217;t know what to do with Google.</figcaption></figure>



<p>Unfortunately, most other URLs I tried to visit resulted in errors because the server could no longer communicate using the types of encryption that the ancient browsers were fluent in.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="639" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.00.06-PM-1024x639.png" alt="" class="wp-image-1125" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.00.06-PM-1024x639.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.00.06-PM-300x187.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.00.06-PM-768x479.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.00.06-PM-1536x958.png 1536w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.00.06-PM-2048x1277.png 2048w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.00.06-PM-1600x998.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>


<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="639" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.02.30-PM-1024x639.png" alt="" class="wp-image-1126" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.02.30-PM-1024x639.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.02.30-PM-300x187.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.02.30-PM-768x479.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.02.30-PM-1536x958.png 1536w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.02.30-PM-2048x1277.png 2048w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-5.02.30-PM-1600x998.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>That said, there is <em>some</em> good news on this front. For many years, a guy by the name of Cameron Kaiser maintained a very special browser called Classilla. As you might guess from its name, Classilla is a fork of Mozilla, the open source browser that succeeded Netscape and eventually gave rise to Firefox. This fork was specifically designed to work in classic MacOS. And because it traces its roots back to a version of Mozilla originally released in 2008, it is at its core five to seven years &#8220;newer&#8221; technologically than the last compatible versions of Netscape and Internet Explorer, respectively. Plus, it continued to received functionality improvements until the project was officially retired in 2021!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="639" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-09-29-at-2.11.24-PM-1-1024x639.png" alt="" class="wp-image-1136" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-09-29-at-2.11.24-PM-1-1024x639.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-09-29-at-2.11.24-PM-1-300x187.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-09-29-at-2.11.24-PM-1-768x479.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-09-29-at-2.11.24-PM-1-1536x958.png 1536w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-09-29-at-2.11.24-PM-1-2048x1277.png 2048w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-09-29-at-2.11.24-PM-1-1600x998.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Classilla does a pretty decent Google impression.</figcaption></figure>



<p>That&#8217;s the good news. The bad news is that even Classilla can&#8217;t handle the encryption protocols (namely, TLS 1.2 and 1.3) that dominate the World Wide Web of 2022. However, all hope is <em>not</em> lost. The final version of Classilla published before the browser was mothballed includes support for a wonky workaround named Crypto Ancienne. (Yes, that&#8217;s French they&#8217;re speaking&#8230;)</p>



<p>The Classilla website provides setup instructions and download links for Crypto Ancienne <a rel="noreferrer noopener" href="http://www.floodgap.com/software/classilla/carl.html" target="_blank">here</a>. But because nothing can be easy, those downloads only work in some of the oldest versions of Mac OS X or in an obscure Unix-like virtualization environment for classic MacOS called Power MachTen. I understand the reason for this—since the whole point is to be able to use this browser on really old computers—but it doesn&#8217;t help me here. Thankfully, the source code for Crypto Ancienne is available <a rel="noreferrer noopener" href="https://github.com/classilla/cryanc" target="_blank">on GitHub</a> and, I can report, can be compiled rather effortlessly on an Apple Silicon Mac.</p>



<p>In order to follow Classilla&#8217;s &#8220;official&#8221; instructions, I also had to track down and compile the source code for a tool called <a rel="noreferrer noopener" href="https://acme.com/software/micro_inetd/" target="_blank">micro_inetd</a>. The micro_inetd program runs on the host computer and listens for requests for encrypted websites coming from Classilla. It then passes those requests on to a program named &#8220;carl&#8221; (yes, carl), which does all the heavy lifting. Together, these two components act as a rudimentary proxy server—a sort of middleman that (in simplified terms) sends the request out to the desired website&#8217;s server, translates the encrypted response into plaintext, and then relays the unencrypted data back to Classilla.</p>



<p>This is <em>horribly</em> insecure, but it does get the job done.</p>



<p>With this monstrosity of an internet setup in place, I was <em>finally</em> able to surf the web  unimpeded. Well, sort of&#8230;</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="639" src="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-7.15.32-PM-1024x639.png" alt="" class="wp-image-1137" srcset="https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-7.15.32-PM-1024x639.png 1024w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-7.15.32-PM-300x187.png 300w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-7.15.32-PM-768x479.png 768w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-7.15.32-PM-1536x958.png 1536w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-7.15.32-PM-2048x1277.png 2048w, https://teachernerd.com/wp-content/uploads/2022/10/Screen-Shot-2022-10-01-at-7.15.32-PM-1600x998.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">The Washington Post editors have really upped their design game.</figcaption></figure>



<p>Web standards, especially CSS (responsible for layout) and JavaScript (responsible for all kinds of client-side fanciness), have evolved <em>so much</em> since the days of 2008 that in a great many cases, what Classilla ultimately renders on the page is an absolute mess.</p>



<p>By default, Classilla attempts to masquerade as the browser built into a Nokia &#8220;flip-phone&#8221; from 2005, but even this doesn&#8217;t really help. Thanks to advances in responsive web design and the ever-increasing power of modern smartphones, it is no longer all that common for websites to serve a completely different, stripped-down version of their content to mobile users. This means that what we&#8217;re left with, no matter what browser Classilla pretends to be (and it gives you options), is quite often unrenderable gobbledegook.</p>



<p>So what have we learned from all this? Well, for one thing, we&#8217;ve learned that it&#8217;s definitely possible to run three different web browsers in various versions of MacOS 9 via two different emulators running on macOS 12 on an Apple Silicon-powered laptop.</p>



<p>We&#8217;ve also learned that it&#8217;s possible (with some effort) to use <em>one</em> of those browsers to contact a modern web server and actually get back a response.</p>



<p>And as long as you don&#8217;t expect to actually be able to <em>read</em> that response, surfing the web like it&#8217;s 2001 can be a thoroughly rewarding experience!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Run MS-DOS on a Mac with Intel or M-series Processor</title>
		<link>https://teachernerd.com/2022/07/16/how-to-run-ms-dos-on-a-mac-with-intel-or-m-series-processor/</link>
		
		<dc:creator><![CDATA[teacherdan]]></dc:creator>
		<pubDate>Sat, 16 Jul 2022 03:21:26 +0000</pubDate>
				<category><![CDATA[How-Tos]]></category>
		<guid isPermaLink="false">https://teachernerd.com/?p=960</guid>

					<description><![CDATA[Let's imagine for a moment that you're feeling a bit fed up with the state of the world and are yearning for the good old days of the 1990s when, because you were a kid, you were oblivious to much of whatever might have been wrong with the world at that point in time.

Now, suppose the epitome of 90s-era technology for you is taking a trip to your dad's office in the big city, where his corporate computer was <em>just</em> better enough than the crummy one at home that you could reliably use it to play a really cool new game—namely, SimCity 2000. And finally, suppose you'd like to fulfill your craving for nostalgia by playing that game, which was designed for MS-DOS (an OS created in the 80s) on your brand new MacBook Pro (which was released in 2021).

Well, there's a problem. Actually, a few problems (not the least of which is that I have too much time on my hands).]]></description>
										<content:encoded><![CDATA[
<p>Let&#8217;s imagine for a moment that you&#8217;re feeling a bit fed up with the state of the world and are yearning for the good old days of the 1990s when, because you were a kid, you were oblivious to much of whatever might have been wrong with the world at that point in time.</p>



<p>Now, suppose the epitome of 90s-era technology for you is taking a trip to your dad&#8217;s office in the big city, where his corporate computer was <em>just</em> better enough than the crummy one at home that you could reliably use it to play a really cool new game—namely, SimCity 2000. And finally, suppose you&#8217;d like to fulfill your craving for nostalgia by playing that game, which was designed for MS-DOS (an OS created in the 80s) on your brand new MacBook Pro (which was released in 2021).</p>



<p>Well, there&#8217;s a problem. Actually, a few problems (not the least of which is that I have too much time on my hands).</p>



<p>First, you can&#8217;t run MS-DOS on a Mac. Apple computers are designed to run macOS and macOS only. Okay, that&#8217;s not technically true. Ever since Apple switched to Intel processors, their Boot Camp tool has made it possible to run various versions of Microsoft Windows on their machines. And with a bit of finagling, you <em>can</em> install Linux distributions and other operating systems. Apple just doesn&#8217;t provide any support for it.</p>



<p>So&#8230;why not MS-DOS? The simple answer is, I&#8217;m not sure; I&#8217;ve never actually tried it. My suspicion is that it&#8217;s just too old. But even if it <em>were</em> possible at some point in time, it&#8217;s not anymore (at least, as we will soon see, not <em>natively</em>).</p>



<p>In 2020, Apple announced that over the next few years, they would transition their entire computer lineup away from the Intel processors the company had been using for the past decade. Instead, Macs would now be powered by a souped up version of the home-grown processors that Apple had been using in their iPhones and iPads for many years.</p>



<p>On the one hand, this was great news. Apple&#8217;s smartphone processors were known to be very powerful and energy efficient, and early reviews of the desktop/laptop versions confirmed that Apple&#8217;s tech was, in many ways, miles ahead of the competition. This played a big role in my decision to buy one of Apple&#8217;s new machines.</p>



<p>On the other hand, Apple&#8217;s decision posed a problem for oddballs like me that find it amusing to get their computers to do things they weren&#8217;t technically designed to do (like running operating systems that aren&#8217;t macOS on an Apple computer).</p>



<p>Here&#8217;s the problem: Intel&#8217;s modern, consumer-oriented processors (as well as those manufactured by its primary competitor, AMD) use an architecture often referred to as &#8220;x86_64.&#8221; This architecture has at its foundation the same basic instruction set, the collection of routines and commands baked into the processors&#8217; circuitry, as the Intel processors (e.g. the 386, 486, and Pentium) used in the original &#8220;IBM-compatible&#8221; personal computers that dominated the 1980s and early 1990s—in other words, the kind of computers you can run MS-DOS on. (The The &#8220;64&#8221; in the name refers to how the architecture has been <em>extended</em> to support modern, 64-bit computing.)</p>



<p>Apple&#8217;s M-series processors, meanwhile, are built around an architecture or instruction set known as &#8220;ARM.&#8221; Trying to run software compiled for an x86-based processor (like MS-DOS or even most versions of Windows) on an ARM-based processor is like trying to drive a car on the ocean or attempting to breath without scuba gear underwater; the most basic assumptions about the environment are completely different.</p>



<p>Unfortunately, this incompatibility is so foundational that even popular tools for creating virtual machines, like Parallels or VMWare Fusion, won&#8217;t do the trick.</p>



<p>Virtualization software lets you share a singe host machine&#8217;s resources amongst several simulated client &#8220;machines,&#8221; but that only works if those clients can understand the host&#8217;s language and exist in the host&#8217;s hardware environment in the first place. So if you wanted to run, say, Windows in a virtual machine on a Mac with an M1 processor, you&#8217;d need a version of Windows that was built for ARM-based processors. This does actually exist—it&#8217;s what Microsoft uses in many of their Surface laptops and tablets—and you can install it in Parallels with just a few clicks.</p>



<p>But if you want to use your brand new MacBook Pro to run SimCity 2000 in MS-DOS, which is <em>definitely</em> not ARM-compatible, you need more than just virtualization. What you need is an <em>emulator</em>. </p>



<h2 class="wp-block-heading">Objective</h2>



<p>Unlike virtualization, which is used to <em>share</em> existing resources, emulation uses software to <em>mimic</em> (or pretend to be) a particular set of hardware that is not physically present.</p>



<p>In the following tutorial, I&#8217;m going to walk you through how to use an emulator to run MS-DOS on a Mac. (Incidentally, the same tools will also work on an Intel-based Mac.) I&#8217;ll also walk you through installing some drivers and tweaking a few settings to make it a bit more convenient to use and to ensure that you can actually install and run a fancy-shmancy late-era DOS game like SimCity 2000.</p>



<p>I recognize that the objective here is super niche. But it turns out it&#8217;s <em>so</em> niche that I actually struggled to find a good set of instructions for this. So in addition to providing an opportunity to talk a bit about processor architecture and the difference between virtualization and emulation (because, let&#8217;s face it, I&#8217;m a teacher and I love explaining things), hopefully this article can also serve as something of a definitive guide to this particular (albeit weird) task.</p>



<h2 class="wp-block-heading">Materials</h2>



<p>I tested this tutorial on my M1-based MacBook Pro. You should be able to follow it on any other M-series laptop or desktop as well. The software we&#8217;ll be using should work on Intel-based Macs too, but I haven&#8217;t explicitly tested it yet.</p>



<p>Besides the computer, you&#8217;ll need a few more things to get this to work:</p>



<ul class="wp-block-list">
<li><strong>Emulation Software: </strong>We&#8217;ll be using UTM. This app bundles QEMU, an open source emulator that has been around forever, and extends it by providing a convenient user interface. You can buy UTM for for $9.99 <a rel="noreferrer noopener" href="https://apps.apple.com/us/app/utm-virtual-machines/id1538878817?mt=12" target="_blank">on the App Store</a> or download it for free <a rel="noreferrer noopener" href="https://mac.getutm.app/" target="_blank">from the developer&#8217;s website</a>. You&#8217;re getting the same app either way; it&#8217;s just a question of whether you want to give some monetary support to the people behind it.</li>



<li><strong>MS-DOS Disk Images: </strong>The 100% most legal way to obtain these disk images is to create them from your own set of physical MS-DOS installation disks. What? You don&#8217;t have DOS installation disks lying around? Who <em>are</em> you?? Alright, look: I&#8217;m not going to just give you a link to pirated software. But if you&#8217;re the sort of person who figures some lawyer out in Redmond, WA is not going to come banging on your front door because you downloaded a piece of ancient software that no one is actually selling anymore, then I have one word for you: WinWorld. Do with that what you will. Oh, and if you&#8217;re trying to track down those, um, physical disks in your basement, I&#8217;ll point out that the version you really want to be on the lookout for is &#8220;MS-DOS 6.22 Plus Enhanced Tools,&#8221; and it would be mighty convenient if you used the version that comes on 3.5&#8243; diskettes. (However, props to you if you manage to find some working 5.25&#8243; floppies in your basement!)</li>



<li><strong>Drivers: </strong>At bare minimum, playing around with DOS will be a lot easier with a working mouse and the ability to mount CD-ROM images since so many programs and games were distributed that way. There are several drivers to choose from and a bunch of places where you can find them. I recommend going to <a rel="noreferrer noopener" href="https://www.computerhope.com/download/hardware.htm" target="_blank">Computer Hope</a> and downloading <em>oakcdrom.sys</em> and <em>mouse.zip</em>. Put them somewhere safe, and I&#8217;ll explain what to do with them later!</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Note:</strong> A more automated (and thus &#8220;easier&#8221;) way to run old DOS games in just about any operating system is a well-known emulator called <a rel="noreferrer noopener" href="https://www.dosbox.com/" target="_blank">DOSBox</a>. I acknowledge the existence of this app and have even played with it myself. The following tutorial is for folks who want to get their hands a bit dirtier and experience the full process of installing and configuring the genuine MS-DOS operating system (plus an emulator) from scratch.</p>
</blockquote>



<h2 class="wp-block-heading">Step 1: Create a Virtual Machine</h2>



<p>So we&#8217;re going to start by opening up the UTM app. If you&#8217;re running it for the very first time, it&#8217;ll probably look something like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.06.33-PM-1024x798.png" alt="" class="wp-image-964" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.06.33-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.06.33-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.06.33-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.06.33-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.06.33-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.06.33-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Click on the box labeled &#8220;Create a New Virtual Machine.&#8221; Now, you should see two options: virtualize or emulate.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.08.41-PM-1024x798.png" alt="" class="wp-image-966" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.08.41-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.08.41-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.08.41-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.08.41-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.08.41-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.08.41-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>As we discussed earlier, for this project to work, we need to use an <strong>emulator</strong>, so go ahead and choose the &#8220;Emulate&#8221; option.</p>



<p>Next, it&#8217;s going to ask you what kind of operating system you want to install.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.12.19-PM-1-1024x798.png" alt="" class="wp-image-971" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.12.19-PM-1-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.12.19-PM-1-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.12.19-PM-1-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.12.19-PM-1-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.12.19-PM-1-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.12.19-PM-1.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Since MS-DOS is definitely not on the list, we&#8217;re going to select &#8220;Other.&#8221;</p>



<p>Now, UTM should be asking us for a Boot ISO Image.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.23.11-PM-1024x798.png" alt="" class="wp-image-973" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.23.11-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.23.11-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.23.11-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.23.11-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.23.11-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.23.11-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>What it&#8217;s looking for is an image of a CD or DVD to install from, but we don&#8217;t have one of those. So we&#8217;re just going to click the checkbox next to &#8220;Skip ISO boot.&#8221; The screen should now look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.25.09-PM-1024x798.png" alt="" class="wp-image-974" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.25.09-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.25.09-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.25.09-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.25.09-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.25.09-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.25.09-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Go ahead and click &#8220;Continue.&#8221;</p>



<p>The next page asks about hardware.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.26.40-PM-1024x798.png" alt="" class="wp-image-975" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.26.40-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.26.40-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.26.40-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.26.40-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.26.40-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.26.40-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The default settings are too modern for us, so we&#8217;re going to make a few adjustments:</p>



<ul class="wp-block-list">
<li><strong>Architecture: </strong>The default is &#8220;x86_64,&#8221; which describes the architecture of modern Intel and AMD consumer processors. This might work just fine since they are theoretically backwards-compatible with their predecessors, but just to be safe, let&#8217;s change this to &#8220;i386 (x86).&#8221; This should get the emulator to more closely mimic the less fancy processor architecture from the 80s and 90s.</li>



<li><strong>System: </strong>This setting tells the emulator what kind of chipset to mimic. Essentially, we&#8217;re telling it what sort of motherboard the pretend processor is being plugged into. By default, UTM wants to use a system that is once again too modern for us. We&#8217;re going to change it something based on much older components: &#8220;Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-7.0) (pc).&#8221;</li>



<li><strong>Memory: </strong>If we don&#8217;t change this, the emulator will try to allocate way too much memory for our virtual machine. MS-DOS 6.22 can only recognize up to 64 MB, so let&#8217;s set this number accordingly.</li>



<li><strong>CPU Cores: </strong>I assume that &#8220;Default&#8221; means just one processor core, but just to be safe, let&#8217;s manually change that to &#8220;1.&#8221;</li>
</ul>



<p>When all is said and done, our hardware settings should look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.43.30-PM-1024x798.png" alt="" class="wp-image-977" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.43.30-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.43.30-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.43.30-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.43.30-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.43.30-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.43.30-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Once again, let&#8217;s click &#8220;Continue.&#8221;</p>



<p>The following page asks us how large a virtual hard drive we want to create.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.46.03-PM-1024x798.png" alt="" class="wp-image-978" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.46.03-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.46.03-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.46.03-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.46.03-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.46.03-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.46.03-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Although the default number is actually too large for DOS to handle, we&#8217;re going to leave it alone for now. UTM uses this setting to automatically create a virtual hard drive. Unfortunately, when using some older versions of UTM, I found that this drive got corrupted every time I shut down the machine. So just to be safe, we&#8217;re going to manually create the virtual hard drive later and attempt to adjust one of the advanced settings. For now, just click &#8220;Continue.&#8221;</p>



<p>The next page is titled Shared Directory.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.51.56-PM-1024x798.png" alt="" class="wp-image-979" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.51.56-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.51.56-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.51.56-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.51.56-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.51.56-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.51.56-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>This functionality is designed to make it easier to share files between our host machine and our virtual machine, but I&#8217;m not convinced this is possible within MS-DOS. We&#8217;re just going to skip it and click &#8220;Continue.&#8221;</p>



<p>The final page shows us an overview of all the settings we chose.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.52.33-PM-1024x798.png" alt="" class="wp-image-980" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.52.33-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.52.33-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.52.33-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.52.33-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.52.33-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.52.33-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>There are two thing we should do here. First, let&#8217;s give the machine a more useful name, like &#8220;MS-DOS.&#8221; Then, we&#8217;re going to check the box labeled &#8220;Open VM Settings&#8221; because there are several more adjustments we need to make.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.54.36-PM.png" alt="" class="wp-image-981" width="432" height="101" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.54.36-PM.png 864w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.54.36-PM-300x70.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.54.36-PM-768x180.png 768w" sizes="auto, (max-width: 432px) 100vw, 432px" /></figure></div>


<p>Once that&#8217;s done, we can click &#8220;Save.&#8221;</p>



<h2 class="wp-block-heading">Step 2: Do Some Additional Configuration</h2>



<p>We should now be looking at the virtual machine settings interface.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.55.35-PM-1024x798.png" alt="" class="wp-image-982" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.55.35-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.55.35-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.55.35-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.55.35-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.55.35-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.55.35-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>We&#8217;re going to use this to adjust some more &#8220;advanced&#8221; settings to ensure that our VM works as expected. Let&#8217;s start by clicking on <strong>System</strong> in the sidebar.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.57.11-PM-1024x798.png" alt="" class="wp-image-983" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.57.11-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.57.11-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.57.11-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.57.11-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.57.11-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-3.57.11-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>You&#8217;ll see some of the settings here that we chose earlier, but we&#8217;re going to make one additional adjustment. Right now, under, CPU, it should say &#8220;Default.&#8221; I&#8217;m not sure what kind of processor this machine actually defaults to, so we&#8217;re going to choose something more specific.</p>



<p>Let&#8217;s set the CPU to &#8220;486.&#8221;</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.31.56-PM-1024x798.png" alt="" class="wp-image-985" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.31.56-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.31.56-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.31.56-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.31.56-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.31.56-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.31.56-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Launched in 1989, the Intel 486 processor is the oldest piece of hardware on this list and was still in use when MS-DOS 6.22 was released in 1994.</p>



<p>Next, let&#8217;s click on <strong>QEMU</strong> in the sidebar.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="773" src="https://teachernerd.com/wp-content/uploads/2023/03/Screenshot-2023-03-09-at-7.19.22-PM-1024x773.png" alt="" class="wp-image-1297" srcset="https://teachernerd.com/wp-content/uploads/2023/03/Screenshot-2023-03-09-at-7.19.22-PM-1024x773.png 1024w, https://teachernerd.com/wp-content/uploads/2023/03/Screenshot-2023-03-09-at-7.19.22-PM-300x226.png 300w, https://teachernerd.com/wp-content/uploads/2023/03/Screenshot-2023-03-09-at-7.19.22-PM-768x580.png 768w, https://teachernerd.com/wp-content/uploads/2023/03/Screenshot-2023-03-09-at-7.19.22-PM-1536x1160.png 1536w, https://teachernerd.com/wp-content/uploads/2023/03/Screenshot-2023-03-09-at-7.19.22-PM-1600x1208.png 1600w, https://teachernerd.com/wp-content/uploads/2023/03/Screenshot-2023-03-09-at-7.19.22-PM.png 2024w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>On this page, we&#8217;re going to first <em>uncheck</em> the box labeled &#8220;UEFI Boot.&#8221; This will disable the more modern startup system that current computers use and force the virtual machine to use the legacy system that&#8217;s been around since the days of MS-DOS.</p>



<p>Then, just to be safe, we&#8217;re going to check the box for &#8220;Force PS/2 controller.&#8221; This will make extra certain that DOS is able to respond to our mouse and keyboard by ensuring that the machine emulates the PS/2 ports that these components used to plug into back before USB.</p>



<p>The settings should now look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.43.05-PM-1024x798.png" alt="" class="wp-image-990" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.43.05-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.43.05-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.43.05-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.43.05-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.43.05-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.43.05-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Everything else on this page can be left as is.</p>



<p>Now we&#8217;re going to go to the <strong>Input</strong> page.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.44.12-PM-1024x798.png" alt="" class="wp-image-991" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.44.12-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.44.12-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.44.12-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.44.12-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.44.12-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.44.12-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>On this page we need to disable USB support. I&#8217;m not sure why this makes a difference, but all I know is that every time I tried to use DOS&#8217;s built-in file editor, the program would crash as soon as I tried to open a menu to save what I was working on. For some reason, once I disabled USB support, this stopped happening.</p>



<p>So, next to where it says &#8220;USB Support,&#8221; go ahead and select &#8220;Off.&#8221;</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.47.50-PM-1024x798.png" alt="" class="wp-image-994" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.47.50-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.47.50-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.47.50-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.47.50-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.47.50-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.47.50-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The next page we&#8217;ll take a look at is <strong>Sound</strong>. I have not yet tried to get sound to work, but my guess is that we should set the Emulated Audio Card to &#8220;Creative Sound Blaster 16&#8221; since that was a pretty typical device from the era.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.51.59-PM-1024x798.png" alt="" class="wp-image-997" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.51.59-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.51.59-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.51.59-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.51.59-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.51.59-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.51.59-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The last thing we need to do is set up the virtual drives. At the bottom of the sidebar, you&#8217;ll see a section labeled &#8220;Drives.&#8221; Go ahead and select the first one.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.52.12-PM-1024x798.png" alt="" class="wp-image-998" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.52.12-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.52.12-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.52.12-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.52.12-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.52.12-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.52.12-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>I mentioned earlier that UTM tries to automatically create a drive for us but that my testing found that this drive doesn&#8217;t work correctly. So we&#8217;re going to remove it by clicking the &#8220;Delete Drive&#8221; button.</p>



<p>Once we click that, the page we were looking at should disappear.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.53.40-PM-1024x798.png" alt="" class="wp-image-999" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.53.40-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.53.40-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.53.40-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.53.40-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.53.40-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.53.40-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Now we need to select &#8220;New Drive&#8221; from the bottom of the menu, which should cause a little panel to pop up.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="792" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.54.05-PM-1024x792.png" alt="" class="wp-image-1000" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.54.05-PM-1024x792.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.54.05-PM-300x232.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.54.05-PM-768x594.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.54.05-PM-1536x1188.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.54.05-PM-1600x1237.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.54.05-PM.png 1976w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>We&#8217;re going to start by creating a virtual CD-ROM drive. So check the box next to &#8220;Removable&#8221; and make sure that the <em>interface</em> is set to &#8220;IDE.&#8221;</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="612" height="322" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.56.18-PM.png" alt="" class="wp-image-1002" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.56.18-PM.png 612w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.56.18-PM-300x158.png 300w" sizes="auto, (max-width: 612px) 100vw, 612px" /></figure></div>


<p>Next, click &#8220;Create.&#8221;</p>



<p>The drive should now show up at the bottom of the menu. If you click it, you should see this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.57.35-PM-1024x798.png" alt="" class="wp-image-1003" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.57.35-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.57.35-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.57.35-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.57.35-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.57.35-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-4.57.35-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Make sure the <em>Image Type</em> is set to &#8220;CD/DVD (ISO) Image&#8221; and the <em>Interface</em> is set to &#8220;IDE.&#8221;</p>



<p>Now, we&#8217;re going to create a virtual floppy disk drive for our virtual computer. Click on &#8220;New Drive&#8221; again in the sidebar, and choose the exact same settings as before. Then, be sure to click on the <em>newly</em> created drive (the one at the bottom of the list). Your screen should now look something like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.01.30-PM-1024x798.png" alt="" class="wp-image-1004" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.01.30-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.01.30-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.01.30-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.01.30-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.01.30-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.01.30-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>In order to make this virtual drive mimic a floppy drive, we need to change a couple settings. First, we need to set the <em>Image Type</em> to &#8220;Disk Image.&#8221; Second, we must change the <em>Interface</em> to &#8220;Floppy.&#8221; Our new settings should look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.02.41-PM-1024x798.png" alt="" class="wp-image-1005" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.02.41-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.02.41-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.02.41-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.02.41-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.02.41-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.02.41-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Notice that our drive&#8217;s entry at the bottom of the menu has changed to say &#8220;Floppy Drive.&#8221; Perfect!</p>



<p>We have one last virtual device to create before we can fire up this virtual machine: the hard drive. Let&#8217;s click on &#8220;New Drive&#8221; one last time. But this time, we&#8217;re going to use some different settings. We&#8217;re going to leave the &#8220;Removable&#8221; box <em>unchecked</em> and make sure the interface is set to &#8220;IDE.&#8221; The size should be set no larger than 2 GB because MS-DOS 6.22 cannot recognize anything bigger than that.</p>



<p>Finally, we&#8217;re going to <em>check</em> the box next to &#8220;Raw Image.&#8221; This is the key setting that prevents the corruption issue I talked about before. (By default, UTM tries to save space on the host computer by creating a relatively small file to represent the hard drive and then growing it as additional space is needed. Something about this breaks our MS-DOS installation, so by selecting the &#8220;raw&#8221; option, we create a file the actual size of the hard drive which never needs to change.) The appropriate settings should look like this:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="612" height="486" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.11.45-PM.png" alt="" class="wp-image-1007" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.11.45-PM.png 612w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.11.45-PM-300x238.png 300w" sizes="auto, (max-width: 612px) 100vw, 612px" /></figure>



<p><em><strong>Note: </strong>Version 2.1.6 of UTM appears to have a bug that prevents the &#8220;Raw Image&#8221; checkbox from working. (It&#8217;s possible that other versions have this bug as well; I haven&#8217;t tested this extensively.) If you can&#8217;t check the box, don&#8217;t worry about it. The original bug that led me to include this step in the first place seems to have been fixed in more recent versions. I tested a virtual machine using the default settings in Version 2.1.6, and it worked just fine!</em></p>



<p>Once you&#8217;ve got your disk image configured, go ahead and click &#8220;Create.&#8221;</p>



<p>Now, if we click on the new drive in the menu, it should look something like the image below. (If you were unable to create a &#8220;Raw Image&#8221; due to the bug described above, your screen will look a little different. But based on my testing, it should still work.)</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.14.33-PM-1024x798.png" alt="" class="wp-image-1008" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.14.33-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.14.33-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.14.33-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.14.33-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.14.33-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.14.33-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>We are <em>finally</em> finished configuring the virtual machine, so let&#8217;s click the &#8220;Save&#8221; button in the bottom right corner.</p>



<h2 class="wp-block-heading">Step 3: &#8220;Insert&#8221; Your Virtual Installation Disk</h2>



<p>We should now be on a screen that looks something like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="798" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.17.16-PM-1024x798.png" alt="" class="wp-image-1009" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.17.16-PM-1024x798.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.17.16-PM-300x234.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.17.16-PM-768x599.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.17.16-PM-1536x1197.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.17.16-PM-1600x1247.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.17.16-PM.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>(If not, make sure the virtual machine is selected in the sidebar.)</p>



<p>We&#8217;re just about ready to actually get DOS running, but we&#8217;ve got just one more little step: We need to virtually insert our virtual installation disk into our virtual floppy drive.</p>



<p>To do this, we either need to make UTM&#8217;s window bigger or scroll down to the bottom of the page so that we can see two drop-down menus. One is for our virtual CD-ROM drive, and the other is for our virtual floppy drive. I&#8217;ve circle them in the screenshot below.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="806" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.19.59-PM-1024x806.png" alt="" class="wp-image-1010" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.19.59-PM-1024x806.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.19.59-PM-300x236.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.19.59-PM-768x604.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.19.59-PM-1536x1209.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.19.59-PM-1600x1259.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.19.59-PM.png 1942w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Click on the drop-down that says &#8220;Removable&#8221; and choose the &#8220;Browse&#8230;&#8221; option. This will open a file browser, which you can use to find your first MS-DOS disk image. My set came with three, so I&#8217;m going to choose the file named &#8220;Disk1.img.&#8221;</p>



<p>Once you&#8217;ve selected your disk image, its filename will show up next to the drop-down menu. (Look at the bottom-right corner of the image below, and you&#8217;ll see that it now says &#8220;Disk1.img.&#8221;)</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="806" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.24.18-PM-1024x806.png" alt="" class="wp-image-1011" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.24.18-PM-1024x806.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.24.18-PM-300x236.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.24.18-PM-768x604.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.24.18-PM-1536x1209.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.24.18-PM-1600x1259.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.24.18-PM.png 1942w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Step 4: Launch the Virtual Machine</h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Note:</strong> We&#8217;re about to start up the virtual machine. If at any time you discover that your mouse has gotten &#8220;stuck&#8221; in the virtual machine&#8217;s window, press the <kbd><strong>CTRL+ALT</strong></kbd> or <kbd><strong>CTRL+Option</strong></kbd> keys on your keyboard to &#8220;release&#8221; it.</p>
</blockquote>



<p>Okay, it&#8217;s time for the moment of truth! I count three different &#8220;play&#8221; buttons you can click to start this virtual machine. Any of them will work, but let&#8217;s use the one in the toolbar at the top of the window. (It&#8217;s the one shaped like a triangle.)</p>



<p>After we click the button, a new window will pop up. This window is our virtual machine&#8217;s display. You should see some status messages flash across the virtual screen, and eventually, the MS-DOS installer will appear. You&#8217;ll know it&#8217;s working if you see some classic gray-white text on a blue background.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.30.40-PM-1024x677.png" alt="" class="wp-image-1012" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.30.40-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.30.40-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.30.40-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.30.40-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.30.40-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.30.40-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Step 5: Install MS-DOS</h2>



<p>All we need to do now is press the <kbd><strong>Enter</strong></kbd> key, just like the instructions on the screen say, which should bring us to the following screen:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.32.29-PM-1024x677.png" alt="" class="wp-image-1013" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.32.29-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.32.29-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.32.29-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.32.29-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.32.29-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.32.29-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>This step is telling us that we need to format the virtual hard drive. We just need to make sure &#8220;Configure unallocated disk space&#8221; is selected and press <strong><kbd>Enter</kbd></strong> again.</p>



<p>We&#8217;ll now see this helpful message informing us that the computer is about to reboot. (Remember: This is referring to the <i>virtual</i> computer.) It also says to &#8220;make sure Setup Disk 1 is in drive A.&#8221; We can feel pretty confident that this is already the case; otherwise, we would have never made it to this step!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.41.03-PM-1024x677.png" alt="" class="wp-image-1014" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.41.03-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.41.03-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.41.03-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.41.03-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.41.03-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.41.03-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Press <strong><kbd>Enter</kbd></strong> one more time so that the installer can do its thing.</p>



<p>The virtual machine should reboot, and you should soon see a progress screen while the hard drive is formatted. Eventually you&#8217;ll get to a screen asking you to confirm some settings:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.42.36-PM-1024x677.png" alt="" class="wp-image-1015" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.42.36-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.42.36-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.42.36-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.42.36-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.42.36-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.42.36-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Make sure the Date/Time, country, and language are correct. (Remember that you can only use the keyboard to navigate this interface, so you&#8217;ll have to use the arrow keys.) Then, select &#8220;The settings are correct&#8221; and press <kbd><strong>Enter</strong></kbd>.</p>



<p>Now, the installer is going to ask you where to actually install everything.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.44.24-PM-1024x677.png" alt="" class="wp-image-1016" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.44.24-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.44.24-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.44.24-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.44.24-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.44.24-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.44.24-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>I actually find it pretty interesting that you can put your DOS files wherever you want, but for simplicity&#8217;s sake, let&#8217;s just stick with the default (&#8220;C:\DOS&#8221;). All we need to do here is press<strong> <kbd>Enter</kbd>.</strong></p>



<p>Now, we should see a progress bar as files are copied to the virtual hard drive. Eventually, the progress will halt because we need to switch to the next install disk.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.49.33-PM-1024x677.png" alt="" class="wp-image-1017" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.49.33-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.49.33-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.49.33-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.49.33-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.49.33-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.49.33-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Ah, life in the 80s&#8230;</figcaption></figure>



<p>To switch the disk, we need to click the little icon in the toolbar that looks like a CD. This should pop up a drop-down menu. Hover over &#8220;Disk Image&#8221; and choose &#8220;Change.&#8221; This will open a file browser where you can find your next disk. Mine is called &#8220;Disk2.img.&#8221; Once the disk is selected, you can press <strong><kbd>Enter</kbd></strong>, and the installation should continue.</p>



<p>You will likely have to switch disks one more time before it&#8217;s over. Eventually, you&#8217;ll see a screen telling you to remove all floppy disks from their drives.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.51.35-PM-1024x677.png" alt="" class="wp-image-1018" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.51.35-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.51.35-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.51.35-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.51.35-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.51.35-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.51.35-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>To eject the virtual floppy disk, go to that same menu we used to swap disks and choose the &#8220;Eject&#8221; option.</p>



<p>Once the disk is ejected, we can press <kbd><strong>Enter</strong></kbd>. The installer will essentially say good-bye to us and instruct us to press <strong><kbd>Enter</kbd></strong> one last time.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.54.50-PM-1024x677.png" alt="" class="wp-image-1019" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.54.50-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.54.50-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.54.50-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.54.50-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.54.50-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.54.50-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>If we follow its directions, our virtual machine should reboot. And finally, if all has gone to plan, we should be greeted by the famous MS-DOS command prompt:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.55.31-PM-1024x677.png" alt="" class="wp-image-1020" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.55.31-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.55.31-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.55.31-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.55.31-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.55.31-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-5.55.31-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>I take it all back. You really <em>can</em> run DOS on a Mac!</p>



<h2 class="wp-block-heading">Step 6: Take a Trip Down Memory Lane</h2>



<p>I could just end this tutorial here, now that I have sort of proved a point. But the real goal of this exercise was to be able to play a childhood computer game. So I&#8217;m going to walk you through a few more configuration steps.</p>



<p>We&#8217;re going to start by setting up <em>extended memory</em>. DOS originally could only deal with 640 kilobytes of memory, which is&#8230;not very much at all. As software applications got bigger and more complicated, and as newer hardware was developed to accommodate them, DOS needed to follow suit. However, DOS&#8217;s original memory limitations never technically went away. Microsoft and other developers basically just found ways to work around them.</p>



<p>Explaining DOS memory management is probably beyond the scope of this tutorial, and frankly, I don&#8217;t fully understand it myself. But you can get an idea of what I&#8217;m talking about by typing in <code>mem</code> at the command prompt and pressing <strong><kbd>Enter</kbd></strong>.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.05.42-PM-1024x677.png" alt="" class="wp-image-1022" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.05.42-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.05.42-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.05.42-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.05.42-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.05.42-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.05.42-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>What this screen shows you is that DOS still only has 640K of &#8220;conventional&#8221; memory available. (It actually shows up as 639K in my VM. I&#8217;m sure that extra 1K is used for something important.)</p>



<p>All the rest of our memory is listed as &#8220;Extended (XMS)&#8221; memory. This memory exists because DOS 6.22 is set up by default to load a special driver, called HIMEM.SYS, that works some magic to make all this extra memory available.</p>



<p>Let&#8217;s take a look at where it happens by typing in <code>edit config.sys</code> at the command prompt and pressing <kbd><strong>Enter</strong></kbd>. This should open up the beautiful (and very blue) MS-DOS file editor.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.08.51-PM-1024x677.png" alt="" class="wp-image-1023" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.08.51-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.08.51-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.08.51-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.08.51-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.08.51-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.08.51-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>We&#8217;re looking at a file named CONFIG.SYS that lives in the root directory of the hard drive. At some point in DOS&#8217;s boot-up sequence, it loads this configuration file and follows the instructions contained within. Lines beginning with &#8220;DEVICE=&#8221; are used to load drivers that control system functionality. One of those drivers is HIMEM.SYS, which I mentioned above.</p>



<p>This HIMEM.SYS does a good job at sort of opening up access to the expanded memory, but apparently, if we want to actually <em>use</em> that extra memory, we need to load what&#8217;s called a memory <em>manager</em>. Fortunately enough, Microsoft includes one with DOS; they just don&#8217;t enable it by default. So we&#8217;re going to add the following line to the file immediately after the one for HIMEM.SYS:</p>



<pre class="wp-block-code"><code>DEVICEHIGH=C:\DOS\EMM386.EXE ram highscan notr i=b000-b7ff</code></pre>



<p>We&#8217;re heading into some serious magic code territory here. The most important piece is <code>DEVICEHIGH=C:\DOS\EMM386.EXE</code>. This loads the expanded memory manger into the &#8220;high&#8221; memory area enabled by HIMEM.SYS. The rest of that gobbledegook is a series of options to tweak some aspects of how the memory manager operates. I borrowed those options from <a rel="noreferrer noopener" href="https://www.legroom.net/howto/msdos" target="_blank">this incredibly informative tutorial</a>, so if you want to know what they actually do, I would encourage you to check it out.</p>



<p>Anyway, once you&#8217;ve edited the file, it should look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.20-PM-1024x677.png" alt="" class="wp-image-1027" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.20-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.20-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.20-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.20-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.20-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.20-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Next, we need to save our changes and exit the editor. If you&#8217;re using a Windows/PC keyboard, you&#8217;ll press <kbd><strong>ALT+F</strong></kbd> to open the file menu. If, like me, you&#8217;re using a standard Mac keyboard, you&#8217;ll need to press <kbd><strong>Option+F</strong></kbd> instead. (Apple&#8217;s <kbd><strong>Option</strong></kbd> key always corresponds to the <kbd><strong>ALT</strong></kbd> key.)</p>



<p>You should see the menu pop open like so:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.33-PM-1024x677.png" alt="" class="wp-image-1028" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.33-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.33-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.33-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.33-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.33-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.36.33-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Now, you can use the arrow keys on your keyboard to navigate to &#8220;Save&#8221; and then press <kbd><strong>Enter</strong></kbd>. Or, you can speed things up by half a second and just press the <kbd><strong>S</strong></kbd> key. (Notice how it&#8217;s been highlighted to let you know that this is the shortcut.)</p>



<p>We should now open the file menu a second time (<strong><kbd>ALT+F</kbd></strong> or <strong><kbd>Option+F</kbd></strong>) and choose &#8220;Exit,&#8221; which will take us back to the command prompt.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.29.04-PM-1024x677.png" alt="" class="wp-image-1026" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.29.04-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.29.04-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.29.04-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.29.04-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.29.04-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.29.04-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>To see if our changes worked, we need to reboot the computer. On a PC keyboard, we would press <kbd><strong>CTRL+ALT+DEL</strong></kbd> to reboot. On my full-length Mac keyboard (the kind that includes a numeric keypad all the way on the right), I can hold down <strong><kbd>CTRL+Option</kbd></strong> and then press the forward delete key (the one that appears above the arrow keys in the little cluster between the main keyboard and the numeric keypad). If you&#8217;re using a small Mac keyboard that doesn&#8217;t have a forward delete key, you&#8217;ll need to hold down <kbd><strong>CTRL+Option+Fn</strong></kbd> and then press the regular <kbd><strong>Delete</strong></kbd> key.</p>



<p>If you&#8217;ve properly performed the so-called &#8220;three-fingered salute&#8221; (though I guess it&#8217;s a four-fingered salute on small Mac keyboards), the virtual machine should reboot and eventually take you to a new command prompt.</p>



<p>We can test whether our changes worked by typing <code>mem</code> once again, pressing <font face="monospace"><b>Enter</b></font>, and inspecting the output:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.39.41-PM-1024x677.png" alt="" class="wp-image-1029" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.39.41-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.39.41-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.39.41-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.39.41-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.39.41-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.39.41-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>A couple things have changed: my missing 1K of conventional memory has actually returned, and now we see this note about how EMM386 is using XMS memory to simulate EMS memory. We don&#8217;t need to worry too much about what that nonsense means, but you can read up on it in the tutorial I linked above if you want.</p>



<p>We&#8217;re going to make one more change now to ensure optimal memory management. We&#8217;re going to type in <code>edit config.sys</code> again and press <kbd><strong>Enter</strong></kbd> so that we can tweak one of the lines in the file.</p>



<p>Find the line that says <code>DOS=HIGH</code> and change it to say <code>DOS=HIGH,UMB</code>. (&#8220;UMB&#8221; stands for &#8220;Upper Memory Block.&#8221;)</p>



<p>The actual details of what that does are a little hairy, but if you save the file, reboot the virtual machine, and run the <code>mem</code> command again, you&#8217;ll see that we now have some &#8220;Upper&#8221; memory available, more memory available &#8220;under 1 MB,&#8221; a larger &#8220;largest executable program size,&#8221; and a &#8220;largest free upper memory block&#8221; of 27K instead of 0.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.44.58-PM-1024x677.png" alt="" class="wp-image-1030" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.44.58-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.44.58-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.44.58-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.44.58-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.44.58-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.44.58-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>These all seem like good things, so let&#8217;s move on!</p>



<h2 class="wp-block-heading">Step 7: Manage the Power</h2>



<p>So, I had no idea about this when I was a kid fooling around with DOS, but apparently the operating system actually has some power management features built in. I don&#8217;t know much about what they do, but I did learn from the tutorial I&#8217;ve mentioned a couple times that it&#8217;s a good idea to turn them on if you&#8217;re running DOS in a virtual machine. Apparently, this will prevent the virtual machine from using more of your host machine&#8217;s processing power than it needs to.</p>



<p>To do do this, we&#8217;re going to—surprise!—edit the config.sys file yet again. By now, you should know how to do this. So I&#8217;m just going to tell you to add the following line right after the one for EMM386.EXE:</p>



<pre class="wp-block-code"><code>DEVICEHIGH=C:\DOS\POWER.EXE adv:min</code></pre>



<p>The file should look like this before you save it. Once you&#8217;re back at the command prompt, go ahead and reboot the virtual machine again.</p>



<p>You should now see a new piece of information show up after all the status messages indicating that the Power Manager has loaded.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.58.11-PM-1024x677.png" alt="" class="wp-image-1031" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.58.11-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.58.11-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.58.11-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.58.11-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.58.11-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-6.58.11-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Although that&#8217;s all you&#8217;ll ever see on the screen, I can confirm that this <em>does</em> actually do something. Prior to adding this command to my CONFIG.SYS file, the virtual machine was using 100% of my processor (according to Apple&#8217;s Activity Monitor) even when I wasn&#8217;t doing anything with it. Once I saved the config file and rebooted, the number dropped to the single digits. I certainly don&#8217;t want to make my computer work harder than it needs to, so I&#8217;m glad I discovered that tip.</p>



<h2 class="wp-block-heading">Step 8: Create a Virtual Floppy Disk</h2>



<p>Okay, things are progressing nicely. We now have a functional machine with some basic memory management and even power management in place. Wouldn&#8217;t it be nice if we could actually install some programs on this thing?</p>



<p>Well, to do that we need a way of actually getting stuff onto the machine. The most logical method would be to mimic the way we&#8217;d do this in 1995: a blank floppy disk!</p>



<p>To create a blank floppy, let&#8217;s open up the Terminal app on the host machine (in my case, my MacBook Pro).</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="710" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.03.21-PM-1024x710.png" alt="" class="wp-image-1032" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.03.21-PM-1024x710.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.03.21-PM-300x208.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.03.21-PM-768x532.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.03.21-PM.png 1394w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Now, we need to type in the following command:</p>



<pre class="wp-block-code"><code>dd bs=512 count=2880 if=/dev/zero of=/Users/&#91;username]/Desktop/floppy.img</code></pre>



<p><em>Note: You&#8217;ll need to replace </em><code>[username]</code><em> in the command above with your actual macOS user name. If you&#8217;re not sure what your name is, just type </em><code>whoami</code><em>in the terminal and hit <kbd><strong>Enter</strong></kbd>.</em></p>



<p>This command basically copies a whole bunch of zeros into a file the exact size of an old 3.5&#8243; diskette (which, incidentally, could hold 1.44 megabytes of data—something I find just wild when I think about how many <em>gigabytes</em> of data I can fit on one of the tiny SD flash cards we use for the cameras in my journalism classroom). The file should appear on your desktop.</p>



<p>This disk image we&#8217;ve created is unformatted; we can&#8217;t <em>do</em> anything with it yet. So let&#8217;s format it!</p>



<p>The first step is to insert it (virtually) into our virtual machine. Just like when we were installing DOS, we can click on that little icon in the virtual machine&#8217;s toolbar that looks like a CD, hover over &#8220;Disk Image (floppy)&#8221; and choose &#8220;Change.&#8221; This time instead of an installer, we&#8217;ll choose the floppy image that now lives on our desktop.</p>



<p>Before you move on, double-check that the disk was selected correctly by clicking the icon again and making sure the name of the new disk (&#8220;floppy.img&#8221;) shows up in the menu.</p>



<p>Now, let&#8217;s return to the DOS command prompt. We&#8217;re going to format our blank disk by issuing the following command:</p>



<pre class="wp-block-code"><code>format a:</code></pre>



<p>After you press <kbd><strong>Enter</strong></kbd>, you should a message asking us to insert a disk. (It turns out we&#8217;re one step ahead of things.)</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.13.24-PM-1024x677.png" alt="" class="wp-image-1033" width="640" height="423" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.13.24-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.13.24-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.13.24-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.13.24-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.13.24-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.13.24-PM.png 1664w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<p>Press <kbd><strong>Enter</strong></kbd> one more time to begin the procedure.</p>



<p>The machine will churn for a bit and then ask for a label.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.14.11-PM-1024x677.png" alt="" class="wp-image-1034" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.14.11-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.14.11-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.14.11-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.14.11-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.14.11-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.14.11-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Call this disk whatever you&#8217;d like (as long as it fits within 11 characters), and press <kbd><strong>Enter</strong></kbd>. (I&#8217;m feeling creative, so I&#8217;m going to call it &#8220;My Disk.&#8221;)</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.15.39-PM-1024x677.png" alt="" class="wp-image-1035" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.15.39-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.15.39-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.15.39-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.15.39-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.15.39-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.15.39-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>When you see the prompt asking whether to format another disk, press <kbd><strong>N</strong></kbd> followed by <kbd><strong>Enter</strong></kbd>.</p>



<p>Now, we should be back at the command prompt.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.19.39-PM-1024x677.png" alt="" class="wp-image-1038" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.19.39-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.19.39-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.19.39-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.19.39-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.19.39-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.19.39-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Step 9: Access the Virtual Disk in macOS</h2>



<p>Now that we have a (virtual) blank floppy disk at our disposal, we can use it to start adding some files to the virtual machine.</p>



<p>To place files on our virtual floppy disk, we start by double-clicking the icon on our host machine&#8217;s desktop.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="368" height="178" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-11.08.11-PM.png" alt="" class="wp-image-1093" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-11.08.11-PM.png 368w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-11.08.11-PM-300x145.png 300w" sizes="auto, (max-width: 368px) 100vw, 368px" /></figure></div>


<p> This tells macOS to mount the disk contained within the image file. On my computer mounted disks show up on my desktop like this:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="566" height="178" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.21.15-PM.png" alt="" class="wp-image-1039" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.21.15-PM.png 566w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.21.15-PM-300x94.png 300w" sizes="auto, (max-width: 566px) 100vw, 566px" /></figure>



<p>Depending on how you have your computer set up, you might need to locate the disk in the macOS Finder. But however you do it, go ahead and open that disk.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="671" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.30.15-PM-1024x671.png" alt="" class="wp-image-1040" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.30.15-PM-1024x671.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.30.15-PM-300x197.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.30.15-PM-768x503.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.30.15-PM-1536x1007.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.30.15-PM-1600x1049.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.30.15-PM.png 1672w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Ooh, so fresh and blank!</figcaption></figure>



<h2 class="wp-block-heading">Step 10: Add Some Drivers to the Disk</h2>



<p>Okay, do you remember those two drivers I had you download back in the <strong>Materials</strong> section of this tutorial? It&#8217;s time to finally do something with them!</p>



<p>The first file was <em>oakcdrom.sys</em>. Let&#8217;s find this file and add it to the empty disk.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="671" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.40.53-PM-1024x671.png" alt="" class="wp-image-1042" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.40.53-PM-1024x671.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.40.53-PM-300x197.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.40.53-PM-768x503.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.40.53-PM-1536x1007.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.40.53-PM-1600x1049.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.40.53-PM.png 1672w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The other thing we downloaded was <em>mouse.zip</em>. When we unzip this file, we get <em>mouse.com</em>. Let&#8217;s put this on the disk, too.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="671" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.42.13-PM-1024x671.png" alt="" class="wp-image-1043" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.42.13-PM-1024x671.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.42.13-PM-300x197.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.42.13-PM-768x503.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.42.13-PM-1536x1007.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.42.13-PM-1600x1049.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.42.13-PM.png 1672w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Now, let&#8217;s go back to the virtual machine and try to access the drive.</p>



<p>At the DOS prompt, type in <code>A:</code> and press <kbd><strong>Enter</strong></kbd>. The prompt should change to <strong>A:\&gt;</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.44.41-PM-1024x677.png" alt="" class="wp-image-1044" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.44.41-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.44.41-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.44.41-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.44.41-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.44.41-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.44.41-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Now, if we enter the <code>dir</code> command, we should see the two files that we added:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.52.01-PM-1024x677.png" alt="" class="wp-image-1045" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.52.01-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.52.01-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.52.01-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.52.01-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.52.01-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.52.01-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Let&#8217;s copy these two files into the DOS folder. After typing in each of the following lines, press enter:</p>



<pre class="wp-block-code"><code>copy oakcdrom.sys c:\dos
copy mouse.com c:\dos</code></pre>



<p>Then, type in <code>C:</code> and press <strong><kbd>Enter</kbd></strong> to switch back to the hard drive (also known as Drive C).</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.55.09-PM-1024x677.png" alt="" class="wp-image-1047" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.55.09-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.55.09-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.55.09-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.55.09-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.55.09-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-7.55.09-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Now, let&#8217;s go edit CONFIG.SYS <em>again</em> by typing <code>edit config.sys</code> and pressing <kbd><strong>Enter</strong></kbd>.</p>



<p>After the line for EMM386.EXE, but before the line for POWER.EXE, add the following line:</p>



<pre class="wp-block-code"><code>DEVICEHIGH=C:\DOS\OAKCDROM.SYS /D:MSCD001</code></pre>



<p>This will tell the computer to load the CD-ROM driver into high memory. The bit at the end gives the device a name. I&#8217;m not entirely sure why, but &#8220;mscd001&#8221; seems to be the standard name used in pretty much every reference I&#8217;ve read, so let&#8217;s go with it. The file should now look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="658" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.09.48-PM-1024x658.png" alt="" class="wp-image-1049" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.09.48-PM-1024x658.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.09.48-PM-300x193.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.09.48-PM-768x493.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.09.48-PM-1536x986.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.09.48-PM.png 1576w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Let&#8217;s save the file and exit back to the prompt.</p>



<p>Next, we need to edit a different configuration file: AUTOEXEC.BAT. This is less a configuration file and more like a script. (Technically, if we&#8217;re using DOS parlance, it&#8217;s called a &#8220;batch&#8221; file.) AUTOEXEC.BAT is essentially a startup file; it&#8217;s a series of DOS commands that the operating system issues right before it turns things over to the user.</p>



<p>So let&#8217;s edit the file by typing <code>edit autoexec.bat</code> and pressing <strong><kbd>Enter</kbd></strong>.</p>



<p>We&#8217;re going to add two lines to the end of this file:</p>



<pre class="wp-block-code"><code>LH C:\DOS\MSCDEX.EXE /D:MSCD001 /L:D
LH C:\DOS\MOUSE.COM</code></pre>



<p><strong>LH</strong> is as shortcut for the <strong>LOADHIGH</strong> command, which work similarly to <strong>DEVICEHIGH</strong> in CONFIG.SYS. It attempts to load a program into the high memory region (rather than the low or &#8220;conventional&#8221;) memory region. The idea is to keep the conventional memory (the first 640 kilobytes) as clear as possible to make more room to load actual applications.</p>



<p>Whereas OAKCDROM.SYS is a third-party driver that tells the computer how to talk to the CD-ROM hardware, <strong>MSCDEX.EXE</strong> is a program included with MS-DOS that helps the operating system read the actual data on the CD. The part of the line that begins &#8220;/D:&#8221; refers to the name we added in the CONFIG.SYS file. The part that says &#8220;/L:D&#8221; tells the computer to assign letter D to the CD-ROM drive.</p>



<p>Meanwhile, <strong>MOUSE.COM</strong>, as the name might suggest, is a mouse driver; it lets the computer respond to input from a mouse.</p>



<p>With these two lines added, the file should now look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.06.39-PM-1024x677.png" alt="" class="wp-image-1050" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.06.39-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.06.39-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.06.39-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.06.39-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.06.39-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.06.39-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>We should now save the file and reboot the virtual machine. If we look carefully at the status messages that show up while the machine is starting up, we should see indications that an Oak Technology CD-ROM driver, the Microsoft Power Manager, the MSCDEX program, and the Microsoft Mouse Drier have all been loaded.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.18.46-PM-1024x677.png" alt="" class="wp-image-1051" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.18.46-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.18.46-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.18.46-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.18.46-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.18.46-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.18.46-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>We can see that the mouse actually works by trying to edit a file again. Let&#8217;s type in <code>edit autoexec.bat</code> and press <strong><kbd>Enter</kbd></strong>. Now, see what happens if you move your mouse around or play with your laptop&#8217;s touchpad.</p>



<p>(If <em>nothing</em> notable happens, you may need to tell the virtual machine to &#8220;capture&#8221; the mouse. You do this by clicking the first icon on the right side of the virtual machine&#8217;s toolbar—the one that looks like a mouse pointer with some lines around it. <em>Now</em> try moving the mouse around.)</p>



<p>With any luck, you should see a square-shaped box moving around the screen. You can use this cursor to select different locations in the file just like you would in a modern-day word processor. You can even use it to open the different menus at the top of the screen and select the various commands. Let&#8217;s go ahead and use the cursor to click on the <strong>File</strong> menu and select <strong>Exit</strong>.</p>



<p>(Reminder: If your cursor gets stuck inside the virtual machine, press <kbd><strong>CTRL+ALT</strong></kbd> or <kbd><strong>CTRL+Option</strong></kbd> to release it back to your host computer.)</p>



<h2 class="wp-block-heading">Step 11: Have Fun!</h2>



<p>Our basic DOS system is finally all set up. All that&#8217;s left is to install any of our favorite programs and, well, have at it!</p>



<p>In my case, I&#8217;ve been wanting to play SimCity 2000. My father bought the game for me some 25 years ago, and I just so happen to have an image file for the CD-ROM the game would have originally come on. Now that the virtual machine has a working CD-ROM driver, I can use the DOS command prompt to access this virtual CD.</p>



<p>First, I need to &#8220;insert&#8221; the CD. I&#8217;ll do this using that same icon in the toolbar that we&#8217;ve used a few times now to access floppy disks. This time, I&#8217;m going to hover over &#8220;CD/DVD (ISO) Image&#8221; and select &#8220;Change.&#8221; Then I&#8217;ll find the disk image on my host computer and select it.</p>



<p>One the disk is selected, I can type <code>D:</code> at the command prompt and press <strong><kbd>Enter</kbd></strong>. Then, I can type <code>dir</code> and press <kbd><strong>Enter</strong></kbd> to view the contents.</p>



<p>For some reason, it takes a really long time for the virtual machine to read the virtual CD the first time. I don&#8217;t know why, but it does eventually work.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.35.53-PM-1024x677.png" alt="" class="wp-image-1052" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.35.53-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.35.53-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.35.53-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.35.53-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.35.53-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.35.53-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>From here, I can see that there is a file named INSTALL.EXE, which is presumably the game&#8217;s installer. So, I&#8217;ll go ahead and type <code>install</code>, followed by <kbd><strong>Enter</strong></kbd>, to run it. (DOS will attempt to run any file that ends with .EXE or .COM, even if you don&#8217;t type that part in.)</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="858" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.37.44-PM-1024x858.png" alt="" class="wp-image-1053" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.37.44-PM-1024x858.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.37.44-PM-300x251.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.37.44-PM-768x643.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.37.44-PM.png 1504w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>And here&#8217;s the installer! It pops up this weird error message about not having enough RAM, which is not true. The good news is, I&#8217;ve tested this and the program works anyway.</p>



<p>After following all the instructions in the installer, I&#8217;m dropped back to the command prompt.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="677" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.40.03-PM-1024x677.png" alt="" class="wp-image-1054" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.40.03-PM-1024x677.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.40.03-PM-300x198.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.40.03-PM-768x508.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.40.03-PM-1536x1015.png 1536w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.40.03-PM-1600x1058.png 1600w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.40.03-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The installer automatically puts me in the game&#8217;s directory (or folder). If it didn&#8217;t, I could return to the hard drive by typing <code>C:</code> and then enter the program&#8217;s folder by typing <code>cd\sc2000</code>. (Here are a couple <a rel="noreferrer noopener" href="https://www.ionos.com/digitalguide/server/know-how/dos-commands-overview/" target="_blank">helpful</a> <a rel="noreferrer noopener" href="https://kb.wisc.edu/helpdesk/page.php?id=903" target="_blank">primers</a> on DOS commands if you&#8217;re new to the operating system or need a refresher.)</p>



<p>Finally, I&#8217;ll run the main program (SC2000.EXE) by entering <code>sc2000</code>.</p>



<p>And&#8230;</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="858" src="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.44.33-PM-1024x858.png" alt="" class="wp-image-1055" srcset="https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.44.33-PM-1024x858.png 1024w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.44.33-PM-300x251.png 300w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.44.33-PM-768x643.png 768w, https://teachernerd.com/wp-content/uploads/2022/07/Screen-Shot-2022-07-15-at-8.44.33-PM.png 1504w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>&#8230;it works!</p>



<p>If you have a game or other program on a CD you&#8217;d like to access, go ahead and try it. If your application comes on a floppy, then you&#8217;ll access it the same way we did our blank floppy. And if you have the application files themselves, but they&#8217;re not on a CD or floppy image, then you can add them to the floppy image that we created together to load them into the virtual machine.</p>



<h2 class="wp-block-heading">Wrapping Up</h2>



<p>If you&#8217;re not sure what to do next, I suggest some Googling. There are a number of archives of old DOS software out there on the internet. As I think I made it clear earlier, I don&#8217;t condone piracy, but the good news is that many programs have been officially placed into the public domain by their original authors, were available for free in the first place, or are considered &#8220;abandonware,&#8221; which means no one is really responsible for them anymore. (As always, proceed at your own risk, both in terms of the legal implications of your decisions and the possibility of obtaining viruses and other malware from random stuff on the internet.)</p>



<p>If you&#8217;re interested in a serious deep dive into the land of MS-DOS, complete with internet connectivity (of a rudimentary sort), command prompt customization, more advanced memory management, and then some, do check out the <a rel="noreferrer noopener" href="https://www.legroom.net/howto/msdos" target="_blank">LegRoom.net </a>tutorial that I&#8217;ve cited a few times. If you&#8217;re feeling especially bold, you can even try installing Windows 3.1 on top of your DOS setup. (I haven&#8217;t done it on this computer yet, but I&#8217;ve managed it in the past.)</p>



<p>As for me, my next step may be to figure out if I can get sound working—and then maybe I&#8217;ll move on to Windows <img src="https://s.w.org/images/core/emoji/16.0.1/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>If you&#8217;ve made it this far, you&#8217;re definitely a trooper. Now go build yourself some virtual skyscrapers!</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
