Under construction. Last update: 2010/11/03 14:58 +0900
A screenshot of test tool. It is log reader. The log describes procedure-to-procedure call history. My special version of DOSBox generates it while playing the game.
Each tree item is a procedure. xxxx:yyyy means procedure's far pointer address in i386 real mode. It says where the procedure starts in computer memory then.
You can see some procedures have meaningful names such as "FIRE_BLIT_PICTURE
".
It is an analyzed procedure on its code working and brought results.
The above screenshots say many many (over 300) procedures should be converted from disasm codes to C/C++ compatible code. It is to partially reproduce the DM2 behavior, such as game load/save routine work. Disasm is brought by debug version of DOSBox. Many thanks to DOSBox community! It is very nice feature.
Currently, the code conversion is done by hand work. Human's brain is
essential to do code conversion. Partially computer helps to generate
formalized/normalized part such as conditional jump meaning such as "if
AX != FFE0
" against "cmp ax,FFE0
", and "if
( AX | 0000 )==0
" against "or ax,0000
".
The following is disassembled source code of FIRE_BLIT_PICTURE
procedure in unlzexec'd FIRE.exe.
Next pair of procedures should have been first successful conversion of this proj.
Disasm code
C/C++ compatible code
Here is a sample of procedure call history tree.
A procedure call tree (partial, not entire)
CREDITS: source code html coloring and formatting is presented by htmlize.
I'm developing the a conversion way which makes it easy to convert from ASM to C.
exp00240 conversion 0.1 sample
I crafted a conversion tool with another thought. Just "I work for conversion, so shorten the total conversion time cost!"
exp00240 conversion 0.2 sample
The progress report has moved to dedicated page. here is a progress paper.
A procedure call tree updated. Investigating how to decode compressed rects chunk.
A procedure call tree updated.
A procedure call tree updated.
A procedure call tree updated.
A procedure call tree updated.
A procedure call tree updated.
A procedure call tree updated.
A procedure call tree updated.
A procedure call tree updated.
New: _0b36_129a, _1031_01d5, _1031_024c, _1031_030a, _1031_03f2,
_1031_0a88, _1031_0c58, _1031_0d9e, _1031_10c8, _1031_111e, _1031_156f,
_2e62_0670, HANDLE_UI_EVENT, PT_IN_RECT
It is to shorten the conversion cost per procedure function. I continue to improve the helper tools to do it faster.
A procedure call tree updated.
New: _0b36_1688, _2405_00ec, _2405_011f, _24a5_0e82, _24a5_0fb8,
_24a5_1532, _2e62_00a3, _2e62_011b, _2e62_02ea, _2e62_0360, _2e62_0572,
_2e62_05d4, _2e62_061d, _2e62_064a
A procedure call tree updated.
New: _0cee_279d, _12b4_0141, _13ae_0009, _1c9a_3a6e, _2405_0029,
_2405_005e, _2405_00c9, _2405_00e7, _2405_02e8, _2405_04f4, _24a5_000f,
_24a5_0a06, _24a5_0ad2, _24a5_0b0f, _24a5_0c35, _2759_0155, _2c1d_06b5,
_2c1d_073d, _2c1d_0889, _2c1d_0ea2, _2e62_0265, _2e62_03b5, _2e62_0cfa,
_3929_07e1, _3929_0826, _3929_0914, _3929_0929, _3929_09fb, _3929_0b5a,
_3929_0c37, _3a15_0f07, _3a15_0fa5, _3a15_38b6, _48ae_04b7, F_LMOD@, FILL_STR,
FORMAT_SKSTR, GET_MAX_CHARGE, IS_MISCITEM_CURRENCY, RESET_SQUAD_DIR, SK_LTOA10,
SK_STRCAT, SK_STRCPY
Removed:_0cd5_0018, _0cee_29b9
A procedure call tree updated.
New: _1031_16a0, _24a5_1798, _2759_222e, _2759_274d, _2f3f_0000,
_2f3f_04ea, _32cb_06cf, _443c_0004, _443c_0434, FIND_SPELL_BY_RUNES
A procedure call tree updated.
New:_01b0_087a, _01b0_0d39, _075f_000b, _075f_1f33, _0b36_1757,
_0cee_159b, _0cee_3202, _121e_0422, _13e4_0360, _1c9a_0cf7, _1c9a_103a,
_1c9a_11bb, _24a5_10fb, _24a5_174d, _2759_0589, _2759_0602, _2759_0f39,
_2759_1204, _2759_14c8, _2759_15d0, _29ee_0b4a, _2c1d_0b2c, _2c1d_0e23,
_2c1d_0e57, _2c1d_0f67, _2c1d_111e, _2c1d_11bf, _2c1d_1cf3, _2c1d_1d64,
_2c1d_1de2, _2fcf_183c, _2fcf_2da7, _443c_03f4, _443c_08ab, _48ae_0001,
_48ae_0058, ADD_RUNE_TO_TAIL, ALLOC_NEW_CREATURE, DRINK_MISCITEM_WATER,
ENGAGE_COMMAND, ENGAGE_X_TELEPORTER, FIND_HAND_WITH_EMPTY_FLASK, OVERSEE_RECORD,
QUERY_CUR_CMDSTR_ENTRY, QUERY_GDAT_FOOD_VALUE_FROM_RECORD, REMOVE_RUNE_FROM_TAIL,
SET_DESTINATION_OF_MINION_MAP
Removed:
A procedure call tree updated.
Some procedures are removed due to refresh of exist procedure call history.
New:_0cee_2e09, _0cee_317f, _32cb_0287, ALLOC_UPPER_MEMORY,
FIND_DISTINCTIVE_ITEM_ON_TILE, FIRE_BOOTSTRAP, GET_WALL_TILE_ANYITEM_RECORD,
IBMIO_BOOTSTRAP, IS_WALL_ORNATE_SPRING, MOVE_RECORD_AT_WALL
Removed:_01b0_087a, _01b0_0d39, _0cee_279d, _2066_1ea3, _2066_1ec9, _2066_1f37,
_2066_1fab, _24a5_0a06, _24a5_0ad2, _24a5_0b0f, _24a5_10fb, _24a5_1532,
_24a5_174d, _2759_0155, _2759_15d0, _29ee_0b4a, _2f3f_0000, _2f3f_04ea,
_3a15_0fa5, _443c_03f4, _443c_04b6, _443c_08ab, _48ae_04b7, DRINK_MISCITEM_WATER,
FIND_HAND_WITH_EMPTY_FLASK, FIRE_MOUSE_SET_POS, IBMIO_MOUSE_SET_POS,
IS_MISCITEM_CURRENCY, QUERY_GDAT_FOOD_VALUE_FROM_RECORD, REMOVE_RUNE_FROM_TAIL,
ROTATE_RECORD_BY_TELEPORTER, RUN_ACTUATOR_TICK_GENERATOR
Generated a per segment address procedure sort.
New:_01b0_04e4, _075f_084d, _075f_1791, _075f_1bc2, _0cd5_0039,
_0cee_3275, _1031_06a5, _12b4_023f, _12b4_0300, _12b4_0881, _12b4_0953,
_12b4_099e, _12b4_0bf1, _13e4_0004, _13e4_0401, _14cd_0802, _19f0_000a,
_19f0_0081, _19f0_00b8, _19f0_01d6, _19f0_0207, _19f0_045a, _19f0_04bf,
_19f0_050f, _19f0_0547, _19f0_0559, _19f0_05e8, _19f0_0891, _19f0_0d10,
_19f0_13aa, _19f0_1511, _19f0_1522, _1c9a_0006, _1c9a_0551, _1c9a_0598,
_1c9a_0648, _1c9a_0e14, _1c9a_19d4, _1c9a_1a48, _1c9a_1b16, _2066_32bb,
_24a5_036a, _2c1d_028c, _2c1d_105f, _2fcf_0c7d, _476d_050e
Converted the depends procedures started from GAME_LOAD procedure. Now converting the fire_main procedure.
Experimental procedure-to-procedure call tree graph available: here is a graph paper
New:_00eb_05c7, _00eb_0bc4, _01b0_08b6, _01b0_0e80, _01b0_1be8,
_01b0_1ed2, _01b0_1ffc, _01b0_20ca, _01b0_20ef, _01b0_2b1b, _075f_11ba,
_075f_1c74, _0b36_020e, _1031_07d6, _13ae_005c, _13e4_01a3, _13e4_0982,
_13e4_0cf2, _14cd_0009, _14cd_0067, _14cd_0276, _14cd_0389, _14cd_0457,
_14cd_0550, _14cd_062e, _14cd_0684, _14cd_0815, _14cd_08f5, _14cd_09e2,
_14cd_0f0a, _14cd_0f3c, _14cd_102e, _14cd_10d2, _14cd_1316, _14cd_18cc,
_14cd_18f2, _14cd_19a4, _14cd_19c2, _14cd_1a3c, _14cd_1a5a, _14cd_1a78,
_14cd_1b74, _14cd_1bac, _14cd_1c45, _14cd_1c63, _14cd_1c8d, _14cd_1cec,
_14cd_1d42, _14cd_1eec, _14cd_1f8b, _14cd_1ff3, _14cd_2162, _14cd_221a,
_14cd_226d, _14cd_22a3, _14cd_232b, _14cd_2398, _14cd_240e, _14cd_248d,
_14cd_25b8, _14cd_2662, _14cd_274f, _14cd_2807, _14cd_2886, _14cd_28d2,
_14cd_2c23, _14cd_2e6e, _14cd_2f07, _14cd_3087, _14cd_3139, _14cd_32a4,
_14cd_33e1, _14cd_3474, _14cd_34d3, _14cd_36b3, _14cd_3aee, _1887_00f8,
_1887_0205, _1887_0239, _1887_05aa, _1887_05f3, _1887_150c, _1c9a_0732,
_1c9a_078b, _1c9a_166f, _1c9a_37be, _1c9a_381c, _1c9a_38a8, _1c9a_3c30,
_2405_0009, _2481_0002, _2481_007d, _2636_03d4, _32cb_0008, _38c8_00c8,
_38c8_0104, _38c8_0109, _38c8_0224, _38c8_04aa, _3929_0e16, _3a15_072f,
_3a15_0763, _3a15_2ca8, _3a15_3a9e, _3e74_0004, _3e74_04d8, _3e74_059e,
_3e74_07b2, _3e74_0820, _3e74_1175, _3e74_1330, _3e74_16ed, _3e74_1d5f,
_3e74_2162, _3e74_216a, _3e74_22cf, _3e74_2439, _3e74_24b8, _3e74_2641,
_3e74_2ec7, _3e74_5788, _443c_0380, _443c_067a, _44c8_1baf, _470a_0003,
_4726_02f7, _4726_03b2, _476d_018a, _476d_02e0, _476d_04f4, _47eb_0003,
_482b_0004, _4937_0320, _crt_brk, _crt_coreleft, _crt_CreateHeap, _crt_farcoreleft,
_crt_farmalloc, _crt_getvect, _crt_normalize, _crt_setblock, ADD_COIN_TO_WALLET,
EMS_ALLOC_POOL , FIND_TILE_ACTUATOR, FIRE_main, GET_FILE_POS_6, GET_FILE_SIZE,
KANJI_FONT_LOAD, OPERATE_PIT_TELE_TILE, WOUND_CREATURE
Removed:_13ae_02a3, IDLE
here is a graph paper and here is a progress paper updated.
New:_075f_18fd, _13e4_071b, _13e4_0806, _13e4_08ff, _1887_09ab,
_1887_0ce1, _1887_0d33, _1887_0df7, _1887_0e19, _1887_0eca, _1887_0f80,
_1887_0fb9, _1887_10db, _3a15_07b4, _3a15_0acd, _3a15_10dc, _3a15_12b8,
_3a15_13cb, _3a15_16ec, _3a15_1da8, _3a15_1ea8, _3a15_220c, _4937_028a,
QUERY_DOOR_STRENGTH
Removed:
Today I succeeded to start debugging DM2_SKSAVE_Converter on Visual Studio NET!
It is time to find and fix lying errors with running code. The converted source code has 57,054 lines for now.
My working processes:
Finally it got on mini frame.
Here are some comments on my conversion work.
The below is comparison sample. The left view is before edit (wrong program).
The right view is after edit (fixed program). It shows that the order of
function call parameter was incorrect.
The below one is also comparison sample. The wrong comparison code "si
> bp0a
" is corrected to right code "si >= bp0a
". As the side
effect of wrong conversion, this code breaks data memory widely, then rest
process of running program brought unexpected results. Finally running code has
been caught by Windows.
This code bit is part of DECODE_IMG3_OVERLAY
procedure.
The below one says "bp01 += 2
" was lack on left code bit.
It is effective to specify what is acceptable condition. For example, memory
allocation checks the buffer size: must be greater equal than 0 bytes and less
than 60,000 bytes.
The validation works only on executable program built on "debug build". All the
validation code is gone on "release build". So the validation code does not
affect the quality of executable program built for final release.
Now it implements mouse support. It can start the game and increase the game
tick now. The message is displayed in Japanese because this port is based on DM2
PS/V version.
That language difficulty will be solved on near future effectively.
It still has numerous problems to play the game on usual way. The game often freezes rather than program abort on usual play.
It gets better by doing bug fix.
I often proceed comparison behavior both DM2 PS/V on DOSBox emulator and ported DM2_SKSAVE_Converter by running simultaneously when I cannot find what is bug easily. This is very terrible work!
Next one shows proceeding comparison by output numerous debug information on
console window. The red mark shows just one difference which I want to know.
The left console window is attached to DM2_SKSAVE_Converter. The right notepad
shows output of DOSBox. I injected some debug codes into DOSBox for this cheat.
The mistake was very easy. However it costs so much time to locate them.
Accidentally I knew my procedure sort page is hit when you google with "F_PADD" keyword. So I decided write some of what they are, with C languange and the lying x86 machine language manner.
The following procedures are provided by Borland's Turbo C++ compiler for
MS-DOS programs. Their procedures are specific for x86 and 16-bits MS-DOS mode,
to perform effective pointer operation. That characteristic is called as A20
address line mode Real-address mode model. (You can check it at "3.3.
MEMORY ORGANIZATION" in
Intel Architecture Software Developer's Manual PDF document.)
Procedure | Purpose | Sample |
---|---|---|
F_PADD N_PADD |
Add offset to pointer, then normalize the pointer. | PADD |
F_PSUB N_PSUB |
Subtract offset from pointer, then normalize the pointer. | PSUB |
F_PADA N_PADA |
Add offset to pointer variable, then normalize the pointer variable. | PADA |
F_PINA N_PINA |
Add offset to pointer variable, then acquire the pointer before accumlative operation. | PINA |
* F_xxx is far address procedure. N_xxx is near address procedure.
PADD
Input: DX:AX ... your far pointer
Input: CX:BX ... your offset for add operation. 32 bits signed integer
Output: DX:AX ... normalized result far pointer
Sample source code bit to use that procedure.
Disassembled by Turbo Debugger
PSUB
Input: DX:AX ... your far pointer.
Input: CX:BX ... your offset for subtract operation. 32 bits signed integer.
Output: DX:AX ... normalized result far pointer.
PADA
Input: DX:AX
... far pointer to your far pointer variable.
Input: far ptr [DX:AX] ... your far pointer variable.
Input: CX:BX ...
amount for add operation. 32 bits signed integer.
Output: DX:AX ...
normalized result far pointer.
Output: far ptr [DX:AX] ... normalized result far pointer.
PINA
Input: ES:BX
... far pointer to your far pointer variable.
Input: far ptr [ES:BX] ... your far pointer variable.
Input: AX ... amount to increment. 16 bits unsigned integer.
Output: ES:BX ...
result far pointer before increment operation.
Output: far ptr [ES:BX] ... result far pointer variable storing after increment
operation.
Useful for post-increment pointer operation.
A short summary how the problems were repaired.
* fix: fix wrong wall rendering.
(Fixed in A.cpp:ver 163) My own procedure contained an error. Some of picture transfer routines are not ported from fire.exe due to save conversion time, I wrote alternative equivalent code instead.
|
* fix: sometimes floor renders wrong.
(Fixed in A.cpp:ver 164) The code was mis-ported. And the mis-calculation of floor image's height caused. The floor image was truncated in vertical direction. |
* fix: eliminate :P icon on wall
rendering. (Fixed in A.cpp:ver 165) The code was mis-ported. The wrong wall id was selected about distance 4 wall. |
* fix: in the inventory player name won't
be rendered. (Fixed in A.cpp:ver 166) I noticed that I have forgotten to port the code. |
* fix: creature won't do half step moving.
(Fixed in A.cpp:ver 167) The code was mis-ported. The variable "si" was uninitialized. |
* fix: flying missile disappears from
screen if it is in some tile position N or E. (Fixed in A.cpp:ver
168) * fix: item cannot be picked up. The code was mis-ported in some parts. |
* fix: you throw, and hit wall, then it
drops at wrong position. (Fixed in A.cpp:ver 169) * fix: throw item goes wrong side. The code was mis-ported. The variable si means whether you throw or not (0 means "not thrown", 1 means "thrown"). The si is initialized to 0. Thus you always throw by left hand. Also mis-ported. It caused falling the item down at wrong floor position. |
* fix: missile explosion won't appear.
(Fixed in A.cpp:ver 170) The code was mis-ported. The explosion power became 0 on left code. It caused no effect sound. The rectangle of explosion image left uninitialized. |
* fix: sleep device causes assertion on
activation. (Fixed in A.cpp:ver 171) The code was mis-ported. The summarization routine took wrong information for painting wall. |
* fix: minion map hides objects on certain
player dir. (Fixed in A.cpp:ver 172) The code was mis-ported. I don't understand what was caused. |
* fix: get unstable after minion is
released. * fix: every door's button is invisible and non-pushable. * fix: you acquire eye of time other than torch when you take wall touch. * fix: the wall window frame disappears. * fix: the wall window curtain won't wave. * fix: even floating creature can fall down the pit. * fix: every creature acts as pit ghost. * fix: the boulder is always rotatable but movable. * fix: the table duplicates itself when it is moved by player. * fix: the table drops someone's remain instead of plank when it is broken. * fix: the key vanishes when you insert it to key hole. * fix: sun crest holder vanishes when you hang it up at wall. * fix: get halted if you see room's window. * fix: you stand at wrong direction when you enter map boundary. * fix: the screen messed up when it begins rain. * fix: spell cast fails so much more than expected times. * fix: door decoration causes assertion when you see it. * fix: teleporter ignores direction settings. * fix: cross scene actuator causes assertion when you see it. * imp: extra option to disable player's half step moving. * fix: the cursor hides permanently when you eat something. * fix: shop panel is broken and exhibits non merchandice items. * imp: port startup program anim. * fix: the outside looks wrong when it begins to rain. Not yet. |
I often want to write meaningless topic.
Accidentally I started to have interests to port a version of Ultima Underworld which works with PC-9821 machine.
DM2 PS/V version uses Real mode of Intel CPU. UW uses Protected mode. It says programming style to absorb hardware dependency is completely different. But I felt I have to consider the Real mode style.
It is interested in the programming technique to absorb hardware's difference.
Usually the function table is prepared to define abstract layer to access hardware.
I researched the table example of DM2 PS/V version. Here is an interpretation of function table. IBMIO supplies these functions to FIRE.
Offset | Purpose or meaning of function | Target peripheral | (My working memo) |
---|---|---|---|
0x00 |
? Print system error message | ? | _476d_05e3 |
0x0C |
Set listener for mouse event | Mouse | _443c_0380 |
0x10 |
Freeze mouse event | Mouse | _443c_087c |
0x14 |
Unfreeze mouse event | Mouse | _443c_0889 |
0x18 |
Capture and lock mouse cursor position | Mouse | FIRE_MOUSE_SET_CAPTURE |
0x1C |
Release and uock mouse cursor position | Mouse | FIRE_MOUSE_RELEASE_CAPTURE |
0x20 |
Show mouse cursor | Mouse | FIRE_SHOW_MOUSE_CURSOR |
0x24 |
Hide mouse cursor | Mouse | FIRE_HIDE_MOUSE_CURSOR |
0x28 |
Modify shape of mouse cursor | Mouse | IBMIO_SET_CURSOR_PATTERN |
0x2C |
? | ? | |
0x30 |
? Update mouse cursor position | Mouse | _443c_040e |
0x38 |
Retrieve mouse status | Mouse | |
0x44 |
Wait while sound card is busy | Sound card | _47eb_02d3 |
0x74 |
Play a sound noize | Sound card | _47eb_02c3 |
0x98 |
? Memory copy | ? | COPY_MEMORY |
0xA0 |
Get path from drive number | ? | _476d_04f4 |