Analysis model: GPT-5 (Codex), reasoning level not exposed
Last edited: 2026-08-30
BBS-A-Holic BBS (2) by The Humble Guys - Technical Dissection
BBS-A-Holic BBS (2) is a real 1991 MS-DOS BBStro, but it is a much smaller
kind of production than a realtime cracktro. The only surviving file is a
3,762-byte executable made with GRABBER 3.60. It expands one signed 80x25
colour-text page, copies the resulting 4,000 bytes to B800h, waits for a key
and restores the previous display state.
The distinction matters. The large left-hand lettering and bordered board ad are original CP437/attribute artwork; the decompressor, video setup, optional timer and key handling belong to G.A. Monroe's generic GRABBER viewer. There are no vector balls, custom bitmap graphics, music or hidden second screen.
Release year: 1991.
The previous research queue associated this file with a THG Lemmings
release. The examined archive does not support that claim: it contains only
THGSITE!.EXE, with no game, release note or companion metadata. This page
therefore treats it as a genuine standalone board advert attributed to The
Humble Guys by the surviving catalogues, not as a proven software-bundled
cracktro.
Sources
Demozoo identifies the production as a 1991 MS-DOS BBStro by The Humble Guys
and an advert for BBS-A-Holic. Pouet independently gives the same year, group,
platform and board-ad identity. Neither catalogue supplies an artwork credit.
The visible footer in the executable signs the ANSI as D·ToX <ACiD> / Little T; that literal signature is reported without trying to map it to catalogue
person records that are not present.
Examined Artifact
The archive has one member:
79394f3638b2a09ada655e90310cbd017da0accd7994891d52bc9a279358dce2 bbs-a-holic_bbs2.zip
b7abdb261d044c774520d7b586740679e6d48a0b8293f8bb38c5d50a1a2494e6 THGSITE!.EXE 3,762 bytes
Its ZIP timestamp is 22 November 2016, the day the production was added to Pouet, so it is a preservation timestamp rather than release-date evidence. The year on this page comes from the catalogues.
The executable identifies its generator internally:
Created by GRABBER (tm) Version 3.60
Copyright (c) G.A. Monroe 1987, 1988, 1989, 1990
That tool identity is consistent with the code: a general-purpose viewer
parses /F, /N, /K and /T command-tail switches, detects the active
adapter, allocates a screen buffer, expands a stored image and optionally
times the display. The examined default route uses none of those switches.
Complete Silent DOSBox-X Run
The exact executable was run directly under DOSBox-X 2026.01.02 on 30 August
2026 with machine=svga_s3 and 3,000 fixed cycles. SDL video and audio used
dummy host drivers; the mixer had nosound=true, and Sound Blaster, MIDI, PC
speaker and Tandy audio were disabled. The file neither requires nor attempts
sound output.
One scripted Enter key traversed the complete route. The program displayed its single page, accepted the key, restored the prior mode and returned normally to DOS. The capture lasts 8.043 seconds. Its private MPEG-TS diagnostic contains an empty AAC stream created by the capture container and is not published.
DOSBox-X produced 720x400 video samples with sample aspect ratio 20:27. The
still below is the complete frame at 00:02, converted with nearest-neighbour
scaling to 720x540 square pixels without cropping or padding:

The page includes only an area-code placeholder and explicitly tells the reader to obtain the number elsewhere. No telephone number is present in the executable, so the complete authored frame can be shown without reproducing historical contact data.
The emulator log records one benign INT 16h extension-probe call before the
screen. That is the viewer's AX=4752h, DL=FFh capability query, not a
failed runtime gate; the page appears, the later Enter is accepted and the
process exits normally.
MZ Shape And A 48-Byte Length Quirk
The executable is not packed by PKLITE, LZEXE or a self-modifying wrapper. It is an ordinary zero-relocation MZ with the GRABBER player and packed page stored together:
physical file size 3,762 bytes
MZ-declared file size 3,714 bytes
header 48 bytes
physical bytes after header 3,714 bytes
MZ-declared load image 3,666 bytes
physical tail beyond declaration 48 bytes
relocations 0
entry CS:IP 0008:0000
entry file offset 00B0h
stack SS:SP 0000:0080
The header fields are e_cp=8, e_cblp=0082h and e_cparhdr=3. Curiously,
the declared total is exactly the physical post-header length, as if GRABBER
computed the module size and forgot to add its 48-byte header. The last 48
physical bytes are not disposable padding: they finish the compressed
attribute plane. The DOSBox-X run proves that its loader made those bytes
available on this route. Exact historical DOS-loader compatibility was not
separately tested, so the malformed size is preserved as an observed artifact
rather than normalized away.
At the MZ entry point, runtime CS begins 128 bytes into the load image. The
first instruction jumps over strings and state to the player at runtime
offset 00F7h:
0000 jmp 00F7h
00F7 mov bx,ds
00F9 mov ax,cs
00FB mov ds,ax
00FD mov es,ax
00FF mov [0043h],bx ; retain original PSP/data segment
0103 cld
0104 call 0759h ; shrink/allocate and switch private stack
0107 call 07E7h ; uppercase command tail in the PSP
No relocation fixups are needed because the player keeps code and state
relative to CS, stores allocated segment values at runtime, and uses BIOS/DOS
services for the machine-facing operations.
The Embedded Page Header
The packed-image header starts at runtime offset 0809h, immediately after the
viewer code:
0809 19 rows = 25
080A 50 columns = 80
080B 03 BIOS mode = 3, colour text
080C 30 border/palette state
080D A0 0F expanded byte count = 4,000
080F..081B viewer state / reserved bytes = zero
081C first compressed plane
The dimensions and byte count agree exactly:
25 rows * 80 columns = 2,000 cells
2,000 cells * (one character + one attribute) = 4,000 bytes
The image is stored as two compressed 2,000-byte planes rather than as
interleaved screen words. The character plane occupies 969 bytes from runtime
081Ch through 0BE4h. A six-byte delimiter follows:
0BE5 00 00 52 47 00 00 NUL, "RG", NUL marker
0BEB attribute plane begins
The attribute plane takes the final 535 bytes and ends at physical EOF.
Exact GRABBER RLE Decoder
The common decoder begins at runtime 0629h. DL is a rotating one-bit token
selector; every eighth token fetches a new flag byte into DH. A clear flag
bit means one literal byte. A set bit means a two-byte (count,value) run:
0629 mov dx,0080h ; rotating selector, DH initially zero
062C mov bx,[080Dh] ; 0FA0h expanded interleaved size
0630 add bx,di ; terminal destination offset
0632 mov es,[003Ch] ; allocated 4,000-byte page buffer
0636 rol dl,1
0638 lodsb ; first token byte
0639 cmp dl,1
063C jne 0641h
063E mov dh,al ; one flag byte for the next eight tokens
0640 lodsb ; first data byte
0641 mov cx,1
0644 test dh,dl
0646 je 064Bh ; clear bit: AL is a literal
0648 mov cl,al ; set bit: AL is repeat count
064A lodsb ; repeated value
064B stosb
064C or bp,bp
064E je 0651h
0650 inc di ; text mode: stride two, one plane at a time
0651 loop 064Bh
0653 cmp di,bx
0655 jb 0636h
0657 mov ax,cs
0659 mov es,ax
065B ret
For text modes the caller sets BP=FFFFh, so every output byte advances DI
twice. The first invocation begins at DI=0 and fills the even character
positions. The marker scanner then locates 00 00 52 47 00 00; the second
invocation begins at DI=1 and fills the odd attribute positions.
The recovered expansion ledger is:
character plane 969 packed bytes 729 tokens 148 runs -> 2,000 bytes
attribute plane 535 packed bytes 293 tokens 205 runs -> 2,000 bytes
separator 6 bytes
combined payload 1,510 bytes -> 4,000 bytes
Hashes of the independently reconstructed data are:
6c3bd2c143ec647b2fe46d728d9ba40eeaeb9b2876246aaf912117384c115c86 character plane
ea3a8ba12d0ed838dd5f7011b48928526fa4948ee3690afcdbb0b876d6b769bb attribute plane
c9d27671fec1e758cc913a61bd0e326ee679bc23e7537ee33e0bf14cc27488ce interleaved B800 page
The page has 1,213 non-space character cells. Its 2,000 attributes use 14
values from 01h through 7Fh; none has bit 7 set, so the artwork does not
request hardware blink. Large coloured fields are ordinary text-cell
backgrounds, while the title edges use CP437 half blocks and full blocks.
Allocation, Mode Setup And Full-Page Copy
The setup at runtime 0759h disables DOS Ctrl-Break checking temporarily,
shrinks the original allocation, reserves a private stack, then allocates an
even-paragraph buffer large enough for the 4,000-byte expanded page. The
resulting screen-buffer segment is stored at [003Ch] and used as ES by the
decoder.
The display path queries the current video mode through BIOS INT 10h/AH=0Fh
and saves the mode, active page and column count. It also reads BIOS data-area
geometry and adapter state. Because the embedded header requests mode 3, the
active colour-text destination is B800:0000; monochrome mode 7 would select
B000:0000 instead.
After both planes have been expanded into their interleaved buffer, one copy publishes the entire authored screen:
03C3 mov ax,B800h
03C6 cmp word [005Eh],03B4h ; monochrome CRT controller?
03CC jne 03D1h
03CE mov ax,B000h
03D1 push es
03D2 mov es,ax
03D4 mov cx,[080Dh] ; 0FA0h bytes
03D8 shr cx,1 ; 07D0h words = 2,000 cells
03DA mov di,[0058h] ; saved display-page offset
03DE xor si,si
03E0 push ds
03E4 mov ds,[003Ch] ; expanded screen buffer
03E8 rep movsw
03EA pop ds
03EB pop es
There is no drawing loop after this copy. What looks like a large graphic is already fully authored in the decompressed cell page.
Timer Hook, Key Gate And Cleanup
GRABBER supports timed and unattended presentation, so the generic player saves interrupt vector 8 and installs a tiny tick handler. The handler only increments a counter and chains to the previous vector:
06FE inc word cs:[0047h]
0703 jmp far cs:[004Bh]
The default route polls with DOS INT 21h/AH=06h, DL=FFh while the timer
window is active. When it reaches the normal blocking gate, the player uses
INT 21h function 0Ch with subfunction 07h: flush standard input, then
read one character without echo. The scripted Enter therefore changes no
screen state; it simply releases the single page.
The exit path restores the prior video mode when necessary, resets palette and
cursor state, restores the saved interrupt-8 vector, restores the original DOS
Ctrl-Break flag and terminates through INT 21h/AH=4Ch. The observed DOSBox-X
return confirms that this cleanup path completed; no timeout or forced kill
was used.
Runtime-To-Code Concordance
| Runtime evidence | Recovered mechanism | Conclusion |
|---|---|---|
| One static 80x25 page appears and remains unchanged until Enter | Header bytes specify 25 rows, 80 columns, mode 3 and a 4,000-byte expansion | This is one colour-text page, not a multi-part graphics intro. |
| The left title and right panel use blocks, half-blocks, line characters and many cell colours | Two RLE streams reconstruct 2,000 CP437 bytes and 2,000 attribute bytes | The apparent graphic is ANSI-style cell art, not a bitmap or custom font. |
| The complete page appears at once | rep movsw copies exactly 2,000 words from the expanded buffer to B800h |
There is no incremental renderer, wipe or animation pass. |
| The frame stays silent and static | No sound path exists; the only interrupt hook increments a timer counter | The hook supports viewer timing, not music or motion. |
| One Enter returns cleanly to DOS | Function 0Ch/07h supplies the blocking key gate; mode, palette, cursor, timer vector and Ctrl-Break state are restored |
The direct run covers the complete authored route and normal exit. |
| The page identifies THG and ACiD distribution roles and bears an ANSI footer signature | Those strings are reconstructed from the executable's character plane, while the viewer identifies itself separately as GRABBER 3.60 | The board advert and art are genuine; the playback code is a generic tool, and no parent game is proven. |
The preservation result is thus narrower but firmer than the earlier catalogue
lead: THGSITE!.EXE is a real period BBStro, not an invented vector/ball demo,
and its entire visual can be recovered byte-for-byte. Its technical interest is
the compact split-plane RLE representation and the surprisingly complete
generic DOS display wrapper around one signed colour-text page.