Analysis model: gpt-5.5 xhigh

Trance by CCS - Technical Dissection

Scope

Trance is a 1993 MS-DOS demo by CCS. The Party 1993 results list it as the tenth-place PC demo entry, behind Lost in space and ahead of X Mas 93. Scene.org keeps the public package as trance.zip in the The Party 1993 PC demo directory.

Public references:

This writeup is based on the scene.org archive, bundled notes, MZ header parsing, static 16-bit disassembly of the DOS load image after its MZ header, and byte-level inspection of the TRANCE support file. It is not a source-level rebuild or a runtime capture.

Private BBS/contact details embedded in the executable are deliberately omitted.

Release Context

The bundled notes describe Trance as a fast-coded text-mode demo written in Turbo Pascal 5.5 in roughly two weeks. The unusual claim is that it uses standard VGA text mode 3 rather than the normal 320x200 graphics mode. The same notes say it was intended to be an intro, but self-made samples pushed it beyond that kind of size budget.

The stated requirements are:

The code supports those notes. The executable is a Borland/Turbo Pascal style MZ program, uses B800 text memory directly, polls VGA retrace, modifies the VGA font plane through A000, probes Sound Blaster DSP bases, and has a fallback parallel-port DAC routine.

Examined Files

Archive hash:

d82467ef50e90b5da765b6c164387f3f115630ef991c39b2543d70c3a59a2859  trance.zip

Extracted files:

DEMO.NFO       1000 bytes  release notes
FILE_ID.DIZ     150 bytes  short party/rank description
TRANCE       821028 bytes  support file: text screens, tables, samples
TRANCE.EXE    21920 bytes  DOS MZ executable

Extracted hashes:

b2fef01cdcb23e8352ae305814baf4f194b6de0f78c0a1e6c5338fe17fa721cc  DEMO.NFO
627510b145d334bfa6f502551617e32ea0cae9aeba064a2003ab0385d9709e01  FILE_ID.DIZ
51b21134209fe1589eb1cce426c982d2d92e6c4dafa6608f889af9b08e07566a  TRANCE
8b8fb65158888cd3aa2c6d4e1ce5937b2d39ef604ff00b16d99c8db16b4c047f  TRANCE.EXE

The ZIP stores four files with normal deflate compression. The uncompressed payload totals 844,098 bytes, most of it in the TRANCE support file.

MZ Layout

TRANCE.EXE is not packed by PKLITE or LZEXE. It is a normal relocated MZ executable:

file size       21920 bytes
MZ image size   21920 bytes
header size       912 bytes
relocations       221
min/max alloc     046a/a46a paragraphs
entry             0000:3844
entry file off    0x3bd4
stack             058b:4000

After removing the 912-byte MZ header, the load image is 21,008 bytes. The image has 45 obvious Pascal-style procedure prologues (55 89 e5). The first few are wrappers around DOS file operations; the main program entry is at image offset 3844h.

Important helper offsets:

0002h  open file wrapper, DOS int 21h AH=3Dh
007eh  read file wrapper, DOS int 21h AH=3Fh
00bfh  close file wrapper, DOS int 21h AH=3Eh
00e2h  seek file wrapper, DOS int 21h AH=42h
01b4h  write character and attribute into B800 text memory
0270h  write only the text attribute byte
02b6h  read a B800 character/attribute word
02ech  wait for vertical retrace through port 3DAh
0307h  copy 4096 bytes from B800 page 0 to a text page
0346h  copy 4096 bytes from a text page back to B800 page 0
03cbh  write one DAC color through 3C8h/3C9h
03f0h  read one DAC color through 3C7h/3C9h
0bd2h  Sound Blaster DSP probe
0c52h  Sound Blaster direct-DAC sample output
0cdfh  parallel-port DAC sample output
0d1ah  CRTC start-address write through 3D4h/3D5h
0e3eh  first scene procedure
1473h  second scene procedure
1bf6h  third scene procedure
20b7h  fourth scene procedure
28b2h  fifth scene procedure
2e87h  sixth scene procedure
332ch  cleanup and restore procedure
3844h  program entry

Text-Mode Renderer

The central trick is that Trance treats text mode as the demo surface.

The cell writer at 01b4h computes:

offset = row * 80 * 2 + column * 2

Then it writes the character byte to B800:offset and writes the attribute byte to B800:offset+1. The attribute is built as (background << 4) | foreground. One branch preserves selected old attribute bits with AND 87h, so effects can change color without completely rebuilding the cell.

The page helpers at 0307h and 0346h copy 1000h bytes between page 0 and a page selected by page << 12. A visible 80x25 text page is 4000 bytes; copying 4096 bytes gives each page a tidy 4 KB stride with small slack. The CRTC helper at 0d1ah writes registers 0Ch and 0Dh, which are the high and low bytes of the display start address. That lets the demo move or swap text pages through the VGA start address rather than repainting everything cell by cell.

The vertical-retrace wait at 02ech is the usual two-phase poll of input status register 3DAh: wait until bit 3 is clear, then wait until it becomes set. That is the same synchronization point the release notes blame for audible sample interruptions.

VGA Font And Palette Work

Despite being a text-mode demo, the executable still talks to A000. The A000 references are in font-plane helpers, not ordinary 320x200 bitmap drawing. Routines around 04dch, 0550h, 06fch, and 08edh program the VGA sequencer at 3C4h and graphics controller at 3CEh, then read or write bytes through A000h. That is the standard way to access the VGA character generator plane while in text mode.

The package also carries screen/font-looking material in TRANCE. Around support-file offset 5CD0h there is a FontEd marker, which fits the custom text-mode appearance: the demo is using mode 3, but not relying on the stock BIOS font.

Palette code is present too:

03cbh  output index to 3C8h, then R/G/B bytes to 3C9h
03f0h  output index to 3C7h, then read R/G/B bytes from 3C9h

At startup, the main path saves 70 palette entries: it loops from 0 to 45h and stores three bytes per entry in temporary memory at 8000:8002. Cleanup later restores those entries before returning to DOS.

Sound Output

The Sound Blaster probe at 0bd2h scans candidate bases from 210h through 280h in 10h steps. For each base it:

write 1 to base+6        ; DSP reset
delay
write 0 to base+6
poll base+0Eh bit 7
read base+0Ah
accept the card if the byte is AAh

On success it sets byte 004Eh to 1 and stores the base port in word 0050h.

The Sound Blaster sample writer at 0c52h recenters the unsigned sample around a midpoint byte at 0062h. Values on the lower side are clipped at 7Fh; values on the upper side are clipped at 80h. The routine then waits for the DSP write buffer at base+0Ch, writes command 10h, waits again, and writes the sample byte. Command 10h is the classic 8-bit direct-DAC output path.

The fallback at 0cdfh is deliberately blunt. It shifts the sample according to the same midpoint state and writes the result to all three supported printer ports:

278h
378h
3BCh

The code calls both output helpers from several scene loops. The Sound Blaster path only produces output when the probe flag is set; the LPT DAC path is cheap enough to broadcast to every expected port.

Support File Structure

TRANCE is 821,028 bytes (0C8724h). It contains all 256 byte values, but the frequency distribution is strongly centered around 80h:

00h bytes  18742
81h bytes  14940
7Fh bytes  14869
80h bytes  14790
82h bytes  14484
7Eh bytes  14310
83h bytes  14214
7Dh bytes  13963

That is consistent with a support file that mixes tables and screens at the front with unsigned 8-bit sample data deeper in the file.

The early blocks are not uniform sample data:

offset   notes
00000h   mostly zero, then low-value ramp/table data
001E2h   visible ascending/descending byte ramp
01000h   printable star/bar pattern followed by zeros
02001h   dense centered data
05CD0h   FontEd marker inside screen/font-like data
06D07h   another small scene/screen chunk
08D08h   large centered sample-like region starts

The executable reads the support file through its own DOS wrappers. Observed seek/read pairs include:

seek 000000h, read 2001h bytes to 8000:0000
seek 002001h, read 3CDEh bytes to 8000:3000
seek 005CDFh, read 1028h bytes to 8000:0000
seek 006D07h, read 2001h bytes to 8000:0000
seek 008D08h, stream in 3000h-byte chunks
seek 0547F8h, read 01D1h bytes to 8000:0000
seek 0549C9h, read 0201h bytes to 8000:0000
seek 054BCAh, stream in 3000h-byte chunks
seek 094BF0h, read 0201h bytes to 8000:0000
seek 094DF1h, read 04E3h bytes to 7000:0000
seek 0952D4h, stream in 3000h-byte chunks

So the large support file is a sequenced resource and sample bank. The demo does not decompress a single monolithic archive; it seeks to fixed offsets and loads exactly the chunks needed by the current part.

Main Program Flow

The entry path at 3844h begins with Turbo Pascal runtime initialization, then masks the keyboard IRQ bit in the PIC mask and saves the current video state. It opens the support file named trance. If the file is missing, it displays a short text-mode error path, polls keyboard port 60h, and exits.

On the normal path it:

save the first 70 DAC entries
open and keep the TRANCE support file handle
probe Sound Blaster bases
turn on the DSP speaker with command D1h if a card was found
set sample midpoint byte 0062h to 80h
clear stop flag 0074h
run scene procedures 0e3e, 1473, 1bf6, 20b7, 28b2, 2e87
repeat that scene group until stop flag 0074h becomes nonzero
run cleanup at 332ch
restore text display and palette state

The scene procedures share the same vocabulary: B800 cell writes, page copies, CRTC start-address changes, font-plane access through A000, retrace waits, and sample-byte output. That is why the demo can feel animated while staying in VGA text mode.

Hardware Marker Summary

Immediate hardware-marker hits in the load image:

B800 text segment references          54
A000 font-plane references            35
VGA retrace port 3DAh                  2
DAC ports 3C7h/3C8h/3C9h              1/2/6
VGA sequencer port 3C4h               12
VGA graphics controller port 3CEh     18
CRTC ports 3D4h/3D5h                   2/2
LPT DAC ports 278h/378h/3BCh           1/1/1
keyboard port 60h                      3
PIT channel 0 immediate-write pattern 18

This marker profile is the production in miniature. It is not a Mode X polygon demo and not a pure text scroller. It is a VGA text-mode program that still uses the lower-level VGA machinery normally associated with graphics demos.

Technical Character

Trance is useful precisely because it is off the usual 1993 PC-demo path:

The result is not technically flashy in the same way as the better-known The Party 1993 winners. Its interest is narrower and stranger: it is a text-mode demo that borrows just enough VGA and audio hardware control from graphics demos to turn mode 3 into a real production surface.