<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.danielfox.ie/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.danielfox.ie/" rel="alternate" type="text/html" /><updated>2026-04-08T01:26:27+00:00</updated><id>https://www.danielfox.ie/feed.xml</id><title type="html">R/S</title><author><name>Dan Fox</name></author><entry><title type="html">Using iOS Shortcuts for ad-free AirPlayable YouTube</title><link href="https://www.danielfox.ie/2026/ios-shortcuts-youtube-hls" rel="alternate" type="text/html" title="Using iOS Shortcuts for ad-free AirPlayable YouTube" /><published>2026-04-07T00:00:00+00:00</published><updated>2026-04-07T00:00:00+00:00</updated><id>https://www.danielfox.ie/2026/ios-shortcuts-youtube-hls</id><content type="html" xml:base="https://www.danielfox.ie/2026/ios-shortcuts-youtube-hls"><![CDATA[<p>Two years ago while walking from a plane to the terminal I dropped my “rugged”
Android device less than a metre onto the tarmac and it smashed. I took a punt
on moving to an iPhone. I was worried about the walled garden I’d heard so much
about and believed, I plan to write about that experience more generally in a
future post (spoiler: it’s mostly unfounded).</p>

<p>This post is going to be about my dislike of the YouTube experience out of the
box and how I was able to solve it with a solution that doesn’t require any
third party apps, dodgyness or developer options.</p>

<h2 id="shortcuts">Shortcuts</h2>
<p>Shortcuts is a native built-in macro/scripting tool for iOS (and macOS) and it
can be utilised completely on device. It has been written about a lot I’m sure,
but when tinkering with my new phone I remember being taken aback by a few small
but clearly incredibly powerful functions it has in it’s library:</p>

<ul>
  <li>Write arbitrary JavaScript to be run on a page within Safari</li>
  <li>Make HTTP requests</li>
  <li>Parse and manipulate JSON</li>
  <li>Run a remote SSH command passing input and receive the output</li>
  <li>Base64 encode/decode</li>
  <li>Hash functions</li>
</ul>

<p>“Shoot, a fella could have a pretty good weekend in Vegas with all that stuff”</p>

<h2 id="youtube-on-ios">YouTube on iOS</h2>
<p>While I have a YouTube Premium subscription and get on just fine with using it
on desktop in a browser I really disliked the native app experience on iOS. So
I migrated to using it within Safari, better experience but still with it’s
issues for me. I’m very much a vanilla native experience enjoyer, that means I
want a no-frills HTML5 video player experience.</p>

<p>When you go full-screen it does transition to the native player (which supports
picture in picture). Funnily if you’re not logged into a premium account YouTube
disables this functionality with a <a href="https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls#2940032">declaration user side</a>. Shortcuts to flip
this flag are common and widespread, neat to see. Anyway I was happy enough with
just using YouTube in Safari for now.</p>

<h2 id="the-airplay-problem">The AirPlay Problem</h2>
<p>Now if I thought I disliked my experience on iOS it was nothing compared to the
awfulness of YouTube on Apple TV. Not to worry, I can simply use Safari on my
phone and use AirPlay to get what I want on the big screen.</p>

<p>That’s when you discover YouTube gimps the quality of playback using AirPlay to
720p. What gives, this is clearly a synthetic restriction enforced with
user-side JavaScript.</p>

<p>Very frustrating, but there was an off the shelf solution available, a neat
Safari extension named <a href="https://apps.apple.com/ie/app/vinegar-tube-cleaner/id1591303229">Vinegar</a>. It does everything I wanted and it was
cheap at €2. Problem solved!…</p>

<h2 id="opacity">Opacity</h2>
<p>Anyone who knows me knows I loathe a black box. I had to know how it worked,
it’s my machine and this is client side stuff. The next problem is how do we
get developer debugging tools going on Safari on an iPhone, turns out it’s
amazingly simple; plug the phone in over USB and click the develop menu on
desktop Safari!</p>

<p>The meat of it is a single API request to a sparsely documented endpoint:
<code class="language-plaintext highlighter-rouge">https://www.youtube.com/youtubei/v1/player</code>.</p>

<p>Researching this a bit further it’s the endpoint leveraged by the likes of
<a href="https://github.com/yt-dlp/yt-dlp/tree/master">yt-dlp</a>. You can spend hours playing with this endpoint and I’d recommend
it, it’s fun. But in the end for our purposes it can all be boiled down to this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ curl 'https://www.youtube.com/youtubei/v1/player' \
-X 'POST' \
-H 'Content-Type: application/json' \
--data-binary '{"context":{"client":{"clientName":"IOS","clientVersion":"20.03.02"}},"videoId":"T4Upf_B9RLQ"}' 2&gt;/dev/null |jq '.streamingData.hlsManifestUrl'
"https://manifest.googlevideo.com/api/manifest/hls_variant/expire/.../file/index.m3u8"
</code></pre></div></div>

<p>That’s it, that’s all we need. The returned URL can be opened in Safari and the
video will play without ads, without PiP restrictions, without AirPlay
restrictions. Enabling the media stats on my Apple TV I can see we’re getting up
to 4k video playing directly in the native player and being a HLS stream it’s
playing from the Apple TV without proxying through the phone!</p>

<p><em>Note on the <code class="language-plaintext highlighter-rouge">clientVersion</code>: When I first built this over a year ago a
different version was used, then of course one day it stopped working, luckily
all that was required was bumping this to what I found currently being used by
yt-dlp</em></p>

<h2 id="kiss">KISS</h2>
<p>Normally I’d probably be done here I know how it works, I can sleep well. But
knowing what’s available in Shortcuts toolbox and how simple this really is
there was an opportunity for some more fun, we can rebuild all of this ourselves
directly on the iPhone.</p>

<p>Unfortunately there’s no nice way of sharing the “source” of a shortcut.</p>

<p><a href="https://www.icloud.com/shortcuts/098bfc041abf423880ddbe00a4690463">You can download the Shortcut directly here.</a></p>

<p>And here’s an ASCII view of what you get in the Shortcuts UI:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  ┌─────────────────────────────────────────────────┐
  │  Receive  URLs  from  Share Sheet               │
  │  If there's no input:                           │
  │  Stop and Respond   Gobshite                    │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Get  Query  from  Shortcut Input               │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Get dictionary from  Component of URL          │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Get  Value  for  v  in  Dictionary             │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Get contents of                                │
  │  https://www.youtube.com/youtubei/v1/player     │
  │                                                 │
  │  Method: POST                                   │
  │  Request Body: JSON                             │
  │                                                 │
  │  ┌───────────────────────────────────────────┐  │
  │  │ Key              Type         Value       │  │
  │  ├───────────────────────────────────────────┤  │
  │  │ context          Dictionary   (1 item)    │  │
  │  │   client         Dictionary   (2 items)   │  │
  │  │     clientVersion  Text       20.03.02    │  │
  │  │     clientName     Text       IOS         │  │
  │  │ videoId          Text         [vid_id]    │  │
  │  └───────────────────────────────────────────┘  │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Get dictionary from  Contents of URL           │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Get  Value  for  streamingData  in  Dictionary │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Get dictionary from  Dictionary Value          │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Get  Value  for  hlsManifestUrl  in Dictionary │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Get URLs from  Dictionary Value                │
  └───────────────────────┬─────────────────────────┘
                          │
  ┌───────────────────────▼─────────────────────────┐
  │  Open  URLs                                     │
  └─────────────────────────────────────────────────┘
</code></pre></div></div>

<p><em>Et voilà!</em></p>

<h2 id="final-thoughts">Final thoughts</h2>
<p>This is a long post about what’s essentially a single POST request at the end of
the day. Also amusing in the face of the ad-blocking arms race, though that was
never the intention here. I still have and will keep my YouTube Premium
account. Also I feel like Vinegar should have made this post about what it does
rather than charge €2 for a black box to bypass ads, it leaving a sour taste in
your mouth writes itself.</p>]]></content><author><name>Dan Fox</name></author><summary type="html"><![CDATA[Two years ago while walking from a plane to the terminal I dropped my “rugged” Android device less than a metre onto the tarmac and it smashed. I took a punt on moving to an iPhone. I was worried about the walled garden I’d heard so much about and believed, I plan to write about that experience more generally in a future post (spoiler: it’s mostly unfounded).]]></summary></entry><entry><title type="html">Remote Cloud Hosted Password Managers/Vaults</title><link href="https://www.danielfox.ie/2022/password-managers" rel="alternate" type="text/html" title="Remote Cloud Hosted Password Managers/Vaults" /><published>2022-07-17T00:00:00+00:00</published><updated>2022-07-17T00:00:00+00:00</updated><id>https://www.danielfox.ie/2022/password-managers</id><content type="html" xml:base="https://www.danielfox.ie/2022/password-managers"><![CDATA[<p>We’ve come a long way in usability of these tools since my first exposure using
<a href="https://pwsafe.org/">Password Safe</a>. Services such as Bitwarden, LastPass,
1Password, and so on have made it extremely easy to get on board with using
a single master password to decrypt a database of passwords (that are ideally
random, long and unique), clients working across multiple devices and OS, vault
storage in the cloud. They also generally come with 2FA options, sounds super
secure.</p>

<p>I’ve been using these types of services for a while (LastPass originally then
migrating to Bitwarden a few years ago, Bitwarden is great), they really do
make life easier and solve the password re-use problem. But I got curious
recently as to how these services are supposedly secure, after researching how
my current provider (Bitwarden) works I thought it useful to document here in
simple language what’s going on.</p>

<p>I’ll assume these providers all use a similar scheme, they tend to use flashy
marketing saying it’s all awesome, listing accreditations and then direct you
to white-papers for the details. I read through the paper for Bitwarden and I
can see why it’s probably not shouted far and wide because it appears not
particularly secure at a glance, but it is pretty good, though it does have
pitfalls that should be made clearer.</p>

<h2 id="encryption-keys">Encryption keys</h2>
<h3 id="master-password-master_pw">Master Password (<code class="language-plaintext highlighter-rouge">$MASTER_PW</code>)</h3>
<p>This is your (changeable) password to login to the cloud service and decrypt
the vault to retrieve your passwords. This theoretically never leaves your
local machine.</p>

<h3 id="the-vault-vault_key">The Vault (<code class="language-plaintext highlighter-rouge">$VAULT_KEY</code>)</h3>
<p>When your account is created a symmetric key is generated locally, generally in
your browser. This key will then be used to encrypt and decrypt all the data
stored in your vault.</p>

<h2 id="storage">Storage</h2>
<h3 id="vault_key---enc_vaultkey"><code class="language-plaintext highlighter-rouge">$VAULT_KEY</code> -&gt; <code class="language-plaintext highlighter-rouge">$ENC_VAULTKEY</code></h3>
<p>The symmetric vault key is encrypted and stored using symmetric encryption
keyed with <code class="language-plaintext highlighter-rouge">$MASTER_PW</code>.</p>

<h3 id="vault">Vault</h3>
<p>The vault is stored in the “cloud” encrypted with <code class="language-plaintext highlighter-rouge">$VAULT_KEY</code>.</p>

<h2 id="access">Access</h2>
<p>When you log in to a service you send a hash of <code class="language-plaintext highlighter-rouge">$LOGIN+$MASTER_PW</code> to the
remote service, if you have enabled 2FA the service may require this to
authenticate you (note: this 2FA has <strong>nothing</strong> to do with your vault), if you
have successfully authenticated you will receive back a copy of the encrypted
vault and <code class="language-plaintext highlighter-rouge">$ENC_VAULTKEY</code>.</p>

<p>The local client will then decrypt <code class="language-plaintext highlighter-rouge">$ENC_VAULTKEY</code> to further decrypt the vault
itself.</p>

<h2 id="master-password-change">Master Password Change</h2>
<p>When you change your master password <code class="language-plaintext highlighter-rouge">$MASTER_PW</code> and <code class="language-plaintext highlighter-rouge">$ENC_VAULTKEY</code> will
change, however <code class="language-plaintext highlighter-rouge">$VAULT_KEY</code> will not.</p>

<h2 id="the-one-ring">The One Ring</h2>
<p>In general there is one original key, the <code class="language-plaintext highlighter-rouge">$VAULT_KEY</code> that if compromised is
not good. If the <code class="language-plaintext highlighter-rouge">$VAULT_KEY</code> is compromised the vault can be decrypted, even
after a <code class="language-plaintext highlighter-rouge">$MASTER_PW</code> change. So in summary the service stores your vault and
<code class="language-plaintext highlighter-rouge">$ENC_VAULTKEY</code>, theoretically locking access to both of those behind potential
2FA and <code class="language-plaintext highlighter-rouge">$MASTER_PW</code>.</p>

<p>It still is a pretty good system but pitfalls should be obvious after reading
this, be careful where you unlock the vault.</p>]]></content><author><name>Dan Fox</name></author><summary type="html"><![CDATA[We’ve come a long way in usability of these tools since my first exposure using Password Safe. Services such as Bitwarden, LastPass, 1Password, and so on have made it extremely easy to get on board with using a single master password to decrypt a database of passwords (that are ideally random, long and unique), clients working across multiple devices and OS, vault storage in the cloud. They also generally come with 2FA options, sounds super secure.]]></summary></entry><entry><title type="html">Markdown kinda sucks</title><link href="https://www.danielfox.ie/2022/markdown-kinda-sucks" rel="alternate" type="text/html" title="Markdown kinda sucks" /><published>2022-06-19T00:00:00+00:00</published><updated>2022-06-19T00:00:00+00:00</updated><id>https://www.danielfox.ie/2022/markdown-kinda-sucks</id><content type="html" xml:base="https://www.danielfox.ie/2022/markdown-kinda-sucks"><![CDATA[<p>So firstly I do in fact quite like Markdown and generally enjoy writing
documents in it. But similarly to YAML it’s simplicity and generally widespread
use has resulted in it being overused and beaten with a large hammer to fit
into places it was never really fit for.</p>

<h2 id="gfm---github-flavored-forked-markdown">GFM - GitHub Flavored <em>(Forked)</em> Markdown</h2>
<p>Now somewhat of a standard, they call it a “flavour” - whatever that is
supposed to mean, it’s a fork with some extra features added for writing nice
<em>README</em> plain-ish text files that render on GitHub projects. It’s nice, it’s
fine. Use it for your GitHub <em>README</em> documents and other GitHub stuff.</p>

<p>It adds mainly <code class="language-plaintext highlighter-rouge">&lt;table&gt;</code> support to Markdown, also “<em>tasklist</em>” which is just a
unordered list with checkboxes instead of bullets, whoop-de-do.</p>

<h2 id="using-it-in-anger">Using it in anger</h2>
<p>It wont take long before you want to do something super crazy and so out there
you’re a lunatic: like aligning text in a single row or cell (YOU ROGUE!).</p>

<p>So OK right, what do you do once you want to do some extremely basic formatting
of your document not supported in markdown but is in HTML? Parsers are pretty
flexible, GitHub and most others render raw HTML tags.</p>

<h2 id="totally-broken">Totally Broken</h2>
<p>Once you’ve used HTML tags or any other extended crap you’ve broken any reason
for using markdown in the first place, go open that document in a plaintext
editor like vim or even better just cat it, yeah it’s not human readable as
documentation in plaintext anymore is it?</p>

<h2 id="who-cares">Who cares?</h2>
<p>Probably absolutely no one, but you’ve just wasted your time trying to hack
markdown and breakout HTML into looking how you wanted. The point of writing
docs in markdown should be so they’re easily readable as plaintext too.
Otherwise just use a real markup language.</p>

<h2 id="the-better-way">The better way</h2>
<p>Write your doc straight in HTML, or better yet brush up on or learn LaTeX, or
markup for troff. Don’t use HTML in the middle of markdown documents, if you do
though that’s OK, you should check out <code class="language-plaintext highlighter-rouge">shell_exec</code> too I think you’d like it.</p>

<p>Markdown is still really great for that quick blog post, reddit post, or any
other simple text article, but stop trying to extend it and beat it into places
it never belonged.</p>]]></content><author><name>Dan Fox</name></author><summary type="html"><![CDATA[So firstly I do in fact quite like Markdown and generally enjoy writing documents in it. But similarly to YAML it’s simplicity and generally widespread use has resulted in it being overused and beaten with a large hammer to fit into places it was never really fit for.]]></summary></entry><entry><title type="html">Buying a New RPN Calculator Today</title><link href="https://www.danielfox.ie/2022/buying-rpn-today" rel="alternate" type="text/html" title="Buying a New RPN Calculator Today" /><published>2022-06-12T00:00:00+00:00</published><updated>2022-06-12T00:00:00+00:00</updated><id>https://www.danielfox.ie/2022/buying-rpn-today</id><content type="html" xml:base="https://www.danielfox.ie/2022/buying-rpn-today"><![CDATA[<p>There are unfortunately very few options today, and in 2022 things only seem
worse. Regular stock of HP 35S and 12C models has dried up in the last year,
this is hopefully just due to pandemic and semiconductor shortage nonsense and
we will see a return of these to production. Perhaps if we’re lucky maybe we’ll
see something this year for the 50th anniversary of the HP-35.</p>

<h2 id="hp-35s">HP 35S</h2>
<p>This is my daily driver, it’s not without it’s issues but it generally does
it’s job well and has a really nice keyboard. Integer features severely let
this calculator down, working with or juggling outside of base 10 is too clunky
and unusable in practice. You should be able to pick one of these up new for
€60-90.</p>

<h2 id="hp-12c">HP 12C</h2>
<p>If you search for a RPN calculator this is probably what will show up. It’s
part of the Voyager series of calculators, there was a 10C, 11C, 12C, 15C, and
16C. This 12C is the only one that has stayed in production and provides
financial functions (this was the shit pre-excel). If you get one today it’s
an ARM machine emulating the old hardware running far faster.</p>

<p>I’ve had a few of these modern 12C’s and the keyboards are decent, but they are
hard on batteries (like seriously), and also far more delicate than they seem.
They don’t do well being thrown in a front pocket of a work bag. So I’d put
these in the retro toy category. Also about €60-90.</p>

<h2 id="swissmicros">SwissMicros</h2>
<p>These are small-batch high end replica’s of old HP’s (they do some new spins on
old hardware too). They’re not cheap, but in my experience they are not
overpriced either. You’ll want something from these guys eventually but not
your first RPN. With taxes in your hand about €140 for a DM16L, but a good
condition used HP 16C would be at least €250.</p>

<p>The build quality of the case, buttons and everything in general is premium.
They’ve also done a great job porting to modern low power MCUs.</p>

<h2 id="px16c--px15c--paxer">PX16C / PX15C / Paxer</h2>
<p>I wont beat around the bush, I don’t own one but also I really don’t like these
and they rub me up the wrong way. It’s a very nice story of a guy making his
own clone of a HP Voyager. But it’s built on dogshit old power hungry 8-bit AVR
chips (it’s an Arduino <em>groan</em>). If this was open source I’d be more
enthusiastic, but as it is it’s basically a shit imitation of what SwissMicros
have been doing for years (with an ATMEGA, again seriously?). Not cheap either,
$55 before shipping and taxes for a circuit board with a LCD some tact switches
and an AVR. Adding EU shipping and taxes you’re at over half the cost of a
SwissMicros for a janky and chonk DIY device that’s not open.</p>

<p>I really wanted to like these and get one (or a few) but the cost is too high
for what it is. $55 (kit) + $25 (shipping) + $18.40 (import tax), guts of $100.
It should have been entirely open source with PCB gerbers available and a “buy
me a coffee” link.</p>

<h2 id="wp-34s">WP 34S</h2>
<p>A HP 20b or 30b with with firmware reflashed. This open source firmware is
extremely capable but is pretty complicated and vast. The underlying hardware
of the 20b and 30b is supposedly the same apart from colour and the keyboard
quality. However I did buy a 30b and converted to 34S and the keyboard is so so
awful I wont use the calculator at all, so god knows how bad the 20b is. The
features on the WP 34S are great though. Needs a set of <a href="https://commerce.hpcalc.org/overlay.php">keyboard overlay
stickers</a>, and making your own
programming cable is very easy. I think my total cost was around €85-90 for new
old stock 30b plus 2x vinyl labels, already having the programming parts lying
around.</p>]]></content><author><name>Dan Fox</name></author><summary type="html"><![CDATA[There are unfortunately very few options today, and in 2022 things only seem worse. Regular stock of HP 35S and 12C models has dried up in the last year, this is hopefully just due to pandemic and semiconductor shortage nonsense and we will see a return of these to production. Perhaps if we’re lucky maybe we’ll see something this year for the 50th anniversary of the HP-35.]]></summary></entry><entry><title type="html">My understanding and summary of ECU fundamentals</title><link href="https://www.danielfox.ie/2022/ecu-basics" rel="alternate" type="text/html" title="My understanding and summary of ECU fundamentals" /><published>2022-06-10T00:00:00+00:00</published><updated>2022-06-10T00:00:00+00:00</updated><id>https://www.danielfox.ie/2022/ecu-basics</id><content type="html" xml:base="https://www.danielfox.ie/2022/ecu-basics"><![CDATA[<p>This post is a copy from an old gist I wrote up a year or so ago. It’s my basic
understanding from a software engineers PoV of what’s going on in a very simple
ECU for a naturally aspirated petrol engine you might find in a motobike or an
older car. Some thoughts around tuning and so on.</p>

<h2 id="outputs">Outputs</h2>
<ul>
  <li>Fuel (“MAP”)</li>
  <li>Spark (Ignition timing/advance)</li>
</ul>

<h2 id="inputs">Inputs</h2>
<p>Can be some of or all of the following. In simplest form a single 2D array is
indexed by “load” and RPM, values represent the duration injectors are switched
on for. What is generally referred to as closed-loop means the value of the
Lambda sensor is taken into consideration when calculating the injector pulse
length. In open-loop the value of the Lambda sensor is ignored.</p>

<p>In a “standard basic” ECU we can assume it has two maps, a closed-loop map for
when the slope of the rate of change with regard to “load” and RPM is close to
zero, and open loop as it wavers. This largely because the response time of the
Lambda sensor is long. “Smarter” ECUs will use sampled recent Lambda values as
a factor in the open-loop calculation.</p>

<ul>
  <li>Throttle (TPS)</li>
  <li>Crank (RPM)</li>
  <li>Air Temp (IAT)</li>
  <li>Barometric pressure (MAP)</li>
  <li>Air flow (MAF)</li>
  <li>Unburned fuel (Lambda/o2)</li>
</ul>

<h2 id="fuel-tuning">Fuel Tuning</h2>
<p>When modifications are made to the stock internal combustion system it <em>may</em> be
necessary to change the behaviour of the fuel injection system. The factory
closed-loop system will usually attempt to run the engine on the lean side of
the stoichiometric ratio for both fuel efficiency and emissions. The majority
of user modifications made will be within the margins the ECU will compensate
for. Noticeable problems will start to occur however under open-loop operation
if the ECU is not of the “learning” type that uses recent Lambda values for
open-loop.</p>

<h3 id="iat-adjustment">IAT Adjustment</h3>
<p>A very simple solution here is to make some adjustments to the reported value
of the current air temperature.</p>

<ul>
  <li>Beer-mat-maths
    <ul>
      <li>-10°C = +3% Fuel</li>
    </ul>
  </li>
</ul>

<p>The actual end effect of this input adjustment will of course vary across ECUs
and their underlying calculations. If it is constantly adjusting a factor where
Lambda takes priority, the effect may even be nil.</p>

<h3 id="piggyback-ecu">Piggyback ECU</h3>
<p>This is what a DynoJet Power Commander and similar devices are. These are
man-in-the-middle devices. In their absolute most basic form they will “trim”
the fuel injectors by running them for a longer/shorter period. To work
consistently they should also modify the ECUs reading of the Lambda sensor.
How these devices will usually work is not by modulating the output of the
Lambda but by providing values to keep it in a constant sate. So in effect
these devices keep an ECU in an open-loop type state with a modified map.</p>

<p>If we are building our own MITM device anything here goes of course with what
inputs &amp; outputs we decide to modulate.</p>

<h3 id="ecu-flashing">ECU Flashing</h3>
<p>Also referred to as “chip-tuning”, “remapping”, and so on. This process
overwrites the original program on the ECU supplied by the manufacturer. This
could be merely a modification to the lookup tables or it could be an entire
system change. This type of modification service is far too often a snake-oil
product sold to unsuspecting customers. Any idiot can get their hands on the
right hardware &amp; software along with enough information to be dangerous here.</p>

<p><strong>DO NOT</strong> engage in this kind of nonsense unless you have a full known good
(tested that you can restore it) backup of your original ECU.</p>

<p>“Ah but I know a guy” - Shit, you’re right. Psst here’s a another secret, <a href="https://www.downloadmoreram.com">free
RAM</a>.</p>

<h2 id="ignition-tuning">Ignition Tuning</h2>
<p>Adjusting the ignition advance for your combustion is a genuine way to more
power and efficiency. It needs to be tuned to the specific type of fuel you’re
using. This is what usually makes the large power gains you get from a ECU
re-flash. But guess what there might be a reason it wasn’t shipped from the
factory like that. If you now run an incompatible fuel you run the risk of
detonation. Unless you’re screening your fuel somehow this is going to end in
a blown up engine.</p>]]></content><author><name>Dan Fox</name></author><summary type="html"><![CDATA[This post is a copy from an old gist I wrote up a year or so ago. It’s my basic understanding from a software engineers PoV of what’s going on in a very simple ECU for a naturally aspirated petrol engine you might find in a motobike or an older car. Some thoughts around tuning and so on.]]></summary></entry><entry><title type="html">HP-16C Exponential Program</title><link href="https://www.danielfox.ie/2022/16c-exponentiation-by-squaring" rel="alternate" type="text/html" title="HP-16C Exponential Program" /><published>2022-06-02T00:00:00+00:00</published><updated>2022-06-02T00:00:00+00:00</updated><id>https://www.danielfox.ie/2022/16c-exponentiation-by-squaring</id><content type="html" xml:base="https://www.danielfox.ie/2022/16c-exponentiation-by-squaring"><![CDATA[<p>The 16C (or DM16L) is a computer scientist model and not a general scientific
calculator, it does not include an exponent function, either arbitrary
y<sup>x</sup> or x². The correct thing to do here is obviously use a suitable
device, but for fun I’ve implemented an exponential program on this model. This
post documents some of that journey.</p>

<h2 id="the-simple-way">The simple way</h2>
<p>The really easy and naive way to do this is to repeatedly multiply, the way we
all know and understand as a basic principle. This is actually a pretty easy
program to write and understand, for <em>a</em> to the power of <em>b</em> we store <em>b-1</em> in
<code class="language-plaintext highlighter-rouge">I</code> then use <strong>DSZ</strong> (Decrement <code class="language-plaintext highlighter-rouge">I</code> skip next instruction if <code class="language-plaintext highlighter-rouge">I</code> is zero) to
multiply <em>a</em> by itself the required amount of times.</p>

<p>This is clearly – slow as shit, becoming even more obvious running it on an
80’s pocket calculator (even if a fancy one).</p>

<h5 id="implementation">Implementation:</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>LBL E // y^x x&gt;=2
1
-
STO I
Rv
ENT
LBL 0
*
LST X
DSZ
GTO 0
x&lt;&gt;y
RTN
</code></pre></div></div>

<h2 id="exponentiation-by-squaring">Exponentiation by squaring</h2>
<p>There is a <em>O</em>(log n) solution to exponent calculation, which I will not go
into as <a href="https://en.wikipedia.org/wiki/Exponentiation_by_squaring">wikipedia</a> explains it well. From here on it will be expected
you’re familiar with the tail-recursive implementation of the algorithm.</p>

<p>This program will only work while the calculator is in integer mode, it will
not work in floating point mode.</p>

<p>We can boil the algorithm down to something like this:</p>
<ol>
  <li>y = 1</li>
  <li>n = n/2</li>
  <li>n was odd? (check the carry bit after a shift-right)
    <ul>
      <li>y = x * y</li>
    </ul>
  </li>
  <li>x = x * x</li>
  <li>(n &gt; 1) ?
    <ul>
      <li>GOTO 2</li>
    </ul>
  </li>
  <li>x = x * y</li>
</ol>

<h5 id="implementation-1">Implementation:</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>LBL E // Main Exponent Program y^x integer only x&gt;=1
F? 0  // {
GTO 0 //   If flag 0 is set jump to loop otherwise set flag for later entry
SF 0  // }

1     // {
STO I //   Store 1 in `I` (y)
Rv    // }

LBL 0 // Start of Label 0 (Main loop)
1     // { If n = 1 go to the end section (2)
x=y?  //
GTO 2 //
Rv    // }

SR    // { n/2 by shifting right, run odd subroutine if carry flag set
F? 4  //
GSB 1 // }

x&lt;&gt;y  // { x = x * x; then loop
ENTER //
*     //
x&lt;&gt;y  //
GTO E // }

LBL 1 // { n is odd subroutine
x&lt;&gt;I  //   Get the y value from register `I`
x&lt;&gt;y  //   y = x * y; store it, restore stack and return
*     //
LSTx  //
x&lt;&gt;y  //
x&lt;&gt;I  //
RTN   // }

LBL 2 // { Subroutine for ending
CF 0  //   Clear flag 0
Rv    //   x = x * y; then return
x&lt;&gt;I  //
*     //
RTN   // }
</code></pre></div></div>]]></content><author><name>Dan Fox</name></author><summary type="html"><![CDATA[The 16C (or DM16L) is a computer scientist model and not a general scientific calculator, it does not include an exponent function, either arbitrary yx or x². The correct thing to do here is obviously use a suitable device, but for fun I’ve implemented an exponential program on this model. This post documents some of that journey.]]></summary></entry></feed>