Analysis model: gpt-5.5 xhigh

Show by Majic 12 - Technical Dissection

Analysis model: gpt-5.5 xhigh

Scope

This is a static dissection of Show by Majic 12, released at Hammering 1994. The public pages and release text credit the demo to Majic 12; the coder is credited as Maxwood. That is the name used in the production metadata and in the demo's own embedded text, so I treat the user's "Maxwell" reference as this Maxwood/Majic 12 production.

Sources:

The analysis target is the fixed archive:

102903192fae04f730b96cb111b2c9e35aced8f1dd462ecf35cf72df838a2571  show_fix.zip
1f2470abef4600ac176b5263f2a4f0a384bdb074e0cb51eb3d773876adc489e8  SHOW.EXE
9c0cf703a3f2f3502dae0cf56e8fc010f081978b9ce322509ec9acf66d3fb174  SHOW.TXT
394b82bb93bc21015894002d6e352dc970b2ae6c7c8294e94cb6346a007501ad  FILE_ID.DIZ

FILE_ID.DIZ calls this "the final bugfree version" and lists the requirements as GUS,386. SHOW.TXT gives the fuller requirement list: 386, VGA-compatible card, Gravis UltraSound with 256 KB, and about 570 KB of conventional memory. It also states that the music replay uses Cascada's GUS routines.

The important caveat: I did not reconstruct source code, and I did not produce a screenshot timeline for every part. This is a binary-level behavioral map of the loader, the resource layout, and the most important render loops. For modules where the extracted file name and code agree, I use a confident visual label. For modules where the binary only proves "picture viewer", "palette cycler", or "planar blitter", I say that directly instead of pretending a frame capture was done.

Why This Demo Is Built Differently

SHOW.EXE is not a normal single executable image. It is a small real-mode DOS loader plus a very large appended module bundle. The MZ header describes only about 17.5 KB of executable image, while the actual file is about 1.95 MB.

The loader reads its own executable file, seeks to an internal directory near the end, and then loads individual *.COD and *.DAT resources by name. The visible show is therefore a script of small self-contained effect modules:

SKULL.START.QQ.ROT.CH.COPPER.16C.1LAP.PIXEL.TMAP.DO.TRON.C.DOOM.NEWG.
STOP.ART.ZZZ.INTER.CIR.FAST.RULES.CRED.NOTJUST.RAS.BIGS.CYC.BOB.COM.
HAM.END.THE.

Each part is loaded, called, allowed to own VGA for a while, and then returns to the loader. This makes the demo feel like one large hand-authored timeline, but the executable structure is closer to a tiny DOS module player.

Credits And Release Notes

The release text credits:

Program:  Maxwood / Majic 12
Graphics: Rack / Majic 12
Music:    Chorus & Sid
Replay:   Cascada GUS routines

END.DAT also contains the demo's own end text. It says the demo was released at Hammering 1994 in Budapest, was compiled with Turbo Assembler, and was written on a 386DX/40 with a Tseng ET4000. That last detail matters: a lot of the code is very explicitly 386-era real-mode VGA code. It avoids a protected mode runtime and spends its budget on precomputed tables, self-modifying code, and direct VGA register control.

Outer EXE Layout

The MZ header has these useful fields:

e_cblp    = 0000h
e_cp      = 0023h       ; MZ image size = 35 * 512 = 17920 bytes
e_cparhdr = 0020h       ; 512-byte header
e_crlc    = 0007h       ; only seven relocations
CS:IP     = 001c:1446h
SS:SP     = 0000:01c0h

The entry point's raw file offset is:

0x200 + 0x1c * 16 + 0x1446 = 0x1806

There are no obvious PKLITE, RNC, PMODE, DOS/4G, or LZ91 packer markers in SHOW.EXE. The large file size is not a packed protected-mode blob; it is mostly an appended effect and asset store.

The loader contains the show script string at file offset 0x919, followed by user-facing error text such as Not enough memory and the Gravis prompt. The internal resource table begins near file offset 0x1aa802.

Resource Directory

The resource directory is read from the executable itself. Each entry is 18 bytes:

00..0b  zero-padded DOS-style filename, e.g. "TMAP.COD"
0c..0f  32-bit file offset, stored as high word then low word for int 21h seek
10..11  16-bit read length

The loader uses two file names for each visible part:

PART.COD  executable code module
PART.DAT  data, graphics, lookup tables, or text for that module

The loaded memory layout is consistent across modules:

code segment = allocated aligned segment
data segment = code segment + 1000h

The loader reads *.COD to offset zero in the code segment, reads *.DAT to offset zero in the data segment, sets up a call contract, and far-calls the loaded code through its module dispatch pointer.

The register contract visible at the call site is:

DS = module data segment
AX = data segment + 1000h, used by some parts as scratch or extra buffer space
CX = loader code segment
DX = loader/Cascada music control offset, observed as 2fd4h
BP = Cascada GUS code segment, observed as 01b1h
BX = Cascada GUS routine offset, observed as 22c8h

Several modules save AX immediately and use it later as a scratch segment. PIXEL.COD, for example, loads it into GS and stores addresses of changed screen bytes there so the next frame can erase only the dirty pixels.

Loader Inner Loop

The loader's own main loop is small but important:

; conceptual form of the part loop
show_ptr = address_of("SKULL.START.QQ...")

while *show_ptr:
    name = read_until_dot(show_ptr)
    cod_name = name + ".COD"
    dat_name = name + ".DAT"

    ; Special case: a module name ending in ".COM" can be rewritten to ".KOM"
    ; depending on the loader's speed/timing variable.

    cod_rec = find_record(cod_name)
    dat_rec = find_record(dat_name)

    read_exe_range(cod_rec.offset, cod_rec.size, code_segment:0000)
    read_exe_range(dat_rec.offset, dat_rec.size, data_segment:0000)

    call_far_module_entry()

The loader has one odd adaptive branch around the COM part. If the parsed module name ends in COM and a loader timing/speed variable is below or equal to 7, it rewrites the first letter to K, so COM.COD becomes KOM.COD. Both module pairs are present in the directory. That strongly suggests COM and KOM are alternate implementations of the same visible slot, probably selected for machine speed or timing tolerance.

Keyboard And Sound

The loader installs its own interrupt 9 keyboard handler:

in   al,60h          ; read scancode
mov  cs:[0625],al
in   al,61h          ; keyboard acknowledge toggle
or   al,80h
out  61h,al
and  al,7fh
out  61h,al
mov  al,20h
out  20h,al          ; end of interrupt
iret

That gives every part a cheap "last scancode" location without calling BIOS in the render loop. The old interrupt vector is saved and restored on exit.

For music, the startup code probes or asks for a Gravis UltraSound port, then calls the Cascada replay routines. The visual parts receive enough loader state to poll a sync/control word. In several effects the outer frame loop waits for a nonzero word at the loader-provided location before drawing the next step. That is the demo's music/timer pacing hook.

Module Inventory

The table below uses sizes from the extracted resource table and entry offsets from the first jump in each *.COD module. The "role" column is intentionally code-oriented. When the visual name is certain, it says so; otherwise it says what the binary actually proves.

Module COD bytes DAT bytes Entry Role
SKULL 23968 60736 0x5600 Opening skull/logo-style planar part; uses A000/A800, direct VGA, and large picture data.
START 64816 24343 0xf8ec Large title/start part; very near 64 KB of code, mostly asset decode and VGA presentation.
QQ 45674 42576 0xad93 Large table-driven visual part; exact caption is not obvious statically.
ROT 31048 64000 0x6b98 Rotation/object part; sizeable trigonometric/table render core and planar output.
CH 6142 128 0x1414 Small control/transition part; almost no external data, mostly code and palette state.
COPPER 672 9004 0x004d Hardware-timed raster/copper bars using retrace polling and VGA palette writes.
16C 1424 52931 0x01a2 16-color picture/palette display; compact code with large image data.
1LAP 608 2528 0x000b Short bridge/transition; VGA timing and palette writes dominate.
PIXEL 55607 30960 0xcbf4 3D pixel/vector object with classic planar Bresenham line inner loops.
TMAP 24288 65343 0x5602 Texture-mapped column/strip renderer, probably the most interesting core renderer.
DO 1860 15360 0x000b Short bridge or picture part; small code, medium data, VGA transition behavior.
TRON 2048 51954 0x0007 Tron/grid line part with planar setup and page flipping.
C 4736 23912 0x0336 Graphics-controller-heavy planar blitter/effect; many GC and sequencer writes.
DOOM 50734 21248 0xc123 Doom-inspired scanned-picture scaler with generated column-copy codelets.
NEWG 16338 10208 0x39c9 Larger graphics effect; direct VGA, palette, and buffer work.
STOP 752 11042 0x004e Compact ILBM/PBM-style picture transition; data contains FORM/ILBM markers.
ART 320 54966 0x0007 Picture viewer with PBM, BMHD, CRNG, and BODY chunks.
ZZZ 8437 65535 0x0d2b Data-heavy full-screen part; many generated/stos-style fills, likely sleep/ZZZ themed.
INTER 592 7083 0x000b Intermission picture viewer; data contains FORM/ILBM/BODY.
CIR 1744 26530 0x000b Circle/ring transition; compact code and large lookup/image data.
FAST 8115 51040 0x0025 Fast full-screen effect; data contains <Maxwood/Majic 12>.
RULES 6942 48096 0x1377 Rules/text or page sequence; moderate renderer plus large data bank.
CRED 896 42883 0x000b Credits picture pages; multiple PBM and CRNG chunks.
NOTJUST 880 14302 0x00ec Short ILBM-backed text/picture part; data contains FORM/ILBM/BODY.
RAS 1120 1530 0x00ae Raster-bar/palette split part; small data and direct VGA register writes.
BIGS 774 43632 0x0007 Big text/bitmap display; tiny code driving large image data.
CYC 8736 60474 0x1a96 Color-cycling picture engine; code and data contain FORM, PBM, BMHD, CRNG, BODY.
BOB 7800 28768 0x052e Blitter object/sprite part; "BOB" name matches the block-move style renderer.
COM 17913 51200 0x3297 One implementation of the adaptive COM slot; heavy planar drawing with many clears.
KOM 25932 51200 0x4197 Alternate implementation of the same slot, selected by loader rewrite on some timings.
HAM 14282 65535 0x2ee4 Hammering/party section or late-demo full-screen part; large data bank.
END 53568 53261 0xcc02 Long end sequence and text scroller; END.DAT contains the demo's release commentary.
THE 576 11636 0x000d Final picture/page; data contains PBM, CRNG, and BODY chunks.

The resource table also contains BEGIN and PERS. They are not in the main show script string I found, so they are either unused, called indirectly, or left over from development:

Module COD bytes DAT bytes Entry Role
BEGIN 752 7120 0x004a ILBM-backed picture/init module; not in the main show script.
PERS 2736 65196 0x0710 Perspective-related resource by name and size; not in the main show script.

Part-By-Part Reading

SKULL opens with a large planar display part. Its data bank is almost 60 KB, and the code hits both A000 and A800, which in this demo usually means the part prepares one page while another page is visible. It uses direct Sequencer and Graphics Controller programming rather than BIOS drawing. The role is most likely the opening skull/logo visual implied by the name.

START is the largest individual code module after the loader. Its entry is at the end of the COD file, and the preceding region is mostly helper code, tables, and unrolled routines. That shape usually means the part jumps over embedded routines/data into a high-offset entry point. Its role is the title or start presentation: it is not a tiny transition, it is a full renderer.

QQ is another large, precomputed, asset-driven module. It uses palette and VGA timing routines but has no readable caption strong enough to name the visual from static evidence alone. The safe statement is: it is a full-screen graphics effect, not a simple text page.

ROT is the first obviously computational part in the timeline. The name, module size, table density, and planar screen access point to a rotation effect: rotating bitmap, rotating object, or rotating coordinate field. The code's shape is not a raw picture viewer; it spends significant time on table-driven address and pixel generation before touching the visible page.

CH is a short control or transition part. Its .DAT is only 128 bytes, so it cannot be showing a substantial image from external data. It is mostly code and state, probably bridging between the earlier full-screen visual and the hardware-timed COPPER part.

COPPER is the cleanest hardware trick in the demo. It sets a 16-color VGA/EGA graphics mode, extracts palette bytes from an ILBM-style BODY image, and then changes hardware state in sync with the raster. It polls 3DAh, writes the Attribute Controller through 3C0h, and uploads DAC values through 3C8h/3C9h while a fade counter changes. This is "copper" in the Amiga sense: not a real PC copper, but a carefully timed CPU loop pretending to be one.

16C is a compact 16-color display part. The code is small and the data is large, which is typical of "show a prepared picture with some palette or scrolling treatment". It also writes VGA planar registers, so it is not a linear 256-color mode part.

1LAP is a small transition. The code uses DAC writes, 3DAh retrace waits, and CRTC/Attribute Controller writes. It likely exists to pace or wipe into the next large effect rather than to carry its own complex renderer.

PIXEL is a major renderer. It transforms points, projects them, then draws line or pixel structures into planar VGA memory. It tracks dirty screen bytes in a scratch segment so the next frame can clear exactly those addresses. Its inner loop is a classic 386-era planar Bresenham plotter, described in detail below.

TMAP is the texture-mapping core. It builds row tables, bit-mask tables, texture delta tables, and interpolation tables, then draws projected vertical strips into a scratch buffer before copying to the screen. This is the most "demo engine" looking part in Show: the renderer is not just blitting a picture, it is using precomputed tables to make texture mapping fast enough on a 386.

DO is a small bridge part. Its data is large enough for graphics, but the code is far smaller than the major renderers. It likely displays or transitions a prepared page.

TRON draws a grid-like line scene. It initializes planar masks, draws horizontal and vertical line structures into two pages, and flips or scrolls by changing CRTC display-start registers. The name and line-grid code agree.

C is a compact planar graphics effect. It writes heavily to the VGA Graphics Controller (3CEh) and Sequencer (3C4h), so its visual work depends on planar masking and read-map/write-map tricks rather than normal byte-per-pixel output.

DOOM is the famous/fancy one in this executable. SHOW.TXT says the Doom effect picture is scanned, and the code matches a scanned-picture scaler: it enters mode 13h, tweaks VGA registers, generates tiny copy routines, and calls those generated routines per column. It is not a Doom engine; it is a Doom-like wall/picture zoomer built from vertical scalers.

NEWG is a medium-large graphics part. It has enough code to be an effect rather than a static page, but without a stronger embedded text label I would not assign a precise visual beyond "new graphics/effect slot".

STOP, ART, INTER, CRED, NOTJUST, and THE are picture/page modules with Amiga-ish file markers in their data (FORM, ILBM, PBM, BMHD, BODY, and often CRNG). Their code is tiny compared with their data. That means they mostly decode or present prepared images, sometimes with color cycling rather than geometric rendering.

ZZZ is data-heavy and fill-heavy. The code contains many store/fill patterns, so it is more active than a minimal picture loader, but the static name is the strongest visual label here. Treat it as a themed full-screen part with large prepared assets.

CIR is a compact circle/ring effect. Its module name and data/code ratio suggest precomputed circle or radial tables feeding a small VGA renderer.

FAST contains the literal <Maxwood/Majic 12> in its data and has a renderer large enough to do more than show a single bitmap. This is probably one of the author-signature or fast-moving text/bitmap sections.

RULES is likely a text/page section. It is too large to be only a palette fade, but not shaped like the big geometric renderers. The name says "rules", and the data size says prepared content.

RAS is the raster-bar module. It is tiny, writes the DAC and VGA registers, and has only 1530 bytes of data. This is a timing/palette trick rather than an asset-heavy picture part.

BIGS is a large bitmap/text presenter: tiny code, huge data. The name likely means "big scroller" or "big letters". Static evidence cannot distinguish those two without frame capture, but the implementation class is clear.

CYC is a color-cycling picture engine. Both code and data contain CRNG markers, the Amiga IFF color-range cycling chunk. The module is not only showing a picture; it is animating palette ranges.

BOB is almost certainly a sprite/blitter-object part. In Amiga terminology, a BOB is a blitter object. On PC VGA there is no Amiga blitter, so the module does the moving/copying itself with CPU loops and planar masks.

COM/KOM are the adaptive pair. The loader has one visible COM slot, but it can rewrite COM.COD to KOM.COD before loading. The two implementations share the same data size. This is a neat production detail: the timeline has one logical part, but the binary ships more than one renderer path for it.

HAM and END are late-demo sections. END.DAT contains the release comments, technical bragging, BBS adverts, and closing text, so END is definitely a long text/end sequence rather than an abstract effect.

VGA Model

Most parts are planar VGA, not chunky mode 13h. A typical module writes:

mov dx,3c4h
mov ax,0202h
out dx,ax       ; Sequencer index 2, map mask

mov dx,3ceh
mov ax,0005h
out dx,ax       ; Graphics Controller mode

mov ax,0a000h
mov es,ax

In planar modes, one byte in A000 represents eight horizontal pixels on one or more bitplanes. That is why many inner loops look strange if read as byte-per-pixel drawing. They are not writing color indices directly. They are selecting planes, rotating bit masks, and ORing prepared bit patterns into screen bytes.

Several modules also use A800. In real mode, segment A800h addresses A0000h + 8000h, so it is the second half of VGA memory. The demo uses that as an alternate page or staging area, then changes CRTC display-start registers to select what is visible.

Inner Loop 1: TMAP.COD Texture Strip Renderer

TMAP enters at 5602h. Its setup sequence does four important things:

  1. Saves the loader-provided scratch segment from AX.
  2. Builds a row-offset table where each scanline advances by 28h bytes.
  3. Clears the scratch buffer with rep stosw.
  4. Builds lookup tables for planar masks, texture deltas, and projection.

The row table proves this renderer is still planar. A 320-pixel-wide planar line is 40 bytes, which is exactly 28h.

The main frame loop toggles between visible pages. It changes CRTC registers 0Ch and 0Dh to set the display start, waits for vertical blank, copies a prepared scratch rectangle to the active page, clears the scratch spans, and then renders new strips.

The core strip routine is at 5a08h. In simplified form:

; Inputs have already been prepared by the edge/projection code.
; BP = texture/sample pointer
; DI = destination offset in scratch buffer
; CX = height / 4
; DX = 0028h, one planar scanline
; BX selects a precomputed mask/pattern table

strip_loop:
    bl = ds:[bp]       ; sample texture/source byte
    bx = bx * 2
    ax = table[bx]     ; planar mask/pattern for this texture sample
    es:[di] |= ax      ; merge into scratch word
    di += 28h          ; next scanline
    bp += next_delta() ; texture step from lodsw table

    ; repeated three more times, unrolled
    ; ...

    loop strip_loop

tail:
    ; same operation for height & 3 remaining pixels

The real loop is more compact and uses lodsw to fetch the next texture advance. It also uses bit rotations and a mask table so a vertical strip can land at arbitrary bit alignment in the planar byte layout.

What this accomplishes:

This is exactly the kind of 386 texture mapper that survives by moving work out of the frame loop. Expensive choices are turned into tables. The runtime hot path is mostly: load sample, table lookup, OR word, add row stride.

TMAP Projection Side

The strip loop is fed by several helper routines:

5ba7h  transforms vertices using sine/cosine tables
5c0fh  perspective-projects coordinates with signed division
5906h  chooses edge order and prepares strip parameters
5a08h  draws the projected vertical strip

So the flow is:

object/texture state
    -> transform
    -> perspective projection
    -> edge/strip setup
    -> vertical strip inner loop
    -> scratch-to-page copy
    -> CRTC page flip

The result is not a general polygon engine in the modern sense. It is a specialized mapper shaped around the exact visual it needs to draw, with planar VGA constraints baked into the lookup tables.

Inner Loop 2: PIXEL.COD Bresenham Planar Plotter

PIXEL enters at cbf4h. It saves the loader sync pointer, stores the loader-provided scratch segment in GS, sets ES=A000h, builds a 40-byte row table, and initializes the VGA palette and CRTC.

The renderer has three major phases:

1. Transform 3D points through sine/cosine tables.
2. Project them into screen-space x/y coordinates.
3. Draw line lists with planar Bresenham routines.

The dirty-byte strategy is important. Every time the plotter touches a screen byte, it stores that byte's address in GS:[bp]. On the next frame the module can erase only those bytes instead of clearing the whole page.

One of the x-major line routines has this structure:

; x-major, positive x direction, positive y direction
di = row_table[y0] + (x0 >> 3)
cx = abs(dx) + 1
si = abs(dy)
bx = abs(dx)
err = bx >> 1
al = bit_mask_for_x0

line_loop:
    es:[di] |= al      ; set one planar pixel bit
    gs:[bp] = di       ; remember dirty byte
    bp += 2

    ror al,1           ; next x bit in this byte
    if carry:
        di += 1        ; crossed into next screen byte

    err += si
    if err >= bx:
        err -= bx
        di += 28h      ; next scanline

    loop line_loop

The code has four variants:

x-major, x increasing
x-major, x decreasing
y-major, x increasing
y-major, x decreasing

That avoids branches inside the pixel loop for sign and major-axis decisions. The setup routine selects the correct routine before entering the hot loop.

This is a textbook 1994 planar line renderer:

PIXEL is therefore not a generic "plot pixels" label. It is a real vector object renderer built around the weirdness of planar VGA memory.

Inner Loop 3: DOOM.COD Generated Vertical Scaler

DOOM enters at c123h. Unlike many other modules, it starts from BIOS mode 13h and then tweaks VGA:

mov ax,0013h
int 10h

; then Sequencer/CRTC changes, page setup, DAC upload

SHOW.TXT says the Doom effect picture was scanned. The data and code match that description: this part is a picture scaler that produces a Doom-like wall motion, not a raycaster.

The most interesting routine is the code generator at c56ch. It emits tiny copy routines into memory. Each generated routine is a sequence of:

mov al,[si+source_displacement]
mov es:[di+dest_displacement],al

followed by retf.

Conceptually:

for each scale_level:
    code_ptr = output_code_area

    for each destination sample in this vertical column:
        emit "mov al,[si+src]"
        emit "mov es:[di+dst],al"

    emit "retf"
    scale_table[scale_level] = code_ptr

Then the visible frame renderer can choose a scale level and call the already generated codelet instead of interpreting a scaler loop every time.

The frame side does roughly this:

build/adjust column boundary arrays
for each visible x column:
    choose VGA write mask / page
    choose scale codelet
    call generated far routine
    clear top/bottom overdraw if needed
flip or scroll page with CRTC start

This is why the part has a large COD file and a comparatively smaller DAT file. The image data is important, but the visual speed comes from runtime-generated specialized column copy code.

The generated-scaler approach is especially suited to 386 real mode:

Inner Loop 4: COPPER.COD Raster Timing

COPPER is tiny enough to understand as a complete effect. It starts by:

1. Setting graphics mode 0Dh.
2. Clearing DAC entries.
3. Setting CRTC offset register 13h to 28h.
4. Initializing BIOS/VGA palette state.
5. Finding the `BODY` marker in its ILBM-style data.

The setup routine extracts palette bytes from the data and shifts them down to VGA's 6-bit DAC range. It also initializes a rotating plane mask.

The frame loop combines music/timer sync, display-start changes, horizontal timing, Attribute Controller writes, and palette fade. The core timing part is:

mov dx,3dah

wait_vblank_or_retrace:
    in  al,dx
    test al,08h
    jz  wait_vblank_or_retrace

wait_horizontal:
    in  al,dx
    test al,01h
    jz  wait_horizontal

mov dx,3c0h
mov al,33h
out dx,al
mov al,low(scroll_or_phase) & 7
out dx,al

After that it streams palette values:

mov dx,3c8h
xor al,al
out dx,al           ; start at DAC index 0
inc dx              ; 3c9h

for i in 0..2fh:
    al = palette[i] - fade
    if al < 0: al = 0
    out dx,al

On the Amiga, a copper list can change registers at specific raster positions without CPU involvement. On VGA, this code does it by burning CPU cycles in polling loops. The visual idea is the same: change color/scroll state while the display is being scanned.

Inner Loop 5: TRON.COD Grid And Page Flip

TRON is small and very direct. Its setup routine selects all VGA planes, then draws a static line/grid frame into two memory regions:

A000: first page
A800: second page

The grid setup writes repeated ffffh line patterns at fixed offsets and then places vertical markers every 28h bytes, matching the planar row stride.

The frame loop changes CRTC display start registers:

mov dx,3d4h
mov al,0ch
out dx,al
inc dx
mov al,display_start_high
out dx,al

dec dx
mov al,0dh
out dx,al
inc dx
mov al,display_start_low
out dx,al

This is a cheap way to move or flip the visible page without copying the entire screen. The expensive grid drawing is done once; the CRTC start address makes the image appear to move.

Picture And Color Cycling Parts

Several data files are recognizably Amiga-style image containers:

ART.DAT     FORM / PBM / BMHD / CRNG / BODY
CRED.DAT    FORM / PBM / BMHD / CRNG / BODY
CYC.COD     FORM / PBM / BMHD / CRNG / BODY markers in code/data path
INTER.DAT   FORM / ILBM / BMHD / BODY
NOTJUST.DAT FORM / ILBM / BMHD / BODY
STOP.DAT    FORM / ILBM / BMHD / BODY
THE.DAT     FORM / PBM / BMHD / CRNG / BODY
COPPER.DAT  FORM / ILBM / BMHD / BODY

The presence of CRNG is a strong clue. In IFF pictures, CRNG chunks describe color cycling ranges. A PC demo can emulate that by rotating DAC palette entries instead of redrawing pixels. That is why some of these modules have tiny code and very large data: the animation is mostly palette manipulation.

CYC is the most explicit color-cycle module. It has many CRNG markers and a larger code body, so it likely parses or applies multiple color ranges rather than just showing one page.

Why The Demo Feels Fast On A 386

The demo repeatedly uses the same performance strategy:

precompute tables
specialize the renderer to the exact effect
draw into a scratch page
copy or page-flip during retrace
avoid full clears when a dirty list is enough
let the VGA hardware handle planes, masks, starts, and palette

Examples:

This is also why the code is difficult to read as a single "engine". It is not one engine. It is a collection of specialized inner loops that share only the loader, music, keyboard, and some VGA idioms.

The Most Important Takeaways

Show is a good example of late real-mode DOS demo engineering. It has no big protected-mode framework and no single clean renderer abstraction. Instead it uses a small loader to sequence many hand-built effects, each with its own tables and VGA assumptions.

The strongest inner loops are:

TMAP   table-driven planar texture strip renderer
PIXEL  dirty-list Bresenham vector/pixel renderer
DOOM   generated vertical scaler for scanned-picture wall motion
COPPER retrace-polled VGA palette/raster trick
TRON   page-start grid movement using CRTC display start

The weaker, asset-heavy parts are still important to the pacing, but their code mostly says "decode/display/cycle this prepared image" rather than exposing a new renderer. The real technical signature of the demo is the way Maxwood combines those prepared visuals with a few very concentrated hand-optimized inner loops.