Blog

Blog

Welcome to the Blog.

Mode 13h in Turbo Pascal

Graphics programming without illusions

2026-02-22

Turbo Pascal graphics programming is one of the cleanest ways to learn what a frame actually is. In modern stacks, rendering often passes through layers that hide timing, memory layout, and write costs. In DOS Mode 13h, almost nothing is hidden. You get 320x200, 256 colors, and a linear framebuffer at segment $A000. Every pixel you draw is your responsibility.

Mode 13h became a favorite because it removed complexity that earlier VGA modes imposed. No planar bit operations, no complicated bank switching for this resolution, and no mystery about where bytes go. Pixel (x, y) maps to offset y * 320 + x. That directness made it ideal for demos, games, and educational experiments. It rewarded people who could reason about memory as geometry.

A minimal setup in Turbo Pascal is refreshingly explicit: switch video mode via BIOS interrupt, get access to VGA memory, write bytes, wait for input, restore text mode. There is no rendering engine to configure. You control lifecycle directly. That means you also own failure states. Forget to restore mode and you leave the user in graphics. Corrupt memory and artifacts appear instantly.

Early experiments usually start with single-pixel writes and quickly hit performance limits. Calling a procedure per pixel is expressive but expensive. The first optimization lesson is batching and locality: draw contiguous spans, avoid repeated multiplies, precompute line offsets, and minimize branch-heavy inner loops. Mode 13h teaches a truth that still holds in GPU-heavy times: throughput loves predictable memory access.

Palette control is another powerful concept students often miss today. In 256-color mode, pixel values are indices, not direct RGB triples. By writing DAC registers, you can change global color mappings without touching framebuffer bytes. This enables palette cycling, day-night transitions, and cheap animation effects that look far richer than their computational cost. You are effectively animating interpretation, not data. ... continue

Interrupts as User Interface

INT 10h, 16h, and 21h as DOS-era interaction surfaces

2026-02-22

In modern systems, user interface usually means windows, widgets, and event loops. In classic DOS environments, the interface boundary often looked very different: software interrupts. INT calls were not only low-level plumbing; they were stable contracts that programs used as operating surfaces for display, input, disk services, time, and devices.

Thinking about interrupts as a user interface reveals why DOS programming felt both constrained and elegant. You were not calling giant frameworks. You were speaking a compact protocol: registers in, registers out, carry flag for status, documented side effects.

Take INT 21h, the core DOS service API. It offered file IO, process management, memory functions, and console interaction. A text tool could feel interactive and polished while relying entirely on these calls and a handful of conventions. The interface was narrow but predictable.

INT 10h for video and INT 16h for keyboard provided another layer. Combined, they formed a practical interaction stack:

That is a full UI model, just encoded in BIOS and DOS vectors instead of GUI widget trees. ... continue

CONFIG.SYS as Architecture

Runtime policy before your application loads

2026-02-22

In DOS culture, CONFIG.SYS is often remembered as a startup file full of cryptic lines. That memory is accurate and incomplete. In practice, CONFIG.SYS was architecture: a compact declaration of runtime policy, resource allocation, compatibility strategy, and operational profile.

Before your application loaded, your architecture was already making decisions:

The shape of your software experience depended on this pre-application contract.

Take a typical line like:

DOS=HIGH,UMB ... continue

C:\> After Midnight

A DOS chronicle

2026-02-22

There is a particular blue that only old screens know how to make. Not sky blue, not electric blue, not any brand color from modern design systems. It is the blue of waiting, the blue of discipline, the blue of possibility. It is the blue that appears when a machine, after clearing its throat with a POST beep, hands you a bare prompt and says: now it is your turn.

C:\>

No dock, no notifications, no assistant bubble, no pretense of helping you think. Only an invitation and a challenge. The operating system has done almost nothing. You must do the rest.

This is not an article about nostalgia as decoration. It is about a working world that existed inside limits so hard they became architecture. A world where your startup sequence was a design document, your tools fit on a few floppies, your failures had names, and your victories often looked like reclaiming 37 kilobytes of conventional memory so a game or compiler could start. It is also a story, because DOS was never just a technical environment. It was a culture of rituals: boot rituals, backup rituals, anti-virus rituals, debugging rituals, and social rituals that happened in school labs, basements, bedrooms, and noisy clubs where people traded disks like rare books.

So let us spend one long night there. Let us walk into a fictional but faithful 1994 room that smells like warm plastic and printer paper. Let us build and run a complete DOS life from dusk to dawn. Every choice in this chronicle is plausible. Most of them were common. Some of them were mistakes. All of them are true to the era. ... continue

Benchmarking with a Stopwatch

Experimental discipline before high-resolution timers

2026-02-22

When people imagine benchmarking, they picture automated harnesses, high-resolution timers, and dashboards with percentile charts. Useful tools, absolutely. But many core lessons of performance engineering can be learned with much humbler methods, including one old trick from retro workflows: benchmarking with a stopwatch and disciplined procedure.

On vintage systems, instrumentation was often limited, intrusive, or unavailable. So users built practical measurement habits with what they had:

It sounds primitive until you realize it enforces the exact thing modern teams often skip: experimental discipline.

The first rule was baseline control. Before measuring anything, define the environment:

Without this, numbers are stories, not data. ... continue

Archive Discipline for the Floppy Era

Naming, verification, and restore habits that still matter

2026-02-22

People remember floppy disks as inconvenience, but they were also a strict training ground for information discipline. Limited capacity, media fragility, and transfer friction forced users to become intentional about naming, versioning, verification, and recovery. Those habits remain useful even in cloud-heavy workflows.

A floppy-era archive was never just “copy files somewhere.” It was an operating procedure:

Each step existed because failure was common and expensive.

Naming conventions carried real weight. You could not hide disorder behind full-text search and huge storage. A good archive label included date, project, and version. A bad label produced weeks of confusion later. Many users adopted compact but expressive patterns like:

Crude by modern standards, but operationally effective. ... continue

The Cost of Unclear Interfaces

Ambiguity as a compounding reliability tax

2026-02-22

Most teams think interface problems are technical. Sometimes they are. More often, they are social problems expressed through technical artifacts.

An interface is any boundary where one thing asks another thing to behave predictably. In code, that can be a function signature, an API schema, a queue contract, or a config file format. In teams, it can be a handoff checklist, an on-call escalation rule, or a release approval process. In both cases, the cost of ambiguity is delayed, compounding, and usually paid by someone who was not in the room when the ambiguity was created.

We notice unclear interfaces first as friction:

Each sentence sounds small. Together, they create reliability tax.

The dangerous part is that unclear interfaces rarely fail loudly at first. They degrade trust slowly. One team adds defensive checks “just in case.” Another adds retries to compensate for uncertain behavior. A third adds custom adapters to normalize inconsistent outputs. Soon, the architecture looks complicated, and everyone blames complexity. But complexity was often an adaptation to interface uncertainty. ... continue

Maintenance Is a Creative Act

2026-02-22

In software culture, novelty gets applause and maintenance gets scheduling leftovers. We celebrate launches, rewrites, and shiny architecture diagrams. We quietly postpone dependency cleanup, operational hardening, naming consistency, test stability, and documentation repair. Then we wonder why velocity decays.

This framing is wrong. Maintenance is not the opposite of creativity. Maintenance is applied creativity under constraints.

Creating something new from a blank page is one creative mode. Improving a living system without breaking commitments is another, often harder, mode. It demands understanding history, preserving intent, and evolving design with minimal collateral damage.

Good maintenance starts with respect for continuity. Existing systems encode decisions that may no longer be obvious but still matter. Some are outdated and should change. Some are hard-earned safeguards that protect production behavior. The maintainer’s job is to tell the difference.

That requires curiosity, not cynicism. “This code is ugly” is easy. “Why did this shape emerge, and what risks does it currently absorb?” is useful. ... continue

Clarity Is an Operational Advantage

2026-02-22

Teams often describe clarity as a communication virtue, something nice to have when there is time. In practice, clarity is operational leverage. It lowers incident duration, reduces rework, improves onboarding, and compresses decision cycles. Ambiguity is not neutral. Ambiguity is a hidden tax that compounds across every handoff.

Most organizations do not fail because they lack intelligence. They fail because intent degrades as it travels. Requirements become slogans. Architecture becomes folklore. Ownership becomes “someone probably handles that.” By the time work reaches production, the system reflects accumulated interpretation drift more than original design intent.

Clear writing is one antidote, but clarity is broader than prose. It includes naming, interfaces, boundaries, defaults, and escalation paths. A variable named vaguely can mislead a future refactor. An API contract with optional security checks invites accidental bypass. A runbook with missing preconditions turns outage response into improvisation theater.

A useful test is whether a tired engineer at 2 AM can make a safe decision from available information. If not, the system is unclear regardless of how elegant it looked in daytime planning meetings. Reliability is partly a documentation quality problem and partly an interface design problem.

One reason ambiguity survives is that it can feel fast in the short term. Vague decisions reduce immediate debate. Deferred precision preserves momentum. But deferred precision is debt with high interest. The discussion still happens later, now under pressure, with higher stakes and worse context. Clarity front-loads effort to avoid emergency interpretation costs. ... continue

Trace-First Debugging

Structured timelines before deeper tooling

2026-02-22

Many debugging sessions fail before the first command runs. The failure is methodological: teams chase hypotheses faster than they collect traceable facts. A trace-first approach reverses this. You start with a structured event timeline, annotate every command with intent, and only then escalate into deeper tooling.

This sounds slower and is usually faster.

A trace-first loop has four repeated steps:

The point is not paperwork. The point is preventing analytical thrash when pressure rises.

During incidents, maintain a plain-text note file in parallel with command execution. Every entry should include: ... continue

1:1 [747ea2..d158d9]