Analysis model: gpt-5.5 xhigh
Knights Of Legend Cracktro by The Humble Guys - Technical Dissection
Knights Of Legend Cracktro is a 23 January 1990 MS-DOS cracktro / loader by
The Humble Guys. Demozoo lists it as a The Humble Guys MS-DOS cracktro released
on 23 January 1990, with the release-date source noted as artscene.fix.no. The
Scene.org archive is demos/compilations/lost_found_and_more/cracktro/knights_of_legend_cracktro.zip.
Release year: 1990.
Sources:
- Demozoo production page: https://demozoo.org/productions/138998/
- Demozoo The Humble Guys group page: https://demozoo.org/groups/7421/
- Scene.org file info: https://files.scene.org/view/demos/compilations/lost_found_and_more/cracktro/knights_of_legend_cracktro.zip
- Scene.org archive: https://files.scene.org/get/demos/compilations/lost_found_and_more/cracktro/knights_of_legend_cracktro.zip
This is the same visual family as the later THG Bubble Bobble Cracktro: a
static text-mode colour-bar card, not an animated demo. Technically, though, it
is different. Bubble Bobble is a flat COM with an XOR stub and a rough DOS
EXEC handoff. Knights Of Legend is a real MZ executable with a 512-byte
header, one relocation, plain unencrypted code, a data segment placed before the
entry code, and a post-key far return to PSP:0000.
The preserved file contains an unused Start.exe string, but it contains no
reachable DOS EXEC path. The visible program draws the card, waits for a key,
then exits.
Visual References
| Time | Image | Notes |
|---|---|---|
00:00.000 |
![]() |
Public Demozoo still of the rendered text-mode colour-bar screen. The program reaches this static state immediately, then waits for a key. |
Generated execution map:

No local DOSBox timing capture was needed for this pass. The display has one
visible state, so the 00:00.000 marker means "after the BIOS text draw stream
has completed", not a measured animated timestamp.
Archive Shape
The examined Scene.org ZIP is 943 bytes:
thg-kol.exe 3463 bytes 1989-12-21 21:19
SHA-256:
bf7639ad6820b18fe32c39ef136c80440b7fe170c5e3a462339965168ee88222 knights_of_legend_cracktro.zip
a53291024cc1dc397d73ebe9780301f2a782f7bb74965f08ab53c5e8b3daf168 thg-kol.exe
There are no sidecar files in this package. The internal file timestamp is 21 December 1989, while Demozoo records a 23 January 1990 release date. I keep the release year as 1990 because that is the public production metadata, but the binary was likely built earlier.
MZ Header
The first 32 bytes:
4D 5A 87 01 07 00 01 00 20 00 00 00 FF FF 00 00
8C 00 81 B3 00 00 17 00 1E 00 00 00 01 00 05 00
Important fields:
last page bytes 0187h
page count 0007h
computed file size 0D87h
relocation records 0001h
header paragraphs 0020h = 512 bytes
minalloc 0000h
maxalloc FFFFh
initial SS:SP 0000h:008Ch
initial CS:IP 0017h:0000h
relocation table 001Eh
overlay number 0000h
The computed MZ size exactly matches the physical file:
(pages - 1) * 512 + last_page = 6 * 512 + 0187h = 0D87h
load image size = 0D87h - 0200h = 0B87h
entry load offset = CS * 16 + IP = 0170h
entry file offset = 0200h + 0170h = 0370h
The single relocation record is:
offset 0005h, segment 0017h
That points at the immediate word in the entry instruction mov ax,0009h.
After DOS relocation, it becomes mov ax,load_segment+0009h, which is then
loaded into DS.
Load-Image Layout
Offsets below are load-image offsets, where 0000h is the first byte after the
512-byte MZ header:
0000-008B repeated "HUMBLE!" filler
0090-0169 strings and dead filename/final-message data
0170-0B86 entry and generated text-mode renderer
The interesting detail is that the strings are before the entry code, not after
it. DOS relocates the entry's mov ax,0009h, and the code sets:
DS = load_segment + 0009h
That makes DS:0000h point at load offset 0090h, the start of the string
pool.
The string pool:
DS:0000 "The Humble Guys!", "$"
DS:0011 "Present", "$"
DS:0019 "Knights of Legend!", "$"
DS:002C "Seems to be Unprotected!", "$"
DS:0045 members line, "$"
DS:0093 "Press any Key to Load!", "$"
DS:00AA "Start.exe", 00
DS:00B4 final thank-you string, "$"
Start.exe and the final string are never reached by the preserved code path.
Entry And Relocated DS Setup
The entry starts at load offset 0170h:
0170 1e push ds
0171 2b c0 sub ax,ax
0173 50 push ax
0174 b8 09 00 mov ax,0009h ; relocated by DOS
0177 8e d8 mov ds,ax
There are two jobs here.
First, push ds and push 0000h build a far-return frame. At DOS EXE entry,
DS normally points at the PSP. The final LRET pops IP=0000h and
CS=original DS, so it returns to PSP:0000h. The PSP starts with INT 20h,
so this is an old DOS exit idiom.
Second, the relocated mov ax,0009h sets up the data segment. With DS equal
to load_segment+0009h, all later DOS string offsets are short offsets into
the string pool.
No stack frame, heap, interrupt hook, or display probe is initialized.
Mode Setup
The mode setup is inline:
0179 b4 00 mov ah,00h
017b b0 03 mov al,03h
017d cd 10 int 10h
Mode 3 gives an 80x25 colour text page. The public frame is a 635x397 JPEG capture of a screen that is logically 80 columns by 25 rows.
Cursor And Block-Write Template
Unlike Bubble Bobble, this MZ version does not factor cursor positioning into
a subroutine. Every draw command inlines both BIOS calls.
A typical span:
017f b6 00 mov dh,00h ; row
0181 b2 00 mov dl,00h ; column
0183 b4 02 mov ah,02h
0185 b7 00 mov bh,00h
0187 cd 10 int 10h ; set cursor
0189 b0 dc mov al,0dch ; CP437 lower half block
018b b3 0a mov bl,0ah ; bright green foreground
018d b9 50 00 mov cx,0050h ; 80 cells
0190 b4 09 mov ah,09h
0192 b7 00 mov bh,00h
0194 cd 10 int 10h ; write repeated char/attribute
The renderer emits 107 BIOS AH=09h repeated-cell writes before the key wait.
The repeated-cell contract is the same as in Bubble Bobble:
current cursor = row/column selected by AH=02h
AL = CP437 character
BL = text attribute
BH = display page, always zero
CX = repeat count
INT 10h AH=09h writes CX cells at that cursor position
The important glyphs:
0DCh lower half block
0DAh top-left box corner
0BFh top-right box corner
0C0h bottom-left box corner
0D9h bottom-right box corner
0C4h horizontal line
0B3h vertical line
0DCh is why the image looks like scanline colour bars. In text mode the glyph
fills only the lower half of the character cell, while the attribute supplies
the foreground colour. The black background remains visible in the upper half.
Recovered Draw Counts
A small emulator for INT 10h/AH=00h, AH=02h, AH=09h, INT 21h/AH=09h,
and INT 16h/AH=00h gives:
mode set calls 1
cursor-position calls 108
BIOS block writes 107
DOS string writes 6
keyboard waits 1
far returns 1
The six DOS string writes:
063A row 04 col 32 DS:0000 The Humble Guys!
064B row 06 col 36 DS:0011 Present
065C row 08 col 31 DS:0019 Knights of Legend!
0850 row 14 col 28 DS:002C Seems to be Unprotected!
09A3 row 18 col 01 DS:0045 members line
0B80 row 22 col 29 DS:0093 Press any Key to Load!
The members line is the same long THG member string used in the later
Bubble Bobble card. It fills the wide box interior from column 1 through
column 77.
Screen Geometry
The authored screen layout:
row 00 full-width DCh colour bar
row 01 full-width DCh colour bar
row 02 bars plus top of title box, columns 20..59
row 03 bars plus title-box side walls
row 04 title string inside title box
row 05 blank row inside title box
row 06 "Present" string inside title box
row 07 blank row inside title box
row 08 game title string inside title box
row 09 blank row inside title box
row 10 bottom of title box
row 11 middle colour bar with a 40-cell brown middle span
row 12 full-width DCh bar
row 13 top of credit box, columns 24..56
row 14 credit string inside credit box
row 15 bottom of credit box
row 16 full-width DCh bar
row 17 top of members box
row 18 members string inside members box
row 19 bottom of members box
row 20 full-width DCh bar with a wide blue middle span
row 21 top of key-prompt box, columns 27..52
row 22 key prompt inside key-prompt box
row 23 bottom of key-prompt box
row 24 final colour bar
The geometry is almost the same as Bubble Bobble. The main differences are
the title string column (Knights of Legend! starts at column 31) and the
credit-box text (Seems to be Unprotected! starts at column 28).
Key Wait And Exit
The final visible command writes the key prompt, then the program waits:
0b7b b4 09 mov ah,09h
0b7d ba 93 00 mov dx,0093h
0b80 cd 21 int 21h
0b82 b4 00 mov ah,00h
0b84 cd 16 int 16h
0b86 cb retf
There is no timer loop during the wait. After the key, RETF consumes the
far-return frame from startup:
IP <- 0000h
CS <- original DOS entry DS, normally the PSP segment
The result is a return to PSP:0000h, where DOS placed the INT 20h exit
instruction. This is the only actual post-key behaviour in the preserved file.
Dead Handoff Data
The data segment contains:
DS:00AA "Start.exe",00
DS:00B4 final thank-you string
But the loaded image has no reachable code after the RETF. It also contains
no INT 21h/AH=4Bh DOS EXEC call, no file open/read path, and no branch that
targets these strings.
That means Start.exe is either a leftover from a fuller template or a hint at
an expected external batch/executable chain not present in this preserved
archive. It is not executed by thg-kol.exe as archived.
Comparison With Bubble Bobble
The visible template is shared:
80x25 mode-3 text page
CP437 DCh colour-bar rows
CP437 box drawing
six DOS AH=09h strings
one BIOS key wait
same THG member line
The implementation differs:
Knights Of Legend:
MZ executable
512-byte header
one relocation
strings before code
inline cursor calls
no XOR decode
final RETF to PSP:0000
no live EXEC handoff
Bubble Bobble:
flat COM executable
15-byte XOR 45h decoder
strings after code
cursor helper subroutine
post-key memory resize/allocation
attempted EXEC of Bubble.mcf
This makes Knights Of Legend the cleaner display-card specimen. It is almost
all generated BIOS text output wrapped in a minimal MZ shell.
What The Code Does, Condensed
- DOS loads the MZ image after a 512-byte header.
- DOS applies one relocation to the entry's
mov ax,0009h. - The entry builds a far-return exit frame to
PSP:0000h. - The entry sets
DSto the string segment at load offset0090h. - It sets BIOS video mode 3.
- It emits 107 BIOS repeated-cell writes for the colour bars and boxes.
- It emits six DOS
$-string writes for the title, credit, member line, and key prompt. - It waits for one key via
INT 16h/AH=00h. - It exits by
RETFtoPSP:0000h.
The important negative result: despite the embedded Start.exe string, this
publicly preserved executable does not load the game. The cracktro is a static
THG text-mode announcement card and exit stub.
