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:
- Scene.org archive: https://archive.scene.org/pub/parties/1993/theparty93/demo/trance.zip
- Scene.org The Party 1993 demo directory: https://archive.scene.org/pub/parties/1993/theparty93/demo/
- Scene.org The Party 1993 results: https://archive.scene.org/pub/parties/1993/theparty93/results.txt
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:
- 386/40 MHz class machine, with cache or shadow RAM helping performance.
- 1 MB RAM.
- Color VGA.
- Sound Blaster compatible card, or a D/A converter on LPT
278h,378h, or3BCh.
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:
- It deliberately uses VGA text mode 3 as the primary display.
- It customizes the text-mode look by accessing the VGA font plane through A000 and VGA sequencer/graphics-controller registers.
- It uses direct B800 page copies and CRTC start-address changes for animation.
- It keeps music out of the picture and drives self-made 8-bit samples instead.
- It supports both Sound Blaster direct DAC and crude parallel-port DAC output.
- It streams an 821 KB support file with fixed DOS seeks rather than bundling a compact single-binary intro.
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.