HeroQuest EXE File

From ModdingWiki
Jump to navigation Jump to search

The original exe is compressed with EXEPACKER, you must decompress with UNP to manipulate it.

HeroQuest EXE File
Format typeExecutable / Script
TypeCompiled
PlatformMS-DOS
Code16-bit x86
Hidden data?No
Games Memory information:
Code segment = 01EF
Data segment = 0B6B
Stack segment = 25F2

[CODE SEGMENT] Main Routines

These are the main routines of the game, disassembled with DOSBOX debugger and annotated.

in-game main loop

01EF:0413  E8E65F              call 000063FC ($+5fe6)					<---- ???
01EF:0416  E8FA5F              call 00006413 ($+5ffa)					<---- Checks left mouse button and everityng under it
01EF:0419  C606CC40FF          mov  byte [40CC],FF         ds:[40CC]=DFFF   
01EF:041E  F606923920          test byte [3992],20         ds:[3992]=9200		<---- Checks if right mouse button has been pressed
01EF:0423  7403                je   00000428 ($+3)         (no jmp)
01EF:0425  E82E03              call 00000756 ($+32e)  					<---- ends the turn if right mouse button pressed
01EF:0428  E85963              call 00006784 ($+6359) 					<---- ???
01EF:042B  E8A202              call 000006D0 ($+2a2)  					<---- ???
01EF:042E  E8E564              call 00006916 ($+64e5) 					<---- draws in the correct order heroes and forniture
01EF:0431  E84553              call 00005779 ($+5345) 					<---- same as above?
01EF:0434  E8DD53              call 00005814 ($+53dd) 					<---- ???
01EF:043A  E87B53              call 000057B8 ($+537b) 					<---- draws heroes, monsters, forniture and doors (not the walls)
01EF:043D  E8B454              call 000058F4 ($+54b4) 					<---- Checks if orthogonal tiles are walkable and updates the directional arrows
01EF:0440  E8A156              call 00005AE4 ($+56a1) 					<---- Checks if monsters are present in the room and updates search icons
01EF:0443  E81E60              call 00006464 ($+601e) 					<---- activates attack, magic, treasure, traps icons
01EF:0446  E8CF60              call 00006518 ($+60cf) 					<---- draws yellow figures on top left
01EF:0449  E8C859              call 00005E14 ($+59c8)					<---- draws glove mouse pointer
01EF:044C  803E9A3F00          cmp  byte [3F9A],00         ds:[3F9A]=0000   
01EF:0451  7503                jne  00000456 ($+3)         (down)           
01EF:0453  E88E5C              call 000060E4 ($+5c8e)					<---- ???
01EF:0456  E87E59              call 00005DD7 ($+597e)					<---- Clean the previous mouse sprite
01EF:0459  E85954              call 000058B5 ($+5459)					<---- Clean the previous hero sprite
01EF:045C  E82100              call 00000480 ($+21)					<---- Quest event checks
01EF:045F  E8EC13              call 0000184E ($+13ec)					<---- Checks if the hero stands on a stair tile
01EF:0462  803E973F00          cmp  byte [3F97],00         ds:[3F97]=0000   
01EF:0467  7403                je   0000046C ($+3)         (no jmp)         
01EF:0469  E8BA00              call 00000526 ($+ba)        				<---- End turn wrap up (resets registers and variables)
01EF:046C  803E9A3F00          cmp  byte [3F9A],00         ds:[3F9A]=0000	
01EF:0471  7401                je   00000474 ($+1)         (no jmp)	
01EF:0473  C3                  ret						
01EF:0474  803E923940          cmp  byte [3992],40         ds:[3992]=9200
01EF:0479  7503                jne  0000047E ($+3)         (down)
01EF:047B  E94FFE              jmp  000002CD ($-1b1)       (up)
01EF:047E  EB93                jmp  short 00000413 ($-6d)  (up)				<--- goes back on top


Shooting routine

Shooting routine (magic and throwing weapons) is utterly broken in this game.
The code checks the map tile the projectile is above and determine if the line of sight is blocked or free.
The way the map is coded resulted in a convoluted code that fails to check LOS.
You can shoot past walls and always hit the target if the hero stands in contact with one wall and the target is the adjacent room exactly above or exactly to the right.
You can also hit the target standing in the perfect diagonal like bishop's movement, and this could happen even if there are no active rooms (solid rock, but marked with 00 like rooms' inner tiles) in between.
LOS is blocked by parallel unrevealed secret doors and opened doors.


Weapon check:

01EF:0AB2  32C0                xor  al,al
01EF:0AB4  F6451110            test byte [di+11],10        ds:[46A8]=0010	<-- di+11 is equipped weapon. checks if it is crossbow?
01EF:0AB8  7501                jne  00000ABB ($+1)         (no jmp)
01EF:0ABA  C3                  ret
01EF:0ABB  B0FD                mov  al,FD					<-- not crossbow
01EF:0ABD  C3                  ret
01EF:0ABE  807D1101            cmp  byte [di+11],01        ds:[B1A7]=0000	<-- starts here
01EF:0ABF  7D11                jge  00000AD2 ($+11)        (down)		<-- jump if greater or equal
01EF:0AC1  0174EE              add  [si-12],si             ds:[4DBA]=260D
01EF:0AC4  807D1102            cmp  byte [di+11],02        ds:[46A8]=0010	<-- F64511/807D11 are the test/cmp of the equipped weapon
01EF:0AC8  74E8                je   00000AB2 ($-18)        (up)
01EF:0ACA  807D1140            cmp  byte [di+11],40        ds:[46A8]=0010
01EF:0ACE  74E2                je   00000AB2 ($-1e)        (up)
01EF:0AD0  B0FC                mov  al,FC
01EF:0AD2  EBE0                jmp  short 00000AB4 ($-20)  (up)
01EF:0AD4  F6451110            test byte [di+11],10        ds:[46A8]=0010	<-- crossbow
01EF:0AD8  750F                jne  00000AE9 ($+f)         (no jmp)
01EF:0ADA  F6451120            test byte [di+11],20        ds:[46A8]=0010	<-- throwing axe
01EF:0ADE  7509                jne  00000AE9 ($+9)         (no jmp)
01EF:0AE0  F6451140            test byte [di+11],40        ds:[46A8]=0010	<-- spear
01EF:0AE4  7503                jne  00000AE9 ($+3)         (no jmp)
01EF:0AE6  B0FC                mov  al,FC
01EF:0AE8  C3                  ret

SHOOTING ROUTINE STARTS HERE:

01EF:0AE9  C606B73F01          mov  byte [3FB7],01         ds:[3FB7]=0301
01EF:0AEE  E82B00              call 00000B1C ($+2b)
01EF:0AF1  32C0                xor  al,al
01EF:0AF3  803EA83F01          cmp  byte [3FA8],01         ds:[3FA8]=0001	<-- check if LOS is blocked (1)
01EF:0AF8  7401                je   00000AFB ($+1)         (down)
01EF:0AFA  C3                  ret
01EF:0AFB  B0FE                mov  al,FE
01EF:0AFD  C606B73F00          mov  byte [3FB7],00         ds:[3FB7]=0300
01EF:0B02  C3                  ret

01EF:0B1C  E81F06              call 0000113E ($+61f)
01EF:0B1F  A0A83F              mov  al,[3FA8]              ds:[3FA8]=0001
01EF:0B22  3401                xor  al,01
01EF:0B24  A2B23F              mov  [3FB2],al              ds:[3FB2]=0000
01EF:0B27  C3                  ret

Set global variables (shooter and target position/distance):

01EF:113E  8B36D43F            mov  si,[3FD4]              ds:[3FD4]=4DC2
01EF:1142  8A7C01              mov  bh,[si+01]             ds:[4DC3]=0F0A	<-- Target X 
01EF:1145  8A5C02              mov  bl,[si+02]             ds:[4DC4]=270F	<-- Target Y
01EF:1148  8BCB                mov  cx,bx
01EF:114A  8B3E3746            mov  di,[4637]              ds:[4637]=4697
01EF:114E  8A7501              mov  dh,[di+01]             ds:[4698]=120A	<-- Hero X 
01EF:1151  8A5502              mov  dl,[di+02]             ds:[4699]=1212	<-- Hero Y 
01EF:1154  8836A53F            mov  [3FA5],dh              ds:[3FA5]=0C0C	<-- Hero X saved at 3FA5
01EF:1158  8816A63F            mov  [3FA6],dl              ds:[3FA6]=020C	<-- Hero Y saved at 3FA6
01EF:115C  C6069F3F00          mov  byte [3F9F],00         ds:[3F9F]=0000	<-- reset projectile temp distance (area used for math)
01EF:1161  C606A83F00          mov  byte [3FA8],00         ds:[3FA8]=0002	<-- reset LOS 0=free, 1=blocked
01EF:1166  B7FF                mov  bh,FF
01EF:1168  8AC6                mov  al,dh
01EF:116A  2AC5                sub  al,ch
01EF:116C  7504                jne  00001172 ($+4)         (down)
01EF:116E  B700                mov  bh,00					<-- target is on the RIGHT (>)
01EF:1170  EB06                jmp  short 00001178 ($+6)   (down)
01EF:1172  7304                jnc  00001178 ($+4)         (down)
01EF:1174  F6D8                neg  al
01EF:1176  B701                mov  bh,01					<-- target is on the LEFT (<)
01EF:1178  A2A13F              mov  [3FA1],al              ds:[3FA1]=0301	<-- horizontal distance shooter-target saved at 3FA1
01EF:117B  8AE8                mov  ch,al
01EF:117D  B3FF                mov  bl,FF
01EF:117F  8AC2                mov  al,dl
01EF:1181  2AC1                sub  al,cl
01EF:1183  7504                jne  00001189 ($+4)         (down)
01EF:1185  B300                mov  bl,00					<-- target is UNDER (v)
01EF:1187  EB06                jmp  short 0000118F ($+6)   (down)
01EF:1189  7304                jnc  0000118F ($+4)         (down)
01EF:118B  F6D8                neg  al
01EF:118D  B301                mov  bl,01					<-- target is ABOVE (^)
01EF:118F  A2A23F              mov  [3FA2],al              ds:[3FA2]=0003	<-- vertical distance shooter-target saved at 3FA2
01EF:1192  3AC5                cmp  al,ch
01EF:1194  7240                jc   000011D6 ($+40)        (no jmp)

bx (bh+bl) registry status based on target/shooter position:

0101 0001 FF01
0100 TRGT FF00
01FF 00FF FFFF


VERTICAL shooting routine:

01EF:1196  8ACD                mov  cl,ch
01EF:1198  8AE8                mov  ch,al
01EF:119A  8AD0                mov  dl,al
01EF:119C  000E9F3F            add  [3F9F],cl              ds:[3F9F]=0000	<-- update projectile travelled distance
01EF:11A0  38169F3F            cmp  [3F9F],dl              ds:[3F9F]=0000
01EF:11A4  7208                jc   000011AE ($+8)         (no jmp)
01EF:11A6  28169F3F            sub  [3F9F],dl              ds:[3F9F]=0000
01EF:11AA  003EA53F            add  [3FA5],bh              ds:[3FA5]=0F0D	<-- Temp Projectile X (d 0:F655)
01EF:11AE  001EA63F            add  [3FA6],bl              ds:[3FA6]=020F	<-- Temp Projectile Y (d 0:F656)
01EF:11B2  C706E9370000        mov  word [37E9],0000       ds:[37E9]=D238	<-- set Vertical flag
01EF:11B8  882EEB37            mov  [37EB],ch              ds:[37EB]=F1E0	<-- distance between projectile and target
01EF:11BC  80FD01              cmp  ch,01
01EF:11BF  7505                jne  000011C6 ($+5)         (down)
01EF:11C1  80FBFF              cmp  bl,FF
01EF:11C4  7403                je   000011C9 ($+3)         (no jmp)
01EF:11C6  E84B00              call 00001214 ($+4b)
01EF:11C9  803EA83F00          cmp  byte [3FA8],00         ds:[3FA8]=0000	<-- check if LOS is still free (0), if 1 exits
01EF:11CE  7401                je   000011D1 ($+1)         (no jmp)
01EF:11D0  C3                  ret
01EF:11D1  FECD                dec  ch
01EF:11D3  75C7                jne  0000119C ($-39)        (up)
01EF:11D5  C3                  ret

HORIZONTAL shooting routine:

01EF:11D6  8AD0                mov  dl,al				
01EF:11D8  8ACD                mov  cl,ch		<-- it moves ch in cl
01EF:11DA  32ED                xor  ch,ch		<-- and puts to 00 ch because uses loop (thus cx) instead of dec ch of vertical routine
01EF:11DC  00169F3F            add  [3F9F],dl              ds:[3F9F]=0001
01EF:11E0  380E9F3F            cmp  [3F9F],cl              ds:[3F9F]=0001
01EF:11E4  7208                jc   000011EE ($+8)         (no jmp)
01EF:11E6  280E9F3F            sub  [3F9F],cl              ds:[3F9F]=0001
01EF:11EA  001EA63F            add  [3FA6],bl              ds:[3FA6]=020F	<-- Temp Projectile Y
01EF:11EE  003EA53F            add  [3FA5],bh              ds:[3FA5]=0F03	<-- Temp Projectile X
01EF:11F2  C706E9370100        mov  word [37E9],0001       ds:[37E9]=0001	<-- set Horizontal flag
01EF:11F8  880EEB37            mov  [37EB],cl              ds:[37EB]=AA04	<-- distance between projectile and target
01EF:11FC  80F901              cmp  cl,01
01EF:11FF  7505                jne  00001206 ($+5)         (down)
01EF:1201  80FFFF              cmp  bh,FF
01EF:1204  7403                je   00001209 ($+3)         (no jmp)
01EF:1206  E80B00              call 00001214 ($+b)
01EF:1209  803EA83F00          cmp  byte [3FA8],00         ds:[3FA8]=0001	<-- check if LOS is still free (0), if 1 exits
01EF:120E  7401                je   00001211 ($+1)         (no jmp)
01EF:1210  C3                  ret
01EF:1211  E2C9                loop 000011DC ($-37)
01EF:1213  C3                  ret

Collision check routine on current tile IN WALL/DOORS map (ds:566F):

01EF:1214  53                  push bx
01EF:1215  52                  push dx
01EF:1216  8A36A63F            mov  dh,[3FA6]              ds:[3FA6]=0839
01EF:121A  8A16A53F            mov  dl,[3FA5]              ds:[3FA5]=3936
01EF:121E  E85D4E              call 0000607E ($+4e5d)
01EF:1221  80BF6F5600          cmp  byte [bx+566F],00      ds:[576C]=8128	<-- Check if tile is 00, if true jumps to the Object map check
01EF:1226  742A                je   00001252 ($+2a)        (no jmp)			at 0B6B:566F is where WALLS/DOORS map is stored
01EF:1228  8A876F56            mov  al,[bx+566F]           ds:[576C]=8128	<-- mov into al the current TILE (28=is north secret door)
01EF:122C  833EE93701          cmp  word [37E9],0001       ds:[37E9]=0001	<-- 1=H, 0=V check for opened door subroutines
01EF:1231  7411                je   00001244 ($+11)        (no jmp)

Vertical shoot subroutine that checks for Horizontal walls/doors:

01EF:1233  24AC                and  al,AC 					<-- binary AND check if Horizontal walls/doors are present (block LOS)
01EF:1235  0AC0                or   al,al					AC= 10101100
01EF:1237  7419                je   00001252 ($+19)        (no jmp)
01EF:1239  A820                test al,20					<-- if door is Horizontal
01EF:123B  7442                je   0000127F ($+42)        (down)
01EF:123D  A804                test al,04					<-- if door is opened
01EF:123F  743E                je   0000127F ($+3e)        (down)
01EF:1241  EB0F                jmp  short 00001252 ($+f)   (down)
01EF:1243  90                  nop

Horizontal shoot subroutine that checks for Vertical walls/doors:

01EF:1244  245C                and  al,5C 					<-- binary AND check if Horizontal walls/doors are present (block LOS)
01EF:1246  0AC0                or   al,al					5C= 01011100
01EF:1248  7408                je   00001252 ($+8)         (down)
01EF:124A  A810                test al,10					<-- if door is Vertical
01EF:124C  7431                je   0000127F ($+31)        (down)
01EF:124E  A804                test al,04					<-- if door is opened
01EF:1250  742D                je   0000127F ($+2d)        (down)

Collision check routine on current tile IN OBJECTS map (ds:586F):

01EF:1252  803EEB3701          cmp  byte [37EB],01         ds:[37EB]=6E03	<-- checks if the projectile is about to hit the target
01EF:1257  742B                je   00001284 ($+2b)        (down)
01EF:1259  80BF6F5800          cmp  byte [bx+586F],00      ds:[1576F]=3637	<-- checks if the tile is passable (00)
01EF:125E  740E                je   0000126E ($+e)         (down)
01EF:1260  8A876F58            mov  al,[bx+586F]           ds:[1576F]=3637	<-- ds:586F is where OBJECTS map is stored
01EF:1264  BB4649              mov  bx,4946					<-- ds:4946 check 
01EF:1267  D7                  xlat
01EF:1268  A2A83F              mov  [3FA8],al              ds:[3FA8]=0000
01EF:126B  EB17                jmp  short 00001284 ($+17)  (down)
01EF:126D  90                  nop
01EF:126E  8A36A63F            mov  dh,[3FA6]              ds:[3FA6]=004D
01EF:1272  8A16A53F            mov  dl,[3FA5]              ds:[3FA5]=4D4D
01EF:1276  E80E00              call 00001287 ($+e)
01EF:1279  A2A83F              mov  [3FA8],al              ds:[3FA8]=0000
01EF:127C  EB06                jmp  short 00001284 ($+6)   (down)
01EF:127E  90                  nop
01EF:127F  C606A83F01          mov  byte [3FA8],01         ds:[3FA8]=BA6B	<-- sets LOS as blocked (1) and exits
01EF:1284  5A                  pop  dx
01EF:1285  5B                  pop  bx
01EF:1286  C3                  ret

Updates with random numbers the first three bytes of heroes' equipment every movement (presumably used as seed for RNG):

01EF:1287  51                  push cx
01EF:1288  57                  push di
01EF:1289  B90500              mov  cx,0005
01EF:128C  BF6346              mov  di,4663	<-- first byte of Barbarian equipment in memory
01EF:128F  33C0                xor  ax,ax
01EF:1291  803D00              cmp  byte [di],00           ds:[6CAA]=0000
01EF:1294  740C                je   000012A2 ($+c)         (down)
01EF:1296  385501              cmp  [di+01],dl             ds:[6CAB]=0000
01EF:1299  7507                jne  000012A2 ($+7)         (no jmp)
01EF:129B  387502              cmp  [di+02],dh             ds:[6CAC]=0000
01EF:129E  7502                jne  000012A2 ($+2)         (no jmp)
01EF:12A0  B001                mov  al,01
01EF:12A2  83C71A              add  di,001A	<-- jumps to the following hero's equipment
01EF:12A5  E2EA                loop 00001291 ($-16)
01EF:12A7  5F                  pop  di
01EF:12A8  59                  pop  cx
01EF:12A9  C3                  ret

TBD

01EF:607E  8ADE                mov  bl,dh
01EF:6080  B700                mov  bh,00
01EF:6082  03DB                add  bx,bx
01EF:6084  81C3C55A            add  bx,5AC5					<-- ds:5AC5 check 
01EF:6088  8B07                mov  ax,[bx]                ds:[FF00]=3737
01EF:608A  B600                mov  dh,00
01EF:608C  03D0                add  dx,ax
01EF:608E  8BDA                mov  bx,dx
01EF:6090  C3                  ret

Monster attack routine

This first block defines the target priority: barbarian - dwarf - elf - wizard - ragnar
It is possible to revers it forcing the monster to chose the weaker hero first reversing the logic by starting from ragnar profile and then jump backward subtracting 1A.
See Heroes' default profiles for reference.

01EF:2257  BE6346              mov  si,4663					<-- starting profile offset 4663=barbarian
01EF:225A  B90500              mov  cx,0005					<-- loop repeats 5 times 
01EF:225D  51                  push cx
01EF:225E  8936D63F            mov  [3FD6],si              ds:[3FD6]=46B1
01EF:2262  8A4419              mov  al,[si+19]             ds:[46CA]=0003	<-- jumps to hero's ID position
01EF:2265  A2BC3F              mov  [3FBC],al              ds:[3FBC]=0003
01EF:2268  E85800              call 000022C3 ($+58)
01EF:226B  59                  pop  cx
01EF:226C  8B36D63F            mov  si,[3FD6]              ds:[3FD6]=46B1
01EF:2270  83C61A              add  si,001A					<-- jumps to the next profile
01EF:2273  803EA83F00          cmp  byte [3FA8],00         ds:[3FA8]=0102
01EF:2278  7503                jne  0000227D ($+3)         (down)
01EF:227A  E95102              jmp  000024CE ($+251)       (down)
01EF:227D  803EA83F03          cmp  byte [3FA8],03         ds:[3FA8]=0102
01EF:2282  7503                jne  00002287 ($+3)         (down)
01EF:2284  E94702              jmp  000024CE ($+247)       (down)
01EF:2287  E2D4                loop 0000225D ($-2c)
01EF:2289  C3                  ret


01EF:22C3  C606A83F00          mov  byte [3FA8],00         ds:[3FA8]=0000
01EF:22C8  803C00              cmp  byte [si],00           ds:[4663]=06FF
01EF:22CB  7503                jne  000022D0 ($+3)         (no jmp)
01EF:22CD  E98101              jmp  00002451 ($+181)       (down)
01EF:22D0  8A4403              mov  al,[si+03]             ds:[4666]=C726	<-- hero's room
01EF:22D3  3A4503              cmp  al,[di+03]             ds:[4DBB]=FB26	<-- monster's room
01EF:22D6  7403                je   000022DB ($+3)         (down)
01EF:22D8  E97601              jmp  00002451 ($+176)       (down)
01EF:22DB  F6441801            test byte [si+18],01        ds:[467B]=0000
01EF:22DF  7403                je   000022E4 ($+3)         (down)
01EF:22E1  E96D01              jmp  00002451 ($+16d)       (down)
01EF:22E4  8B5401              mov  dx,[si+01]             ds:[4664]=0D06
01EF:22E7  52                  push dx
01EF:22E8  57                  push di
01EF:22E9  E864F7              call 00001A50 ($-89c)
01EF:22EC  5F                  pop  di
01EF:22ED  57                  push di
01EF:22EE  E84E02              call 0000253F ($+24e)
01EF:22F1  E8F03D              call 000060E4 ($+3df0)
01EF:22F4  B9F401              mov  cx,01F4
01EF:22F7  E88D23              call 00004687 ($+238d)
01EF:22FA  5F                  pop  di
01EF:22FB  5A                  pop  dx
01EF:22FC  8816A53F            mov  [3FA5],dl              ds:[3FA5]=1106
01EF:2300  8836A63F            mov  [3FA6],dh              ds:[3FA6]=0411
01EF:2304  BBA240              mov  bx,40A2
01EF:2307  891ECA40            mov  [40CA],bx              ds:[40CA]=40A2
01EF:230B  E8703D              call 0000607E ($+3d70)			<-- 	if jumped the monster doesn't attack when in contact

01EF:230E  81C36F54            add  bx,546F
01EF:2312  8A07                mov  al,[bx]                ds:[3F28]=4040		
01EF:2314  243F                and  al,3F				
01EF:2316  3A4503              cmp  al,[di+03]             ds:[4DBB]=FB26	<-- monster's room check. if removed the monster attack through walls and doors
01EF:2319  7403                je   0000231E ($+3)         (down)
01EF:231B  E93301              jmp  00002451 ($+133)       (down)
01EF:231E  B501                mov  ch,01
01EF:2320  A0A53F              mov  al,[3FA5]              ds:[3FA5]=1106
01EF:2323  2A4501              sub  al,[di+01]             ds:[4DB9]=0F06
01EF:2326  7504                jne  0000232C ($+4)         (no jmp)
01EF:2328  B500                mov  ch,00
01EF:232A  EB08                jmp  short 00002334 ($+8)   (down)
01EF:232C  3C80                cmp  al,80
01EF:232E  7204                jc   00002334 ($+4)         (no jmp)
01EF:2330  F6D8                neg  al
01EF:2332  B5FF                mov  ch,FF
01EF:2334  A2A13F              mov  [3FA1],al              ds:[3FA1]=0100
01EF:2337  882EA33F            mov  [3FA3],ch              ds:[3FA3]=0100
01EF:233B  B501                mov  ch,01
01EF:233D  A0A63F              mov  al,[3FA6]              ds:[3FA6]=0411
01EF:2340  2A4502              sub  al,[di+02]             ds:[4DBA]=260F
01EF:2343  7504                jne  00002349 ($+4)         (no jmp)
01EF:2345  B500                mov  ch,00
01EF:2347  EB08                jmp  short 00002351 ($+8)   (down)
01EF:2349  3C80                cmp  al,80
01EF:234B  7204                jc   00002351 ($+4)         (no jmp)
01EF:234D  F6D8                neg  al
01EF:234F  B5FF                mov  ch,FF
01EF:2351  A2A23F              mov  [3FA2],al              ds:[3FA2]=0001
01EF:2354  882EA43F            mov  [3FA4],ch              ds:[3FA4]=0601
01EF:2358  8B5501              mov  dx,[di+01]             ds:[4DB9]=0F06
01EF:235B  89169F3F            mov  [3F9F],dx              ds:[3F9F]=1006
01EF:235F  C606A93F00          mov  byte [3FA9],00         ds:[3FA9]=0000
01EF:2364  8A5D09              mov  bl,[di+09]             ds:[4DC1]=8100
01EF:2367  02DB                add  bl,bl
01EF:2369  02DB                add  bl,bl
01EF:236B  025D09              add  bl,[di+09]             ds:[4DC1]=8100
01EF:236E  32FF                xor  bh,bh
01EF:2370  8A870648            mov  al,[bx+4806]           [illegal]
01EF:2374  A29C3F              mov  [3F9C],al              ds:[3F9C]=0003
01EF:2377  8A0EA23F            mov  cl,[3FA2]              ds:[3FA2]=0001
01EF:237B  A0A13F              mov  al,[3FA1]              ds:[3FA1]=0100
01EF:237E  3AC1                cmp  al,cl
01EF:2380  7203                jc   00002385 ($+3)         (no jmp)
01EF:2382  EB6A                jmp  short 000023EE ($+6a)  (down)
01EF:2384  90                  nop
01EF:2385  8B169F3F            mov  dx,[3F9F]              ds:[3F9F]=1006
01EF:2389  3836A63F            cmp  [3FA6],dh              ds:[3FA6]=0411
01EF:238D  7425                je   000023B4 ($+25)        (down)
01EF:238F  A0A43F              mov  al,[3FA4]              ds:[3FA4]=0601
01EF:2392  0AC0                or   al,al
01EF:2394  741E                je   000023B4 ($+1e)        (down)
01EF:2396  02F0                add  dh,al
01EF:2398  E8DD00              call 00002478 ($+dd)
01EF:239B  3CFF                cmp  al,FF
01EF:239D  7503                jne  000023A2 ($+3)         (no jmp)
01EF:239F  E9B500              jmp  00002457 ($+b5)        (down)
01EF:23A2  0AC0                or   al,al
01EF:23A4  750E                jne  000023B4 ($+e)         (no jmp)
01EF:23A6  8A26A43F            mov  ah,[3FA4]              ds:[3FA4]=0601
01EF:23AA  E8B000              call 0000245D ($+b0)
01EF:23AD  7303                jnc  000023B2 ($+3)         (down)
01EF:23AF  E99900              jmp  0000244B ($+99)        (down)
01EF:23B2  EBD1                jmp  short 00002385 ($-2f)  (up)
01EF:23B4  8B169F3F            mov  dx,[3F9F]              ds:[3F9F]=1006
01EF:23B8  A0A53F              mov  al,[3FA5]              ds:[3FA5]=1106
01EF:23BB  3AC2                cmp  al,dl
01EF:23BD  7503                jne  000023C2 ($+3)         (no jmp)
01EF:23BF  E98F00              jmp  00002451 ($+8f)        (down)
01EF:23C2  A0A33F              mov  al,[3FA3]              ds:[3FA3]=0100
01EF:23C5  0AC0                or   al,al
01EF:23C7  7503                jne  000023CC ($+3)         (no jmp)
01EF:23C9  E98500              jmp  00002451 ($+85)        (down)
01EF:23CC  02D0                add  dl,al
01EF:23CE  E8A700              call 00002478 ($+a7)
01EF:23D1  3CFF                cmp  al,FF
01EF:23D3  7503                jne  000023D8 ($+3)         (no jmp)
01EF:23D5  E97F00              jmp  00002457 ($+7f)        (down)
01EF:23D8  0AC0                or   al,al
01EF:23DA  7403                je   000023DF ($+3)         (down)
01EF:23DC  EB73                jmp  short 00002451 ($+73)  (down)
01EF:23DE  90                  nop
01EF:23DF  A0A33F              mov  al,[3FA3]              ds:[3FA3]=0100
01EF:23E2  32E4                xor  ah,ah
01EF:23E4  E87600              call 0000245D ($+76)
01EF:23E7  7303                jnc  000023EC ($+3)         (down)
01EF:23E9  EB60                jmp  short 0000244B ($+60)  (down)
01EF:23EB  90                  nop
01EF:23EC  EB97                jmp  short 00002385 ($-69)  (up)
01EF:23EE  8B169F3F            mov  dx,[3F9F]              ds:[3F9F]=1006
01EF:23F2  A0A53F              mov  al,[3FA5]              ds:[3FA5]=1106
01EF:23F5  3AC2                cmp  al,dl
01EF:23F7  7426                je   0000241F ($+26)        (down)
01EF:23F9  A0A33F              mov  al,[3FA3]              ds:[3FA3]=0100
01EF:23FC  0AC0                or   al,al
01EF:23FE  741F                je   0000241F ($+1f)        (down)
01EF:2400  02D0                add  dl,al
01EF:2402  E87300              call 00002478 ($+73)
01EF:2405  3CFF                cmp  al,FF
01EF:2407  7503                jne  0000240C ($+3)         (no jmp)
01EF:2409  EB4C                jmp  short 00002457 ($+4c)  (down)
01EF:240B  90                  nop
01EF:240C  0AC0                or   al,al
01EF:240E  750F                jne  0000241F ($+f)         (no jmp)
01EF:2410  A0A33F              mov  al,[3FA3]              ds:[3FA3]=0100
01EF:2413  32E4                xor  ah,ah
01EF:2415  E84500              call 0000245D ($+45)
01EF:2418  7303                jnc  0000241D ($+3)         (down)
01EF:241A  EB2F                jmp  short 0000244B ($+2f)  (down)
01EF:241C  90                  nop
01EF:241D  EBCF                jmp  short 000023EE ($-31)  (up)
01EF:241F  8B169F3F            mov  dx,[3F9F]              ds:[3F9F]=1006
01EF:2423  3836A63F            cmp  [3FA6],dh              ds:[3FA6]=0411
01EF:2427  7428                je   00002451 ($+28)        (down)
01EF:2429  A0A43F              mov  al,[3FA4]              ds:[3FA4]=0601
01EF:242C  0AC0                or   al,al
01EF:242E  7421                je   00002451 ($+21)        (down)
01EF:2430  02F0                add  dh,al
01EF:2432  E84300              call 00002478 ($+43)
01EF:2435  3CFF                cmp  al,FF
01EF:2437  741E                je   00002457 ($+1e)        (down)
01EF:2439  0AC0                or   al,al
01EF:243B  7514                jne  00002451 ($+14)        (no jmp)
01EF:243D  8A26A43F            mov  ah,[3FA4]              ds:[3FA4]=0601
01EF:2441  E81900              call 0000245D ($+19)
01EF:2444  7303                jnc  00002449 ($+3)         (down)
01EF:2446  EB03                jmp  short 0000244B ($+3)   (down)
01EF:2448  90                  nop
01EF:2449  EBA3                jmp  short 000023EE ($-5d)  (up)
01EF:244B  C606A83F01          mov  byte [3FA8],01         ds:[3FA8]=0000	<-- hero is not reachable
01EF:2450  C3                  ret
01EF:2451  C606A83F02          mov  byte [3FA8],02         ds:[3FA8]=0000	<-- hero is not reachable
01EF:2456  C3                  ret
01EF:2457  C606A83F00          mov  byte [3FA8],00         ds:[3FA8]=0000	<-- hero is reachable
01EF:245C  C3                  ret

01EF:245D  89169F3F            mov  [3F9F],dx              ds:[3F9F]=1006	<-- called only when the monster needs to move
01EF:2461  8B1ECA40            mov  bx,[40CA]              ds:[40CA]=40A2
01EF:2465  8807                mov  [bx],al                ds:[3F28]=6148
01EF:2467  886701              mov  [bx+01],ah             ds:[3F29]=0061
01EF:246A  8306CA4002          add  word [40CA],0002       ds:[40CA]=40A2
01EF:246F  FE06A93F            inc  byte [3FA9]            ds:[3FA9]=0000
01EF:2473  FE0E9C3F            dec  byte [3F9C]            ds:[3F9C]=0003
01EF:2477  C3                  ret

01EF:2478  A0BC3F              mov  al,[3FBC]              ds:[3FBC]=0000
01EF:247B  E80139              call 00005D7F ($+3901)
01EF:247E  803C00              cmp  byte [si],00           ds:[4663]=06FF
01EF:2481  7408                je   0000248B ($+8)         (down)
01EF:2483  3B5401              cmp  dx,[si+01]             ds:[4664]=0D06
01EF:2486  7503                jne  0000248B ($+3)         (no jmp)
01EF:2488  B0FF                mov  al,FF
01EF:248A  C3                  ret

01EF:248B  B500                mov  ch,00
01EF:248D  382EBC3F            cmp  [3FBC],ch              ds:[3FBC]=0000
01EF:2491  7412                je   000024A5 ($+12)        (down)
01EF:2493  8AC5                mov  al,ch
01EF:2495  E8E738              call 00005D7F ($+38e7)
01EF:2498  803C00              cmp  byte [si],00           ds:[4663]=06FF
01EF:249B  7408                je   000024A5 ($+8)         (down)
01EF:249D  3B5401              cmp  dx,[si+01]             ds:[4664]=0D06
01EF:24A0  7503                jne  000024A5 ($+3)         (no jmp)
01EF:24A2  B001                mov  al,01
01EF:24A4  C3                  ret
01EF:24A5  FEC5                inc  ch
01EF:24A7  80FD04              cmp  ch,04
01EF:24AA  75E1                jne  0000248D ($-1f)        (no jmp)
01EF:24AC  52                  push dx
01EF:24AD  E8CE3B              call 0000607E ($+3bce)
01EF:24B0  5A                  pop  dx
01EF:24B1  81C36F58            add  bx,586F
01EF:24B5  803F00              cmp  byte [bx],00           ds:[3F28]=6148
01EF:24B8  7403                je   000024BD ($+3)         (down)
01EF:24BA  B002                mov  al,02
01EF:24BC  C3                  ret
01EF:24BD  8A8700FC            mov  al,[bx-0400]           ds:[3B28]=E04B
01EF:24C1  243F                and  al,3F
01EF:24C3  3A4503              cmp  al,[di+03]             ds:[4DBB]=FB26 	<-- monster's room check.
01EF:24C6  7503                jne  000024CB ($+3)         (no jmp)	
01EF:24C8  32C0                xor  al,al
01EF:24CA  C3                  ret
01EF:24CB  B003                mov  al,03
01EF:24CD  C3                  ret

01EF:24CE  893ED43F            mov  [3FD4],di              ds:[3FD4]=4DB8
01EF:24D2  8A0EA93F            mov  cl,[3FA9]              ds:[3FA9]=0001
01EF:24D6  0AC9                or   cl,cl
01EF:24D8  7455                je   0000252F ($+55)        (down)
01EF:24DA  32ED                xor  ch,ch
01EF:24DC  BBA240              mov  bx,40A2
01EF:24DF  891ECA40            mov  [40CA],bx              ds:[40CA]=40A4
01EF:24E3  51                  push cx
01EF:24E4  8B3ED43F            mov  di,[3FD4]              ds:[3FD4]=4DB8
01EF:24E8  8B5501              mov  dx,[di+01]             ds:[4DB9]=0F06
01EF:24EB  E8903B              call 0000607E ($+3b90)
01EF:24EE  8A8F6F58            mov  cl,[bx+586F]           ds:[59FB]=0000
01EF:24F2  C6876F5800          mov  byte [bx+586F],00      ds:[59FB]=0000
01EF:24F7  8B1ECA40            mov  bx,[40CA]              ds:[40CA]=40A2
01EF:24FB  8B5501              mov  dx,[di+01]             ds:[4DB9]=0F06
01EF:24FE  0217                add  dl,[bx]                ds:[018C]=1149
01EF:2500  027701              add  dh,[bx+01]             ds:[018D]=0611
01EF:2503  895501              mov  [di+01],dx             ds:[4DB9]=0F06
01EF:2506  8306CA4002          add  word [40CA],0002       ds:[40CA]=40A2
01EF:250B  E8703B              call 0000607E ($+3b70)
01EF:250E  888F6F58            mov  [bx+586F],cl           ds:[AE50]=0A16
01EF:2512  81C36F54            add  bx,546F
01EF:2516  895D04              mov  [di+04],bx             ds:[4DBC]=55E1
01EF:2519  E834F5              call 00001A50 ($-acc)		
01EF:251C  8B3ED43F            mov  di,[3FD4]              ds:[3FD4]=4DB8
01EF:2520  E81C00              call 0000253F ($+1c)
01EF:2523  E8BE3B              call 000060E4 ($+3bbe)
01EF:2526  B9F401              mov  cx,01F4
01EF:2529  E85B21              call 00004687 ($+215b)						<-- 500.000 nop cycles, to slow down monster's animation
01EF:252C  59                  pop  cx		
01EF:252D  E2B4                loop 000024E3 ($-4c)
01EF:252F  51                  push cx
01EF:2530  B93200              mov  cx,0032
01EF:2533  E86A11              call 000036A0 ($+116a)						<-- more nops 
01EF:2536  E2FB                loop 00002533 ($-5)
01EF:2538  59                  pop  cx
01EF:2539  E853F8              call 00001D8F ($-7ad)						<-- here the monster attacks whein in contact with the hero
01EF:253C  E99131              jmp  000056D0 ($+3191)      (down)
01EF:253F  8A4502              mov  al,[di+02]             ds:[EF42]=3736
01EF:2542  32E4                xor  ah,ah
01EF:2544  BA000A              mov  dx,0A00
01EF:2547  F7E2                mul  dx
01EF:2549  8BD8                mov  bx,ax

01EF:4687  51                  push cx
01EF:4688  E820EF              call 000035AB ($-10e0)
01EF:468B  59                  pop  cx
01EF:468C  E2F9                loop 00004687 ($-7)
01EF:468E  C3                  ret

01EF:607E  8ADE                mov  bl,dh	
01EF:6080  B700                mov  bh,00	
01EF:6082  03DB                add  bx,bx
01EF:6084  81C3C55A            add  bx,5AC5
01EF:6088  8B07                mov  ax,[bx]                ds:[0130]=0101
01EF:608A  B600                mov  dh,00
01EF:608C  03D0                add  dx,ax
01EF:608E  8BDA                mov  bx,dx
01EF:6090  C3                  ret


Hero's pathfinding routine

01EF:6449  E8E2D4              call 0000392E ($-2b1e)
01EF:644C  E85800              call 000064A7 ($+58)
01EF:644F  833CFF              cmp  word [si],FFFF         ds:[3911]=0000
01EF:6452  7503                jne  00006457 ($+3)         (down)
01EF:6454  E95F03              jmp  000067B6 ($+35f)       (down)

01EF:67B6  8B16E747            mov  dx,[47E7]              ds:[47E7]=0087
01EF:67BA  8B2EE947            mov  bp,[47E9]              ds:[47E9]=0097
01EF:67BE  BB2D40              mov  bx,402D
01EF:67C1  BE1941              mov  si,4119
01EF:67C4  B93400              mov  cx,0034
01EF:67C7  51                  push cx
01EF:67C8  8B4402              mov  ax,[si+02]             ds:[491E]=01C0
01EF:67CB  051800              add  ax,0018
01EF:67CE  2BC2                sub  ax,dx
01EF:67D0  7302                jnc  000067D4 ($+2)         (down)
01EF:67D0  7302                jnc  000067D4 ($+2)         (no jmp)
01EF:67D2  F7D8                neg  ax
01EF:67D4  D1E8                shr  ax,1
01EF:67D6  8B0C                mov  cx,[si]                ds:[4119]=0044
01EF:67D8  83C108              add  cx,0008
01EF:67DB  2BCD                sub  cx,bp
01EF:67DD  7302                jnc  000067E1 ($+2)         (no jmp)
01EF:67DF  F7D9                neg  cx
01EF:67E1  03C1                add  ax,cx
01EF:67E3  D1E8                shr  ax,1
01EF:67E5  8907                mov  [bx],ax                ds:[402D]=0000
01EF:67E7  83C302              add  bx,0002
01EF:67EA  83C604              add  si,0004
01EF:67ED  59                  pop  cx
01EF:67EE  E2D7                loop 000067C7 ($-29)
01EF:67F0  BB2D40              mov  bx,402D
01EF:67F3  B8FFFF              mov  ax,FFFF
01EF:67F6  B93400              mov  cx,0034
01EF:67F9  3B07                cmp  ax,[bx]                ds:[402D]=0000
01EF:67FB  7204                jc   00006801 ($+4)         (down)
01EF:67FD  8B07                mov  ax,[bx]                ds:[4095]=0000
01EF:67FF  8BD1                mov  dx,cx
01EF:6801  83C302              add  bx,0002
01EF:6804  E2F3                loop 000067F9 ($-d)
01EF:6806  3D0800              cmp  ax,0008
01EF:6809  7201                jc   0000680C ($+1)         (no jmp)
01EF:680B  C3                  ret
01EF:680C  BB3400              mov  bx,0034
01EF:680F  2BDA                sub  bx,dx
01EF:6811  83FB2D              cmp  bx,002D
01EF:6814  720B                jc   00006821 ($+b)         (down)
01EF:6816  83EB2D              sub  bx,002D
01EF:6819  D1E3                shl  bx,1
01EF:681B  8B8F034A            mov  cx,[bx+4A03]           ds:[4A14]=0E09
01EF:681F  EB06                jmp  short 00006827 ($+6)   (down)
01EF:6821  8A8FD649            mov  cl,[bx+49D6]           ds:[49E7]=1E37
01EF:6825  32ED                xor  ch,ch
01EF:6827  A1E43F              mov  ax,[3FE4]              ds:[3FE4]=5574
01EF:682A  03C1                add  ax,cx
01EF:682C  2D6F54              sub  ax,546F
01EF:682F  8BD8                mov  bx,ax
01EF:6831  81C36F56            add  bx,566F
01EF:6835  3B1E110E            cmp  bx,[0E11]              ds:[0E11]=FFFF
01EF:6839  7501                jne  0000683C ($+1)         (down)
01EF:683B  C3                  ret
01EF:683C  8BD8                mov  bx,ax
01EF:683E  B500                mov  ch,00
01EF:6840  3D1A00              cmp  ax,001A
01EF:6843  7207                jc   0000684C ($+7)         (down)
01EF:6845  2D1A00              sub  ax,001A
01EF:6848  FEC5                inc  ch
01EF:684A  EBF4                jmp  short 00006840 ($-c)   (up)
01EF:684C  8AC8                mov  cl,al
01EF:684E  8A876F54            mov  al,[bx+546F]           ds:[AC1A]=0200
01EF:6852  243F                and  al,3F
01EF:6854  7501                jne  00006857 ($+1)         (down)
01EF:6856  C3                  ret
01EF:6857  80BF6F5800          cmp  byte [bx+586F],00      ds:[B01A]=0101
01EF:685C  7503                jne  00006861 ($+3)         (down)
01EF:685E  EB11                jmp  short 00006871 ($+11)  (down)
01EF:6860  90                  nop
01EF:6861  80BF6F5800          cmp  byte [bx+586F],00      ds:[B01A]=0101
01EF:6866  7501                jne  00006869 ($+1)         (down)
01EF:6868  C3                  ret
01EF:6869  80BF6F5840          cmp  byte [bx+586F],40      ds:[B01A]=0101
01EF:686E  7201                jc   00006871 ($+1)         (down)
01EF:6870  C3                  ret
01EF:6871  8BD1                mov  dx,cx
01EF:6873  51                  push cx
01EF:6874  E810AA              call 00001287 ($-55f0)
01EF:6877  59                  pop  cx
01EF:6878  0AC0                or   al,al
01EF:687A  7401                je   0000687D ($+1)         (down)
01EF:687C  C3                  ret
01EF:687D  8B3E3746            mov  di,[4637]              ds:[4637]=4663
01EF:6881  880EF03F            mov  [3FF0],cl              ds:[3FF0]=0000
01EF:6885  882EF13F            mov  [3FF1],ch              ds:[3FF1]=0000
01EF:6889  8A4501              mov  al,[di+01]             ds:[3913]=0000
01EF:688C  A2EE3F              mov  [3FEE],al              ds:[3FEE]=0000
01EF:688F  A2F53F              mov  [3FF5],al              ds:[3FF5]=0C02
01EF:6892  8A4502              mov  al,[di+02]             ds:[4665]=200C
01EF:6895  A2EF3F              mov  [3FEF],al              ds:[3FEF]=040C
01EF:6898  A2F63F              mov  [3FF6],al              ds:[3FF6]=000C
01EF:689B  E80EC5              call 00002DAC ($-3af2)
01EF:689E  803EC83F00          cmp  byte [3FC8],00         ds:[3FC8]=0000
01EF:68A3  7501                jne  000068A6 ($+1)         (no jmp)
01EF:68A5  C3                  ret
01EF:68A6  BB1340              mov  bx,4013
01EF:68A9  891ECC3F            mov  [3FCC],bx              ds:[3FCC]=0000
01EF:68AD  C3                  ret  
01EF:2DAC  A0EE3F              mov  al,[3FEE]              ds:[3FEE]=0000
01EF:2DAF  2A06F03F            sub  al,[3FF0]              ds:[3FF0]=1515
01EF:2DB3  7902                jns  00002DB7 ($+2)         (no jmp)
01EF:2DB5  F6D8                neg  al
01EF:2DB7  8A26EF3F            mov  ah,[3FEF]              ds:[3FEF]=1500
01EF:2DBB  2A26F13F            sub  ah,[3FF1]              ds:[3FF1]=3915
01EF:2DBF  7902                jns  00002DC3 ($+2)         (no jmp)
01EF:2DC1  F6DC                neg  ah
01EF:2DC3  02C4                add  al,ah
01EF:2DC5  A2E937              mov  [37E9],al              ds:[37E9]=3737
01EF:2DC8  A09C3F              mov  al,[3F9C]              ds:[3F9C]=3A3A
01EF:2DCB  32E4                xor  ah,ah
01EF:2DCD  A3F93F              mov  [3FF9],ax              ds:[3FF9]=3F3E
01EF:2DD0  C606A83F00          mov  byte [3FA8],00         ds:[3FA8]=3A3A
01EF:2DD5  C606C83F00          mov  byte [3FC8],00         ds:[3FC8]=1515
01EF:2DDA  C706F33F0000        mov  word [3FF3],0000       ds:[3FF3]=1515
01EF:2DE0  C706CC3F0000        mov  word [3FCC],0000       ds:[3FCC]=3B3C

Starting from memory location 0B6B:0A0E the subsequent 512 bytes are set to 1A1A x100h (256 times) by this function:

01EF:2DE6  BF0E0A              mov  di,0A0E
01EF:2DE9  B90001              mov  cx,0100
01EF:2DEC  50                  push ax
01EF:2DED  B86B0B              mov  ax,0B6B
01EF:2DF0  8EC0                mov  es,ax
01EF:2DF2  58                  pop  ax
01EF:2DF3  B81A1A              mov  ax,1A1A
01EF:2DF6  F3AB                repe stosw

The code then creates a map with all possible paths of the hero:

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 07 06 07 08 09 -- 09 08
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 07 06 05 06 09 0A 09 08 07
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 06 05 04 05 0A 0B 0A 09 06
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 05 04 03 04 0B -- -- -- 05
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 03 02 01 02 01 02 03 04
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 05 04 03 02 -- -- -- -- 05
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 06 05 04 03 -- -- -- -- 06
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 07 06 05 04 -- -- -- -- 07
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 07 06 05 -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
01EF:2DF8  8B3E3746            mov  di,[4637]              ds:[4637]=4663
01EF:2DFC  EB74                jmp  short 00002E72 ($+74)  (down)
01EF:2DFE  90                  nop
01EF:2DFF  A0F23F              mov  al,[3FF2]              ds:[3FF2]=0000
01EF:2E02  8B1EF33F            mov  bx,[3FF3]              ds:[3FF3]=0000
01EF:2E06  8887FB3F            mov  [bx+3FFB],al           ds:[411D]=0050
01EF:2E0A  43                  inc  bx
01EF:2E0B  3B1EF93F            cmp  bx,[3FF9]              ds:[3FF9]=0009
01EF:2E0F  7601                jbe  00002E12 ($+1)         (no jmp)
01EF:2E11  C3                  ret
01EF:2E12  891EF33F            mov  [3FF3],bx              ds:[3FF3]=0001
01EF:2E16  8A26F93F            mov  ah,[3FF9]              ds:[3FF9]=0009
01EF:2E1A  2AE3                sub  ah,bl
01EF:2E1C  A0F03F              mov  al,[3FF0]              ds:[3FF0]=0B04
01EF:2E1F  2A06F53F            sub  al,[3FF5]              ds:[3FF5]=0B04
01EF:2E23  7902                jns  00002E27 ($+2)         (down)
01EF:2E25  F6D8                neg  al
01EF:2E27  3AC4                cmp  al,ah
01EF:2E29  7603                jbe  00002E2E ($+3)         (down)
01EF:2E2B  E98400              jmp  00002EB2 ($+84)        (down)
01EF:2E2E  A0F13F              mov  al,[3FF1]              ds:[3FF1]=000B
01EF:2E31  2A06F63F            sub  al,[3FF6]              ds:[3FF6]=000B
01EF:2E35  7902                jns  00002E39 ($+2)         (down)
01EF:2E37  F6D8                neg  al
01EF:2E39  3AC4                cmp  al,ah
01EF:2E3B  7775                ja   00002EB2 ($+75)        (no jmp)
01EF:2E3D  E87700              call 00002EB7 ($+77)
01EF:2E40  7270                jc   00002EB2 ($+70)        (no jmp)
01EF:2E42  3E885E00            mov  ds:[bp],bl             ds:[007A]=0002
01EF:2E46  A0F53F              mov  al,[3FF5]              ds:[3FF5]=0B04
01EF:2E49  3A06F03F            cmp  al,[3FF0]              ds:[3FF0]=0B04
01EF:2E4D  7523                jne  00002E72 ($+23)        (no jmp)
01EF:2E4F  A0F63F              mov  al,[3FF6]              ds:[3FF6]=000B
01EF:2E52  3A06F13F            cmp  al,[3FF1]              ds:[3FF1]=000B
01EF:2E56  751A                jne  00002E72 ($+1a)        (no jmp)
01EF:2E58  881EC83F            mov  [3FC8],bl              ds:[3FC8]=0000
01EF:2E5C  57                  push di
01EF:2E5D  BF1340              mov  di,4013
01EF:2E60  BEFB3F              mov  si,3FFB
01EF:2E63  8A0EC83F            mov  cl,[3FC8]              ds:[3FC8]=0000
01EF:2E67  32ED                xor  ch,ch
01EF:2E69  890EF93F            mov  [3FF9],cx              ds:[3FF9]=0001
01EF:2E6D  F3A4                repe movsb
01EF:2E6F  5F                  pop  di
01EF:2E70  EB40                jmp  short 00002EB2 ($+40)  (down)
01EF:2E72  C606F23F00          mov  byte [3FF2],00         ds:[3FF2]=0100
01EF:2E77  FE0EF63F            dec  byte [3FF6]            ds:[3FF6]=000B

part of 2DF8 routine this writes the temporary math:

01EF:2E7B  E881FF              call 00002DFF ($-7f)
01EF:2E7E  FE06F63F            inc  byte [3FF6]            ds:[3FF6]=000B
01EF:2E82  C606F23F01          mov  byte [3FF2],01         ds:[3FF2]=0000
01EF:2E87  FE06F53F            inc  byte [3FF5]            ds:[3FF5]=0B04
01EF:2E8B  E871FF              call 00002DFF ($-8f)
01EF:2E8E  FE0EF53F            dec  byte [3FF5]            ds:[3FF5]=0B04
01EF:2E92  C606F23F02          mov  byte [3FF2],02         ds:[3FF2]=0000
01EF:2E97  FE06F63F            inc  byte [3FF6]            ds:[3FF6]=000B
01EF:2E9B  E861FF              call 00002DFF ($-9f)
01EF:2E9E  FE0EF63F            dec  byte [3FF6]            ds:[3FF6]=000B
01EF:2EA2  C606F23F03          mov  byte [3FF2],03         ds:[3FF2]=0000
01EF:2EA7  FE0EF53F            dec  byte [3FF5]            ds:[3FF5]=0B04
01EF:2EAB  E851FF              call 00002DFF ($-af)
01EF:2EAE  FE06F53F            inc  byte [3FF5]            ds:[3FF5]=0B04
01EF:2EB2  FF0EF33F            dec  word [3FF3]            ds:[3FF3]=0000
01EF:2EB6  C3                  ret


Memory locations for hero's movement 3FEE = 3FEF = Y stop 3FF0 = X stop 3FF1 = Y start 3FF2 = X start 3FF3 = 3FF4 = 3FF5 = 3FF6 = 3FF9 = rolled movement

3FFB - 4005 = math locations that varies among 00,01,02,03, at the end every byte is set to 03


The hero's moving animation is then delegated to in-game the main loop routines.

[DATA SEGMENT] Main Pointers

The file inside the exe that represents the Data Segment (every byte that is not strictly CODE) starts at offset 0x9BE0. Every pointer is relative to this address.


Heroes' default profiles

offset  mem pointer                   BP MP                      EQ             AD DD          ID 
0xE243  0B6B:4663   00 00 00 00 00 00 08 02 1D 00 00 00 00 00 00 00 00 00 00 00 03 02 00 00 00 00	Barbarian
0xE25D  0B6B:467D   00 00 00 00 00 00 07 03 32 00 00 00 00 00 00 80 00 00 00 00 02 02 00 00 00 01	Dwarf
0xE277  0B6B:4697   00 00 00 00 00 00 06 04 35 00 00 00 00 00 00 00 00 00 00 00 02 02 00 00 00 02	Elf
0xE291  0B6B:46B1   00 00 00 00 00 00 04 06 4A 00 00 00 00 00 00 00 00 00 00 00 01 02 00 00 00 03	Wizard
0xE2AB  0B6B:46CB   00 00 00 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 00 01 02 00 00 00 04	Ragnar

The byte positions are the same of HeroQuest Savegame Format. Load and save operations read and write at these addreses.

When initializing the heroes the default values are resetted by the function 01EF:78D3 that resets all values to zero and Body and Mind points to default

0x00DF74 0B6B:4394  08 07 06 04 02    Default Body point values (last one is Ragnar's)
0x0148FB 0B6B:AD1B  02 03 04 06 00    Default Mind point values

Character initialization code:

01EF:78D3  8A1E9E40            mov  bl,[409E]              ds:[409E]=0002
01EF:78D7  B700                mov  bh,00
01EF:78D9  8B879443            mov  ax,[bx+4394]           ds:[4396]=0406
01EF:78DD  884406              mov  [si+06],al             ds:[469D]=0406	<-- sets default body points
01EF:78E0  8A871BAD            mov  al,[bx-52E5]           ds:[FFFFAD1D]=EC8B
01EF:78E4  884407              mov  [si+07],al             ds:[469E]=3804	<-- sets default mind points
01EF:78E7  C6440E00            mov  byte [si+0E],00        ds:[46A5]=0000	<-- resets Owned weapon
01EF:78EB  C6440F00            mov  byte [si+0F],00        ds:[46A6]=0000	<-- resets Owned armour
01EF:78EF  C6440D00            mov  byte [si+0D],00        ds:[46A4]=0000	<-- resets Owned special items 
01EF:78F3  C744090000          mov  word [si+09],0000      ds:[46A0]=000A	<-- resets GOLD
01EF:78F8  C6441100            mov  byte [si+11],00        ds:[46A8]=0000	<-- resets Equipped weapon
01EF:78FC  C6441200            mov  byte [si+12],00        ds:[46A9]=0000	<-- resets Equipped special item
01EF:7900  C6441300            mov  byte [si+13],00        ds:[46AA]=0200	<-- resets Equipped armour
01EF:7904  885C19              mov  [si+19],bl             ds:[46B0]=0002	<-- refresh hero's ID
01EF:7907  803E9E4001          cmp  byte [409E],01         ds:[409E]=0002	<-- if dwarf
01EF:790C  7504                jne  00007912 ($+4)         (down)
01EF:790E  804C0E80            or   byte [si+0E],80        ds:[46A5]=0000	<-- gives him the toolkit
01EF:7912  BB0800              mov  bx,0008					<-- "The character is renewed" string
01EF:7915  E8D50F              call 000088ED ($+fd5)				<-- draws the scroll

Searched room table

The game keeps track of the searched room by storing the value FF into a two tables (treasure and traps searches) using the room number as relative offset (bx).
Room numbers go from 00 to 2A so each table is 2B bytes long and every byte of the table is set to 00 at the beginnng of the quest.
The code that puts FF into the table:

mov byte ptr [bx+4B70h], 0FFh    [0B6B:4B70] starting address of TREASURE search
mov byte ptr [bx+4B9Bh], 0FFh    [0B6B:4B9B] starting address of TRAPS/SECRET PASSAGES search

NOTE: upon starting a quest, every Special event ID is put into the tables replacing the 00.

Equipment screen

With position on screen is intended the string header 11XXYY

0x014863 Hero's classes label (ie. Barbarian) position on screen
0x00DF2B pointers block to default Hero's classes (5 pointers)
0x00DF35 default Hero's classes labels (5 Labels)
0x014873 Hero's name label (ie. Sigmar) position on screen
0x00E1B7 pointers block to default Hero's names
0x00E1C5 default Hero's names labels (5 Labels)
0x0141A4 first epilogue panel text (its pointer A5C4 is written inside the code at offset 0x0649)
0x0143A2 second epilogue panel text (its pointer A7C2 is written inside the code at offset 0x0658)
0x0147F7 actual gear prices (hexadecimal) -  4x12 = 30 Bytes (2 bytes for equipment bit mask and 2 bytes for default price, little endian)
0x01482B pointers block to single gear costs - 2xC = 18 Bytes
0x014843 price (in decimal) labels - 1F Bytes
0x01486F "GOLD" label position on screen
0x014867 gold amount position on screen (default is 0000)
0x014877 equipment names position on screen
0x01487B pointers block to the pointers in [language].bin where the item names are - 0x18 Bytes
0x014943 equipment names position on screen during a quest (the subsequent 28 zeroes are the placeholder)
0x014920 position on screen of a bar filled with 20h char used to delete the equipment names while moving se mouse over the icons
0x014924 Text colour (1F is white)
0x014925 Background colour (14 is transparent)

Intro Sequence

Every text panel of the intro resides into INTRO.EXE and they're in English only.
In order to translate them (or change the lenght of the text) you have to uncompress the exe first, then Locate every pointers of each panel.
The data segment inside the exe starts at 0x01C0. Every pointer is relative to this address.

Panel # default pointer value pointer exe offset
1 0603 0x0212
2 F203 0x0214
3 9B04 0x0216
4 8706 0x0218
5 7008 0x021A
6 CA0A 0x021C

The panels layout follows the same rules described under HeroQuest Strings Format

Protection screen

to restore shield protection in UNCOMPRESSED QUEST.EXE modify

offset 0x0541 from 90 90 90	to E8 DC FE		(if you modify these bytes only the shield screen stays and regardless of page entered the game starts anyway)
offset 0x0549 from EB		to 74