/* * This is a reverse engineering I did of Keen 1 using DosBox. * * I patched the x86 processor emulator to call do_keen_checks() * all the way down the bottom of this file. It would "simulate" * the execution of a particular function at a given address by * calling the C translation, many of which were given descriptive * names. * * Many memory addresses in the data segment are used directly * and these were also given descriptive names. * * Thanks to John Carmack and the rest of Id Software for making * a great game and doing some neat tricks in this code. * * QuantumG, circa 2008. * */ #include #include #include #include "dosbox.h" #include "mem.h" #include "cpu.h" #include "inout.h" #include "callback.h" #include "pic.h" #include "fpu.h" #include "paging.h" bool trace = false; typedef void func(); #define MAX_RET_LOCS 1024 struct { Bit16u addr; func *func; } retlocs[MAX_RET_LOCS]; int num_retlocs = 0; #define PUSH(n) { reg_esp -= 2; mem_writew(SegPhys(ss) + reg_sp, (Bit16u)(reg_##n & 0xffff)); } #define PUSHI(n) { reg_esp -= 2; mem_writew(SegPhys(ss) + reg_sp, (Bit16u)((n) & 0xffff)); } #define POP(n) { reg_##n = mem_readw(SegPhys(ss) + reg_sp); reg_sp += 2; } #define MOV(d, s) reg_##d = reg_##s #define MEMW(n) mem_readw(SegPhys(ds) + (n)) #define W_MEMW(n, v) mem_writew(SegPhys(ds) + (n), v) #define MEMB(n) mem_readb(SegPhys(ds) + (n)) #define W_MEMB(n, v) mem_writeb(SegPhys(ds) + (n), v) #define MEMD(n) mem_readd(SegPhys(ds) + (n)) #define W_MEMD(n, v) mem_writed(SegPhys(ds) + (n), v) unsigned int TOPHYS(unsigned int n) { int nh = n >> 16; int nl = n & 0xffff; return nh * 16 + nl; } unsigned int N_PADD(unsigned int n, int a) { int nh = n >> 16; int nl = n & 0xffff; int nn = nh * 16 + nl; nn += a; nh = nn >> 4; nl = nn & 0xf; return (nh << 16) | nl; } #define RET { reg_eip = mem_readw(SegPhys(ss) + reg_sp); reg_sp += 2; return; } //#define CALL(x, ra) { int tmp_eip = reg_eip; PUSHI(0xf00d); x(); assert(reg_eip == tmp_eip); } #define RETLOC(n) if (reg_eip == 0x##n) goto retloc_##n #define EMU_CALL(d, ra, f) \ if (num_retlocs >= MAX_RET_LOCS) { printf("out of retlocs\n"); } \ else { retlocs[num_retlocs].addr = 0x##ra; retlocs[num_retlocs].func = f; num_retlocs++; \ PUSHI(0x##ra); \ reg_eip = d; \ return; \ } \ retloc_##ra: #define EMU_INSTR(da, ra, f) \ if (num_retlocs >= MAX_RET_LOCS) { printf("out of retlocs\n"); } \ else { retlocs[num_retlocs].addr = 0x##ra; retlocs[num_retlocs].func = f; num_retlocs++; \ reg_eip = 0x##da; \ return; \ } \ retloc_##ra: #define tick_count 0x5135 #define sound_data_hi 0x5141 #define sound_limiter 0x514C #define cur_sound_pos 0x514A #define sound_disabled 0x5151 #define rnd 0x5157 #define rnd_vals 0x5159 #define word_182A9 0x5259 // seems to count down by two every yorp/vorticon jump, then goes back to 22 #define word_182AB 0x525B // ditto, but seems to be 0A greater than 5259 #define word_182AD 0x525D // also changed during sprite jumps (not keen) #define dword_1869A 0x564A #define dword_1869E 0x564E #define sprite_sync 0x5B14 #define dword_18DFC 0x5DAC #define dword_18E00 0x5DB0 #define map_width_intiles 0x6C08 #define map_width_intiles_x2 0x6C06 #define map_height_in_tiles 0x6C58 #define tile_data_1 0x6C48 #define sprite_copy.type 0x8220 #define sprite_copy.active 0x8222 #define sprite_copy.pos_x_lo 0x8224 #define sprite_copy.pos_x_hi 0x8226 #define sprite_copy.pos_y_lo 0x8228 #define sprite_copy.pos_y_hi 0x822A #define sprite_copy.box_left_x 0x822c #define sprite_copy.box_top_y 0x8230 #define sprite_copy.box_right_x 0x8234 #define sprite_copy.box_bottom_y 0x8238 #define sprite_copy.delta_x 0x823C #define sprite_copy.delta_y 0x823E #define sprite_copy.vel_x 0x8240 #define sprite_copy.vel_y 0x8242 //need to define 0x8244 as sprite strength #define sprite_copy.frame_var2 0x8246 #define sprite_copy.cur_frame 0x8248 #define sprite_copy.sync_time 0x824a #define sprite_copy.frame_countdown 0x824C #define sprite_copy.unk_w_1 0x824E #define sprite_copy.unk_w_2 0x8250 #define sprite_copy.think_func 0x8252 #define sprite_copy.contact_func 0x8254 #define sprite_array_offset 0x6EDA //note that this is also the type of the first sprite (i.e. keen, type = 1) #define keen_active 0x6EDC //first sprite active (i.e. keen, so value = 1) #define keen_pos_x 0x6EDE #define keen_pos_y 0x6EE2 #define keen_box_left_x 0x6EE6 #define keen_box_right_x 0x6EEE #define keen_box_top_y 0x6EEA #define keen_box_bottom_y 0x6EF2 #define keen_delta_x 0x6EF6 #define keen_delta_y 0x6EF8 #define keen_vel_x 0x6EFA #define keen_vel_y 0x6EFC //keen_strength? 0x6EFE //keen_frame_var2 0x6F00 #define keen_cur_frame 0x6F02 #define keen_sync_time 0x6F04 #define keen_frame_countdown 0x6F06 //keen_unk_w_1 0x6f08 //keen_unk_w_2 0x6f0a #define keen_think_func 0x6F0C #define keen_contact_func 0x6F0E #define scroll_x_lo 0x6ED0 #define scroll_x_hi 0x6ED2 #define scroll_y_lo 0x6ED4 #define scroll_y_hi 0x6ED6 #define dword_1B00E 0x7FBE #define dword_1B012 0x7FC2 #define monsters 0x6F10 //pointer to sprite array + 1 (right after keen) #define num_monsters 0x5DB4 #define word_1B2A8 0x8258 #define got_part_1 0xAA94 #define got_part_2 0xAA9C #define got_part_3 0xAA96 #define got_part_4 0xAA98 #define ray_gun_charge 0xAAC8 #define got_pogo 0xAA9A #define current_level 0x8304 #define current_tile_x 0x8218 #define current_tile_y 0x821A #define level_finished 0x6C60 //0 = not finished (ie died), 1 = finished, 2 = exit via teleport #define tile_kind_tbl 0x056e #define aLevel0 0x1D4C #define aLevel 0x1D53 #define aDot 0x1D59 #define pExt 0x2506 #define level_data 0x6EC8 //far pointer to level tiles #define word_186A4 0x5654 #define background_width 0x5642 #define background_height 0x5646 #define bodies 0x7FD6 #define num_bodies 0x8216 #define word_13A84 0x0A34 #define word_1909C 0x604C #define input.direction 0x7FCA #define input.jump 0x7FCC #define input.pogo 0x7FCE #define input_old.direction 0x7FD0 // these three appear to be the input from the previous frame #define input_old.jump 0x7FD2 #define input_old.pogo 0x7FD4 #define sc_up 0x82EA #define sc_pgup 0x82EB #define sc_right 0x82EC #define sc_pgdn 0x82ED #define sc_down 0x82EE #define sc_end 0x82EF #define sc_left 0x82F0 #define sc_home 0x82F1 #define sc_ctrl 0x8284 #define sc_alt 0x8285 #define key_map 0x502c #define word_1C782 0x9732 //controls #define word_1B3B2 0x8362 #define word_1B38C 0x833C #define byte_180AA 0x505A //cheat keys #define byte_18090 0x5040 #define byte_180B5 0x5065 #define byte_1809E 0x504E #define byte_18094 0x5044 #define byte_1809C 0x504C #define god_mode 0x5DAA #define aGodModeEnabled 0x1EA6 #define aGodModeDisabled 0x1EB7 #define key_scan 0x50AC #define key_code 0x50AE #define aSoundYN 0x1D91 #define byte_1D732 0xA6E2 #define want_sound 0x5143 #define word_186B0 0x5660 #define word_186A2 0x5652 #define sprite_scratch_back 0x5DB6 #define word_18B66 0x5B16 #define word_18E08 0x5DB8 #define overdraw_draw_guard 0x6ED8 #define filter_draw_guard 0x6ECC #define sprite_draw_guard 0x6EBE #define sprite_scratch_data 0x6EC6 #define word_1909E 0x604E #define sprite_scratch_na 0x6ECE #define word_19C5A 0x6C0A #define sprite_scratch_overdraw 0x7FBA #define word_19CB4 0x6C64 #define tick_count_2 0x563E #define word_1B356 0x8306 #define sprite_data 0x834E #define word_1B35E 0x830E #define word_1B362 0x8312 #define word_1B360 0x8310 #define word_1B364 0x8314 #define word_1B346 0x82F6 #define dword_1B2AA 0x825A #define word_13050 0x0000 #define dword_1B342 0x82F2 #define word_1C74A 0x96FA #define dword_1D726 0xA6D6 #define dword_1B2B6 0x8266 #define aErrorDuringCodeExp 0x2853 #define word_186A6 0x5656 #define word_18B62 0x5B12 #define word_1B358 0x8308 #define draw_func 0x5658 #define trans_map 0x50B0 #define value 0xAACA #define dword_19F12 0x6EC2 #define num_keens_left 0xAAC6 #define word_1D740 0xA6F0 #define tile_data_sprites 0x6C4C #define word_C139 0xC139 #define word_C163 0xC163 #define word_C160 0xC160 #define word_C166 0xC166 #define unk_C15D 0xC15D #define byte_C163 0xC163 #define byte_C160 0xC160 #define byte_C166 0xC166 #define dword_1D72E 0xA6DE #define aOutOfMemoryTryUnlo 0x278F #define word_16606 0x35B6 #define word_19CB2 0x6C62 #define word_1804C 0x4FFC #define word_1660E 0x35BE #define dstseg 0x35B4 #define word_16602 0x35B2 #define word_190A2 0x6052 #define word_19CB8 0x6C68 #define word_190A0 0x6050 #define word_19CB6 0x6C66 #define word_19C5E 0x6C0E #define word_19C5C 0x6C0C #define ega_regen_start_addr 0x35BA #define ega_colors 0x35B8 #define int8_divider 0x5149 #define pass_keys_to_bios 0x5026 #define word_1685C 0x380C #define sprite_dst_lo 0x5022 #define sprite_data 0x834E #define sprite_pixel_count 0x5018 #define sprite_mask_src_lo 0x501A #define blit_funcs 0x5004 #define draw_sprite_func 0x5016 #define word_18074 0x5024 #define word_1806E 0x501E #define sprite_mask_hi 0x82E8 #define sprite_src_hi_1 0x82E0 #define sprite_src_hi_2 0x82E2 #define sprite_src_hi_3 0x82E4 #define sprite_src_hi_4 0x82E6 #define aCk1 0x1EC9 #define aLoadingCommand 0x1ECD #define aJoystickDetect 0x1F05 #define Joystick_Detect 0x5B10 #define aJoystickNotDet 0x1F17 #define aKeystrokesWill 0x1F2D #define video_cap 0x9730 #define aEgaCardDetecte 0x1F53 #define aVgaCardDetecte 0x1F65 #define aHeyIDonTSeeAnE 0x1F77 #define aAnywayYGoAhead 0x1FC2 #define aDecompressingGraph 0x1FEB #define EGAHEAD_TileNum 0x8352 // #define tileinfo_start 0x00A8 #define anim_frame_tiles_4 0x4A84 #define anim_frame_tiles_3 0x450C #define anim_frame_tiles_2 0x3F94 #define anim_frame_tiles_1 0x3A1C #define aSounds_ 0x201E #define unk_1B2E0 0x8290 #define word_1818F 0x513F #define word_1B016 0x7FC6 #define word_1B00C 0x7FBC #define ctrl_type 0x833E #define word_1551E 0x24CE #define aOops_ 0x2444 #define toggle_lights 0x821E #define word_1B02E 0x7FDE #define word_148D6 0x1886 #define word_1B048 0x7FF8 #define word_1B02A 0x7FDA #define word_1B02C 0x7FDC #define word_1B028 0x7FD8 #define segx 0x008E #define last_seg 0x53D6 #define end_bss_seg 0x00A6 #define end_bss_off 0x00A4 #define last_extend_lo 0x00A0 #define last_extend_hi 0x00A2 #define aDivideError 0x0046 #define orig_int0_off 0x0072 #define orig_int0_seg 0x0074 #define orig_int4_off 0x0076 #define orig_int4_seg 0x0078 #define orig_int5_off 0x007A #define orig_int5_seg 0x007C #define orig_int6_off 0x007E #define orig_int6_seg 0x0080 #define aQuitYN 0x1D5B #define unk_14DB7 0x1D67 #define aQuitToDOsOr 0x1D68 #define aTItle 0x1D7A #define unk_14DD3 0x1D83 #define quit_to_title 0x6EBC #define word_15520 0x24D0 #define word_1B348 0x82F8 #define word_1B3A4 0x8354 #define word_1B2D2 0x8282 #define EGAHEAD_font_seg 0x8300 #define word_1B3A8 0x8358 #define word_1B3AE 0x835E #define word_1B3AA 0x835A #define word_1B3B0 0x8360 #define start_bss_off 0x009C #define word_13056 0x0006 #define dword_1B378 0x8328 #define word_1B398 0x8348 #define byte_1C784 0x9734 #define unk_1C785 0x9735 #define word_1B376 0x8326 #define EGAHEAD_Bmpdatastart_seg 0x8366 #define word_B8DA 0xB8DA #define word_B8DE 0xB8DE #define word_B8DC 0xB8DC #define EGAHEAD_Bmploc_seg 0x834C #define unk_182AF 0x525F #define unk_182D1 0x5281 #define word_182CF 0x527F #define word_182B7 0x5267 #define word_1D748 0xA6F8 #define aOutOfMemoryTryUn_0 0x27D8 #define word_1B3AC 0x835C #define word_1B3A6 0x8356 #define aOutOfMemoryTryUn_1 0x2801 #define aOutOfMemoryTryUn_2 0x282A #define byte_15558 0x2508 #define byte_15569 0x2519 #define byte_1558B 0x253B #define byte_1557A 0x252A #define aMissingATextFile 0x359D #define word_1DADE 0xAA8E #define word_1DB2E 0xAADE #define got_yellow_keycard 0xAA9E #define got_red_keycard 0xAAA0 #define got_green_keycard 0xAAA2 #define got_blue_keycard 0xAAA4 #define word_1DAF6 0xAAA6 #define word_158FC 0x28AC #define dword_1DB44 0xAAF4 #define dword_1DB48 0xAAF8 #define aNewGame 0x2E96 #define aContinueGame 0x2EA3 #define aStory 0x2EB5 #define aAboutId___ 0x2EBF #define aHighScores 0x2ECF #define aOrderingInfo 0x2EDF #define aPreviews 0x2EF1 #define aRestartDemo 0x2EFF #define aUseThe 0x2F11 #define aArrows 0x2F1A #define aMouse 0x2F21 #define aJoystick 0x2F27 #define aKeensLeft 0x2E88 #define saved_sound_pos 0x514D #define saved_sound_limiter 0x514F #define saved_int8_divider 0x5150 #define EGAHEAD_Tileloc_seg 0x836A #define word_13F4A 0x0EFA #define word_1D75E 0xA70E #define story_text 0xA70A #define word_130E2 0x0092 #define word_1DACA 0xAA7A #define orig_int9_off 0x5028 #define orig_int9_seg 0x502A #define word_1B2A6 0x8256 #define int8_set 0x513D #define orig_int8_off 0x5145 #define orig_int8_seg 0x5147 #define a_gapics_ 0x254C #define aEgahead_ 0x2871 #define EGAHEAD_FontNum 0x836E #define EGAHEAD_BmpNum 0x8342 #define EGAHEAD_SpriteNum 0x972E #define aEgalatch_ 0x287A #define EGAHEAD_font_off 0x82FE #define EGAHEAD_Tileloc_off 0x8368 #define EGAHEAD_Bmploc_off 0x834A #define EGAHEAD_Bmpdatastart_off 0x8364 #define dword_1D72A 0xA6DA #define aEgasprit_ 0x2884 #define dword_1B2AE 0x825E #define unk_1DC1A 0xABCA #define word_1DC38 0xABE8 #define dword_1DC32 0xABE2 #define dword_1DC2A 0xABDA #define dword_1DC26 0xABD6 #define dword_1DC2E 0xABDE #define word_1D738 0xA6E8 #define word_14410 0x13C0 #define word_1DC36 0xABE6 #define cur_level 0x6EC0 #define byte_1808B 0x503B #define byte_180A6 0x5056 #define aYourShipIsMissingT 0x354B #define aGoGetThem 0x3572 #define aPressA 0x3584 #define aKey 0x3590 #define aButton 0x3595 #define word_158E6 0x2896 #define dword_158DE 0x288E #define dword_1D74A 0xA6FA #define dword_158E2 0x2892 #define dword_1D74E 0xA6FE #define dword_1DB22 0xAAD2 #define dword_1DB1E 0xAACE #define dword_1DB26 0xAAD6 #define dword_1DB2A 0xAADA #define dword_1D752 0xA702 #define dword_1D756 0xA706 #define word_1D760 0xA710 #define word_1D762 0xA712 #define on_world_map 0xAAFC #define aScores_ 0x28E2 #define aYorpy 0x28EF #define aStorytxt_ 0x28C8 #define aEndtext_ 0x28BB #define aPreviews_ 0x28D5 #define aHelptext_ 0x28AE #define help_text 0xAA90 #define end_text 0xAAF0 #define previews_text 0xA6E4 #define dword_1DB4E 0xAAFE #define word_1DBB0 0xAB60 #define word_1DBA2 0xAB52 #define unk_1DBBE 0xAB6E #define word_1DB6A 0xAB1A #define word_1DB78 0xAB28 #define word_1DB94 0xAB44 #define word_1DB86 0xAB36 #define unk_19EF4 0x6EA4 #define word_185B6 0x5566 #define byte_185B8 0x5568 #define aCtlpanel_ 0x27C4 #define word_1B390 0x8340 #define word_1B2BE 0x826E #define word_1B2BC 0x826C #define word_1B2C4 0x8274 #define word_1B2C2 0x8272 #define word_1B2CA 0x827A #define word_1B2C8 0x8278 #define word_1B2D0 0x8280 #define word_1B2CE 0x827E #define word_1B3BC 0x836C #define word_1B2BA 0x826A #define word_1B2C6 0x8276 #define word_1B2C0 0x8270 #define word_1B2CC 0x827C #define aWeAreAGroupOfSoftw 0x2F30 #define a0_0 0x3102 #define unk_16156 0x3106 #define unk_1615E 0x310E #define aCommanderKeenInvas 0x32DC #define aOfTheVorticonsCons 0x32F6 #define aOfThreeUniqueAnd 0x3311 #define aChallengingEpisode 0x3329 #define a1_MaroonedOnMars15 0x3342 #define a2_TheEarthExplodes 0x335D #define a3_KeenMustDie15 0x3378 #define aOrderTheTrilogyFor 0x3393 #define aTheSecretHintsTric 0x33BB #define aTheSpecialCheatMod 0x33E2 #define aTheLatestVersionOf 0x3409 #define aSeveralFreeBonusGa 0x342E #define aMailOrdersTo 0x344E #define aU_s_FundsOnlyApoge 0x3476 #define aChecksOrMOSP_o_Box 0x349E #define aInclude2PHGarlandT 0x34C6 #define aSpecify5_253_5Disk 0x34F2 #define aOrOrderTollFree180 0x351C #define aSaved__0 0x30F5 #define aContinueWhichGame 0x3230 #define a19OrEsc_0 0x3248 #define aThatGameHasnT 0x325B #define aBeenSavedYet 0x326F #define aThatFileIsIncompat 0x3282 #define aWithThisVerionOfCk 0x329D #define aYouHearInYour 0x2030 #define aMind 0x2046 #define asc_150AC 0x205C #define aItIsTooBadThat 0x2072 #define aYouCannotReadThe 0x2088 #define aStandardGalactic 0x209E #define aAlphabetHuman_ 0x20B4 #define aAMessageEchoesIn 0x20CA #define aYourHead 0x20E0 #define asc_15146 0x20F6 #define aTheTeleporterIn 0x210C #define aTheIceWillSend 0x2122 #define aYouToTheDarkSide 0x2138 #define aOfMars_ 0x214E #define aAVoiceBuzzesIn 0x2164 #define aYourMind 0x217A #define asc_151E0 0x2190 #define aThereIsAHidden 0x21A6 #define aCity_LookInThe 0x21BC #define aDarkAreaOfThe 0x21D2 #define aCityToTheSouth_ 0x21E8 #define aYouSeeTheseWords 0x21FE #define aInYourHead 0x2214 #define asc_1527A 0x222A #define aYouWillNeedA 0x2240 #define aRaygunInTheEnd 0x2256 #define aButNotToShootThe 0x226C #define aVorticon___ 0x2282 #define aYouHearInYour_0 0x2298 #define aMind_0 0x22AE #define asc_15314 0x22C4 #define aGaaarrrrrgg 0x22DA #define aAYorpishWhisper 0x22F0 #define aSays 0x2306 #define asc_1536C 0x231C #define aLookForDarkHidden 0x2332 #define aBricks_YouCanSee 0x2349 #define aNaughtButTheir 0x235F #define aUpperLeftCorner_ 0x2375 #define aAYorpyMindThought 0x238B #define aBellows 0x23A1 #define asc_15407 0x23B7 #define aYouCannotKillThe 0x23CD #define aVorticonCommander 0x23E3 #define aDirectly_ 0x23F9 #define aPressEnter 0x240F #define aScoreExtraKeenAt 0x1E02 #define asc_14E70 0x1E20 #define aKeensShipParts 0x1E23 #define asc_14E91 0x1E41 #define asc_14E94 0x1E44 #define asc_14E97 0x1E47 #define aRaygunPogoKeycards 0x1E4A #define asc_14EB8 0x1E68 #define asc_14EBA 0x1E6A #define asc_14EBD 0x1E6D #define asc_14EBF 0x1E6F #define asc_14EC2 0x1E72 #define asc_14EC4 0x1E74 #define aCharge 0x1E77 #define asc_14ED1 0x1E81 #define asc_14ED4 0x1E84 #define asc_14ED6 0x1E86 #define aPleasePressAKey 0x1E89 #define aPreview2_ck1 0x3116 #define aPreview3_ck1 0x3123 #define word_18309 0x52B9 #define word_18305 0x52B5 #define word_1830B 0x52BB #define word_18307 0x52B7 #define dword_1830D 0x52BD #define word_18315 0x52C5 #define word_18318 0x52C8 #define word_18311 0x52C1 #define word_18313 0x52C3 #define word_1D746 0xA6F6 #define word_1D742 0xA6F2 #define word_1D744 0xA6F4 #define word_1D73A 0xA6EA #define dword_1D73C 0xA6EC #define unk_1D7BE 0xA76E #define byte_180C4 0x5074 #define byte_180CC 0x507C #define unk_1D7BA 0xA76A #define byte_180C5 0x5075 #define byte_180CD 0x507D #define byte_1807D 0x502D #define byte_1831F 0x52CF #define aSaved__ 0x30E8 #define aYouCanSaveTheGame 0x3130 #define aOnlyOnTheWorldMap 0x3147 #define aPressAKey 0x315F #define aWhichGamePosition 0x3170 #define aDoYouWantToSave_ 0x3185 #define a19OrEsc 0x319B #define aThatGamePosition 0x31AB #define aAlreadyExists 0x31BF #define aOverwriteIt_ 0x31D0 #define aYouCanContinueThis 0x31DF #define aFromTheMainMenuNex 0x31FB #define aYouPlay_PressAKey 0x3219 #define aScores__0 0x2AB6 #define aFirst 0x2AC3 #define aScore 0x2E36 #define aCongratulations 0x2E46 #define aYouGot 0x2E5F #define aPlaceEnterYourName 0x2E6D #define word_1DB3E 0xAAEE #define dword_1DB52 0xAB02 #define word_1DBA4 0xAB54 #define word_1DBB2 0xAB62 #define word_1DB6C 0xAB1C #define word_1DB7A 0xAB2A #define word_1DB96 0xAB46 #define word_1DB88 0xAB38 #define unk_1DBCB 0xAB7B #define aEsc 0x2619 #define aBksp 0x261D #define aTab 0x2622 #define aCtrl 0x2626 #define aLshift 0x262B #define aSpace 0x2632 #define aCapslk 0x2638 #define aF 0x263F #define aF11 0x2641 #define aF12 0x2645 #define aScrllk 0x2649 #define aEnter 0x2650 #define aRshift 0x2656 #define aPrtsc 0x265D #define aAlt 0x2663 #define aHome 0x2667 #define aPgup 0x266C #define aEnd 0x2671 #define aPgdn 0x2675 #define aIns 0x267A #define aDel 0x267E #define aNumlk 0x2682 #define char_map 0x244E #define aKeyboardCommands 0x2688 #define asc_156EB 0x269B #define a0North 0x26AD #define a1Northeast 0x26BB #define a2East 0x26C9 #define a3Southeast 0x26D7 #define a4South 0x26E5 #define a5Southwest 0x26F3 #define a6West 0x2701 #define a7Northwest 0x270F #define a8Button1 0x271D #define a9Button2 0x272B #define aModifyWhichAction 0x2739 #define aPressTheNewKey 0x274F #define asc_157B4 0x2764 #define asc_157C8 0x2778 #define aJoystickConfigurat 0x2559 #define asc_155C4 0x2574 #define aHoldTheJoystickInT 0x258F #define aUpperLeft 0x25AA #define aCornerAndPressButt 0x25B7 #define aHoldTheJoystickI_0 0x25D2 #define aLowerRight 0x25F0 #define aCornerAndPressBu_0 0x25FE #define aYouAreNowCheating 0x1D9E #define aYouJustGotAPogoSti 0x1DB5 #define aAllTheKeyCardsAnd 0x1DD1 #define aLotsOfRayGunCharge 0x1DE9 #define aCtlpanel__0 0x27CE #define unk_1597E 0x292E #define unk_159BA 0x296A #define unk_15A66 0x2A16 #define aCommanderKeenRetur 0x2BD4 #define aWithBaconMegarocke 0x2BF9 #define aReplacesTheMissing 0x2C1C #define aGetHomeBeforeHisPa 0x2C41 #define aFinale_ck1 0x2C62 #define aKeenMakesItHomeAnd 0x2C6D #define aRushesToBeatHis 0x2C85 #define aParentsUpstairs_ 0x2C99 #define aShhhHoney___letS 0x2CAB #define aSeeIfLittleBilly 0x2CC0 #define aIsAsleep_ 0x2CD5 #define aBilly____AreYouA 0x2CE0 #define aWhatIsThisOneEyed 0x2CF7 #define aGreenThingInYour 0x2D0E #define aRoom___ 0x2D23 #define aAwMomCanTI 0x2D30 #define aKeepHim_ 0x2D42 #define aWellWeLlTalkAbout 0x2D4C #define aThatInTheMorning 0x2D64 #define aSon_YouGetSomeRest 0x2D7A #define aOkMom_Goodnight_ 0x2D92 #define aGoodnightDear_ 0x2DA6 #define aButThereIsNoSleep 0x2DB7 #define aForCommanderKeenTh 0x2DCE #define aVorticonMothership 0x2DE7 #define aLoomsAboveReadyTo 0x2DFC #define aDestroyEarth 0x2E13 #define aToBeContinued____ 0x2E22 #define dword_158F2 0x28A2 #define dword_158F6 0x28A6 #define word_158FA 0x28AA #define aBadContactPointer 0x242F #define aBadThinkPointer 0x241C #define points_tbl 0x2026 #define a_think_yorp_look 0x19D3 #define a_think_12 0x489D #define a_think_contact_nop 0x3360 #define a_think_18 0x40EF #define a_think_17 0x41F8 #define a__memset 0xD439 #define a_default_think 0x2919 #define a_default_contact 0x2927 #define a_finish_cur_sound 0xbf7f #define a_sub_42AC 0x42ac #define a_kill_keen 0x4260 #define a_open_door 0x27F8 #define a_add_score 0x0D52 #define a_think_13 0x3867 #define a_show_message 0x24F4 #define a_think_yorp_walk 0x194F #define a_think_19 0x290E #define a_think_28_tankbot_move 0x1EA9 #define a_think_2 0x1DC7 #define a_think_11 0x47E8 #define a__itoa 0xD38A #define a__strcpy 0xD753 #define a__strcat 0xD71A #define a__open 0xD49E #define a__filelen 0xD15C #define a__close 0xC5AB #define a_map_file_to_mem 0x5CB8 #define a_init_background 0x7881 #define a_add_monster 0x2935 #define a_contact_6 0x22BB #define a_think_4_garg_look 0x1B51 #define a_contact_4 0x1BCE #define a_think_32 0x3B8B #define a_move_left_right 0x2B9A #define a_think_29 0x3C99 #define a_think_31 0x4054 #define a_think_33_fire_raygun 0x3E12 #define a_toggle_switch 0x35D2 #define a_think_30 0x3EC8 #define a_N_SCOPY 0xE29B #define a_get_mouse_ctrl 0x56DB #define a_get_joystick_ctrl 0x58AF #define a_start_cheating 0x0DB0 #define a_clear_keys 0x5C3A #define a_draw_box_opening2 0x60BE #define a_draw_string 0x62D2 #define a_read_char_with_echo 0x6268 #define a_clear_overlay 0xB736 #define a_save_cur_sound 0xBF44 #define a_show_pause_menu 0x0E3A #define a_restore_cur_sound 0xBF63 #define a_translate_key 0xBDCE #define a_handle_redef_keys 0x53C0 #define a_handle_joystick 0x4FA9 #define a_save_game 0x9AB4 #define a_handle_quit 0x082B #define a_do_help 0x9DB4 #define a_sub_CD36 0xCD36 #define a_sub_BF36 0xBF36 #define a_do_drawing 0xB750 #define a__printf 0xC935 #define a__exit 0xC5D7 #define a_draw_mural 0x97AB #define a_sync_drawing 0x239 #define a_draw_screen 0x0289 #define a_get_keyb_ctrl_state 0x55A3 #define a_check_ground 0x2C97 #define a_get_random 0xC0CE #define a_calc_jump_height 0xC05C #define a_do_fall 0x2C2A #define a_compute_sprite_delta 0x2C6D #define a_set_cur_sound 0xBEF3 #define a_check_ceiling 0x3365 #define a__LXMUL 0xE563 // multiplies longs dx:ax * cx:bx and stores result in dx:ax #define a_draw_filter 0xBAB6 #define a_delay 0xC0E2 #define a_draw_box_opening 0x611A #define a_draw_box 0x604E #define a_check_vid_mode 0xC297 #define a_alloc_mem 0xDEE4 #define a_chg_vid_and_error 0x1261 #define a_sub_B87C 0xB87C #define a_sub_103C0 0x11D00 #define a_sub_E70D 0x1004D #define a_draw_sprite 0xBB2D #define a_do_overdraw 0xB939 #define a_stop_cur_sound 0xBF2A #define a_puts 0xCBAE #define a_poll_joystick 0x5811 #define a_detect_video 0xC169 #define a_decomp_graphics 0x6CE6 #define a_alloc_and_map_file 0x5DE4 #define a_init_rnd 0xC0AC #define a_sub_C013 0xC013 #define a_setup_int8 0xBE65 #define a_setup_int9 0xBD95 #define a_init_ctrls 0x665D #define a_sub_5C58 0x5C58 #define a_main_loop 0x7913 #define a_draw_sprite_at 0x2C5 #define a_add_body 0x297E #define a_bridge_extend 0x4A8B #define a_bridge_retract 0x4AFA #define a_lights_on 0x3592 #define a_lights_out 0x35B2 #define a__setblock 0xD6FE #define a_int0_handler 0x015C #define a_int8_handler 0xBF97 #define a_draw_box2 0x5F1E #define a_draw_char 0xB8E0 #define a_contact_5_yorp 0x1A68 #define a__filelength 0xD15C #define a__strlen 0xD777 #define a_extend_bss 0xC5FA #define a_sub_6BD4 0x6BD4 #define a_sub_6B62 0x6B62 #define a_show_logo_text 0xA1EB #define a_sub_A1D4 0xA1D4 #define a_handle_ctrl 0x5A39 #define a__read 0xD62F #define a_sub_6A30 0x6A30 #define a_sub_DDFE 0xDDFE #define a__movedata 0xD451 #define a_load_level_data 0x066B #define a_fade_in 0x6C49 #define a_scroll_up_logo 0xA262 #define a_fade_out 0x6C8D #define a_handle_global_keys 0x0C51 #define a_do_draw_mural 0x97D3 #define a_do_about_us 0x984C #define a_do_scores 0x9A24 #define a_show_ordering_info 0xA566 #define a_do_ordering_info 0xA33B #define a_draw_title 0x928F #define a_draw_menu 0x95FD #define a_sub_614B 0x614B #define a_draw_ordering_info 0xA497 #define a_think_34 0x488E #define a_think_20_yorp_incapacitated 0x1A2C #define a_think_14 0x26FE #define a_add_monster_8 0x46BA #define a_think_9_raygun_flight 0x4808 #define a_contact_9_raygun 0x4849 #define a___chmod 0xCF6D #define a_think_22_garg_move 0x1AA8 #define a_contact_2 0x1E94 #define a_add_monster_5 0x1880 #define a_add_monster_4 0x1843 #define a_add_monster_2 0x1777 #define a_add_monster_1_tank_bot 0x1713 #define a_add_monster_6 0x18E3 #define a_add_special_body 0x1920 #define a_int9_handler 0xBE1A #define a_think_25 0x1E5E #define a_decomp_file 0x6884 #define a_vga_regplane_select 0xc104 #define a__outportb 0xD623 #define a__outport 0xD617 #define a_detect_worldmap_col 0x2AE9 #define a_check_world_map_col 0xA616 #define a_draw_game 0xAE1C #define a_wait_for_key 0xB185 #define a_handle_global_keys 0x0C51 #define a_handle_cheat_keys 0x11F0 #define a_sub_8F90 0x8f90 #define a_mark_cities_done 0x805E #define a_game_over 0x8ADF #define a_show_keens_left 0x8F26 #define a_N_SPUSH 0xE2BA #define a_move_worldmap 0xAA95 #define a_draw_level 0x4B69 #define a_handle_secret_city 0x8919 #define a_draw_win 0x818C #define a_start_menu 0x96B0 #define a_continue_game 0x9C4E #define a_do_story 0x9D73 #define a_show_about_us 0x9732 #define a_show_scores 0x9A59 #define a_do_previews 0x96E2 #define a_process_text_file 0xB364 #define a_sub_7ABB 0x7abb #define a__harderr 0xD1F5 #define a_sub_C552 0xC552 #define a_write_file 0x5D63 #define a_do_intro_and_menu 0x8FF0 #define a_draw_worldmap 0x7C04 #define a_think_16 0x45C4 #define a_init_level 0x15EB #define a_do_scrolling 0x3418 #define a_detect_mnstr_col 0x29BD #define a_sub_2A3B 0x2A3B #define a_sprite_active_screen 0x3296 #define a_detect_background_col() 0x42EA #define a__inportb 0xD264 #define a__outportb 0xD623 #define a_slide_sprite 0x0501 #define a_draw_invvid_string 0xA5BC #define a_draw_about_us 0x97F0 #define a_draw_scores 0x986C #define a__ltoa 0xD3CB #define a_pogo_jump 0x2BDF #define a_slide_door 0x273D #define a_think_1_tankbot_def 0x1F75 #define a_contact_nop 0x2045 #define a_think_26_tankbot_shoot 0x1FC1 #define a_think_27_tankbot_turn 0x1F8F #define a_add_monster_9_tank_shot 0x48DE #define a_contact_10 0x4A00 #define a_get_file_length 0x636B #define a_draw_stringz 0x6476 #define a_draw_number 0x632A #define a_sub_C513 0xC513 #define a_show_image_file 0x983 #define a_do_text_viewer 0x9FB2 #define a_sub_C35F 0xC35F #define a_sub_C2D5 0xC2D5 #define a_sub_9E32 0x9E32 #define a_sub_B243 0xB243 #define a_sub_608C 0x608C #define a_draw_text_page 0xB4DF #define a_sub_9E6D 0x9E6D #define a_scroll_text 0xB640 #define a_get_string_input 0x65B7 #define a_draw_keyname 0x51FA #define a__inportb 0xD264 #define a_save_ctrls 0x67A9 #define a_restore_int9 0xBDB0 #define a_restore_int8 0xBEB7 #define a__gotoxy 0xC8E5 #define a_sub_CD62 0xCD62 #define a_draw_stringz2 0x8150 #define a_sub_8132 0x8132 #define a_add_monster_7 0x20CB #define a_think_15 0x204A #define a_think_7 0x2192 #define a_contact_7 0x22A6 #define a_think_8 0x2151 #define a_think_23 0x1CC8 #define a_think_24_vort_search 0x1D15 #define a_think_3 0x1C0E #define a_contact_3 0x1D6E #define a_think_body_3 0x4A45 #define a_think_body_6 0x2369 #define a_sub_B739 0xB739 // seg000:0xC0CE void get_random() { reg_bx = MEMW(rnd); reg_bx++; reg_bx &= 0xff; W_MEMW(rnd, reg_bx); reg_al = MEMB(rnd_vals + reg_bx); reg_ah = 0; RET; } // seg000:2C2A void do_fall() { assert(reg_eip == 0x2c2a); PUSH(bp); MOV(bp, sp); PUSH(si); reg_si = 1; // seg000:2C64 while (reg_si <= MEMW(sprite_sync)) { // seg000:2C33 W_MEMW(sprite_copy.vel_y, MEMW(sprite_copy.vel_y) + 3); // 3 = Byte $2c37 if ((short)MEMW(sprite_copy.vel_y) <= 200) { // 200 = word $2c3c // seg000:2C48 if ((short)MEMW(sprite_copy.vel_y) < -400) W_MEMW(sprite_copy.vel_y, -400); } else { // seg000:2C40 W_MEMW(sprite_copy.vel_y, 200); // 200 = word $2c44 } // seg000:2C56 if (reg_si != MEMW(sprite_sync)) { reg_ax = MEMW(sprite_copy.vel_y); W_MEMW(sprite_copy.delta_y, MEMW(sprite_copy.delta_y) + reg_ax); } reg_si++; } POP(si) POP(bp) RET; } // seg000:2C97 void check_ground() { assert(reg_eip == 0x2c97); PUSH(bp); MOV(bp, sp); reg_sp -= 0xc; PUSH(si); PUSH(di); W_MEMW(reg_bp - 0xc, 0); // seg000:2CA4 limit sprite movement to 15 pixels per frame if ((short)MEMW(sprite_copy.delta_x) > 3840) { // seg000:2CAC W_MEMW(sprite_copy.delta_x, 3840); } else { // seg000:2CB4 if ((short)MEMW(sprite_copy.delta_x) < -3840) W_MEMW(sprite_copy.delta_x, -3840); } // seg000:2CC2 if ((short)MEMW(sprite_copy.delta_y) > 3840) { // seg000:2CCA W_MEMW(sprite_copy.delta_y, 3840); } else { // seg000:2CD2 if ((short)MEMW(sprite_copy.delta_y) < -3840) W_MEMW(sprite_copy.delta_y, -3840); } // seg000:2CE0 update bounding box_y reg_ax = MEMW(sprite_copy.delta_y); int tmp = (short)reg_ax; W_MEMD(sprite_copy.box_bottom_y, (int)MEMD(sprite_copy.box_bottom_y) + tmp); // seg000:2CEC reg_ax = MEMW(sprite_copy.delta_y); W_MEMD(sprite_copy.box_top_y, (int)MEMD(sprite_copy.box_top_y) + tmp); // convert xbounding map-coordinates to tile coordinates tmp = MEMD(sprite_copy.box_left_x) >> 0xc; reg_ax = (Bit16u)(tmp & 0xffff); W_MEMW(reg_bp - 4, reg_ax); tmp = MEMD(sprite_copy.box_right_x) >> 0xc; reg_ax = (Bit16u)(tmp & 0xffff); W_MEMW(reg_bp - 6, reg_ax); // seg000:2D16 moving down if ((short)MEMW(sprite_copy.delta_y) > 0) { // seg000:2D20 convert (new) bottom_box_y to map tile coord, store on stack tmp = MEMD(sprite_copy.box_bottom_y) >> 0xc; reg_ax = (Bit16u)(tmp & 0xffff); reg_dx = (Bit16u)(tmp >> 16); PUSH(ax); reg_ax = MEMW(sprite_copy.delta_y); PUSH(dx); reg_dx = (Bit16u)((int)(short)reg_ax >> 16); PUSH(ax); PUSH(dx); reg_dx = MEMW(sprite_copy.box_bottom_y + 2); reg_ax = MEMW(sprite_copy.box_bottom_y); POP(bx); POP(cx); // loaded (new) bottom _box_y to dx:ax; load delta_y to bx:cx // seg000:2D3D tmp 1 = (new) bottom_box_y - delta_y int tmp1 = (reg_dx << 16) | reg_ax; int tmp2 = (reg_bx << 16) | reg_cx; tmp1 -= tmp2; tmp1 >>= 0xc; reg_ax = (Bit16u)(tmp1 & 0xffff); reg_dx = (Bit16u)(tmp1 >> 16); POP(bx) // seg000:2D47 // cmp bx, dx Bit16u tmpdx = reg_dx; POP(dx) if (reg_bx != tmpdx || reg_dx != reg_ax) { // seg000:2D53 tmp = MEMD(sprite_copy.box_bottom_y); tmp >>= 0xc; reg_ax = (Bit16u)(tmp & 0xffff); W_MEMW(reg_bp - 0xa, reg_ax); reg_ax = MEMW(reg_bp - 4); W_MEMW(reg_bp - 2, reg_ax); // seg000:2DCC while ((short)MEMW(reg_bp - 2) <= (short)MEMW(reg_bp - 6)) { // seg000:2D6A reg_ax = MEMW(reg_bp - 0xa); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; //one word per tile reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); //Point ES:BX to tile plane in map file reg_bx += reg_ax; //Point ES:BX to tile that sprite has just crossed into reg_bx = mem_readw(SegPhys(es) + reg_bx); //load BX with tile_number of said map tile reg_bx <<= 1; //convert to word // seg000:2D81 if (MEMW(reg_bx + 0xa34) == 0) { //ds:0A34 = tileinfo blocking up plane // seg000:2DC9 W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) + 1); } else { // seg000:2D88 W_MEMW(sprite_copy.vel_y, 0); reg_ax = 0; reg_dx = 0x1000; //PUSH(ax); //PUSH(dx); tmp1 = MEMD(sprite_copy.box_bottom_y) + 1; tmp1 %= reg_dx; // seg000:2DA4 //reg_ax = (Bit16u)(tmp1 >> 16); //reg_dx = (Bit16u)(tmp1 & 0xffff); //PUSH(ax); //PUSH(dx); reg_dx = (Bit16u)(tmp1 >> 16); reg_ax = (Bit16u)(tmp1 & 0xffff); MOV(si, ax); W_MEMW(sprite_copy.delta_y, MEMW(sprite_copy.delta_y) - reg_ax); // seg000:2DAD tmp1 = (int)(short)reg_ax; reg_dx = (Bit16u)(tmp1 >> 16); W_MEMD(sprite_copy.box_top_y, MEMD(sprite_copy.box_top_y) - tmp1); MOV(ax, si); tmp1 = (int)(short)reg_ax; reg_dx = (Bit16u)(tmp1 >> 16); W_MEMD(sprite_copy.box_bottom_y, MEMD(sprite_copy.box_bottom_y) - tmp1); W_MEMW(reg_bp - 0xc, 2); break; //jmp seg000:2E94 } } } } else if ((short)MEMW(sprite_copy.delta_y) < 0) { // seg000:2DD7 // seg000:2DE1 int tmp1 = MEMD(sprite_copy.box_top_y) >> 0xc; reg_ax = (Bit16u)(tmp1 & 0xffff); reg_dx = (Bit16u)(tmp1 >> 16); PUSH(ax); reg_ax = MEMW(sprite_copy.delta_y); PUSH(dx); tmp1 = (short)reg_ax; reg_dx = (Bit16u)(tmp1 >> 16); int tmp2 = tmp1; PUSH(ax); PUSH(dx); tmp1 = MEMD(sprite_copy.box_top_y); reg_dx = MEMW(sprite_copy.box_top_y + 2); reg_ax = MEMW(sprite_copy.box_top_y); POP(bx); POP(cx); tmp1 -= tmp2; tmp1 >>= 0xc; reg_ax = (Bit16u)(tmp1 & 0xffff); reg_dx = (Bit16u)(tmp1 >> 16); // seg000:2E07 POP(bx); // cmp bx, dx Bit16u tmpdx = reg_dx; POP(dx); if (reg_bx != tmpdx || reg_dx != reg_ax) { // seg000:2E14 tmp1 = MEMD(sprite_copy.box_top_y) >> 0xc; W_MEMW(reg_bp - 8, tmp1 & 0xffff); reg_ax = MEMW(reg_bp - 4); W_MEMW(reg_bp - 2, reg_ax); while (MEMW(reg_bp - 2) <= MEMW(reg_bp - 6)) { // seg000:2E2B reg_ax = MEMW(reg_bp - 8); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; if (MEMW(reg_bx + 0x13c0) == 0) { // seg000:2E89 W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) + 1); } else { // seg000:2E49 W_MEMW(sprite_copy.vel_y, 0); tmp1 = MEMD(sprite_copy.box_top_y) % 0x1000; reg_dx = 0x1000 - (tmp1 & 0xffff); reg_si = reg_dx; W_MEMW(sprite_copy.delta_y, MEMW(sprite_copy.delta_y) + reg_dx); reg_ax = reg_si; tmp1 = (short)reg_ax; reg_dx = (Bit16u)(tmp1 >> 16); W_MEMD(sprite_copy.box_top_y, MEMD(sprite_copy.box_top_y) + tmp1); reg_ax = reg_si; tmp1 = (short)reg_ax; reg_dx = (Bit16u)(tmp1 >> 16); W_MEMD(sprite_copy.box_bottom_y, MEMD(sprite_copy.box_bottom_y) + tmp1); W_MEMW(reg_bp - 0xc, 8); break; } } } } // seg000:2E94 int tmp1 = (short)MEMW(sprite_copy.delta_x); W_MEMD(sprite_copy.box_left_x, (int)MEMD(sprite_copy.box_left_x) + tmp1); tmp1 = (short)MEMW(sprite_copy.delta_x); W_MEMD(sprite_copy.box_right_x, (int)MEMD(sprite_copy.box_right_x) + tmp1); tmp1 = MEMD(sprite_copy.box_top_y) >> 0xc; W_MEMW(reg_bp - 8, tmp1 & 0xffff); tmp1 = MEMD(sprite_copy.box_bottom_y) >> 0xc; W_MEMW(reg_bp - 0xa, tmp1 & 0xffff); // seg000:2ECA if ((short)MEMW(sprite_copy.delta_x) > 0) { // seg000:2ED4 tmp1 = MEMD(sprite_copy.box_right_x) >> 0x0c; reg_ax = (Bit16u)(tmp1 & 0xffff); reg_dx = (Bit16u)(tmp1 >> 16); PUSH(ax); reg_ax = MEMW(sprite_copy.delta_x); PUSH(dx); tmp1 = (short)reg_eax; reg_dx = (Bit16u)(tmp1 >> 16); PUSH(ax); PUSH(dx); // seg000:2EE8 int tmp2 = MEMD(sprite_copy.box_right_x); reg_ax = (Bit16u)(tmp1 & 0xffff); reg_dx = (Bit16u)(tmp1 >> 16); POP(bx); POP(cx); tmp1 -= tmp2; tmp1 >>= 0xc; reg_ax = (Bit16u)(tmp1 & 0xffff); reg_dx = (Bit16u)(tmp1 >> 16); // seg000:2EFA POP(bx); // cmp bx, dx Bit16u tmpdx = reg_dx; POP(dx); if (reg_bx != tmpdx || reg_dx != reg_ax) { // seg000:2F07 tmp1 = MEMD(sprite_copy.box_right_x) >> 0xc; W_MEMW(reg_bp - 6, tmp1 & 0xffff); reg_di = MEMW(reg_bp - 8); while ((short)reg_di <= (short)MEMW(reg_bp - 0xa)) { // seg000:2F1B MOV(ax, di); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 6); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; if (MEMW(reg_bx + 0x1886) == 0) { // seg000:2F79 reg_di++; } else { // seg000:2F38 W_MEMW(sprite_copy.vel_x, 0); tmp1 = (MEMD(sprite_copy.box_right_x) + 1) % 0x1000; reg_ax = (Bit16u)(tmp1 & 0xffff); MOV(si, ax); W_MEMW(sprite_copy.delta_x, MEMW(sprite_copy.delta_x) - reg_ax); tmp1 = (short)reg_ax; W_MEMD(sprite_copy.box_left_x, tmp1); MOV(ax, si); tmp1 = (short)reg_ax; W_MEMD(sprite_copy.box_right_x, tmp1); W_MEMW(reg_bp - 0xc, MEMW(reg_bp - 0xc) | 4); break; } } } } else if ((short)MEMW(sprite_copy.delta_x) < 0) { // seg000:2F8C tmp1 = MEMD(sprite_copy.box_left_x) >> 0xc; reg_ax = (Bit16u)(tmp1 & 0xffff); reg_dx = (Bit16u)(tmp1 >> 16); PUSH(ax); reg_ax = MEMW(sprite_copy.delta_x); PUSH(dx); tmp1 = (short)reg_ax; reg_dx = (Bit16u)(tmp1 >> 16); PUSH(ax); PUSH(dx); tmp1 = MEMD(sprite_copy.box_left_x); POP(bx); POP(cx); int tmp2 = (reg_bx << 16) | reg_cx; tmp1 -= tmp2; tmp1 >>= 0xc; reg_ax = (Bit16u)(tmp1 & 0xffff); reg_dx = (Bit16u)(tmp1 >> 16); // seg000:2FB2 POP(bx); Bit16u tmpdx = reg_dx; POP(dx); if (reg_bx != tmpdx || reg_dx != reg_ax) { // seg000:2FBC tmp1 = MEMD(sprite_copy.box_left_x) >> 0xc; W_MEMW(reg_bp - 4, tmp1 & 0xffff); reg_di = MEMW(reg_bp - 8); // seg000:302E while ((short)reg_di <= (short)MEMW(reg_bp - 0xa)) { // seg000:2FD0 MOV(ax, di); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 4); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; if (MEMW(reg_bx + 0xEFA) == 0) { // seg000:302D reg_di++; } else { // seg000:2FED W_MEMW(sprite_copy.vel_x, 0); tmp1 = 0x1000 - (MEMD(sprite_copy.box_left_x) % 0x1000); reg_dx = (Bit16u)(tmp1 & 0xffff); MOV(si, dx); W_MEMW(sprite_copy.delta_x, MEMW(sprite_copy.delta_x) + reg_dx); MOV(ax, si); W_MEMD(sprite_copy.box_left_x, MEMD(sprite_copy.box_left_x) + reg_ax); MOV(ax, si); W_MEMD(sprite_copy.box_right_x, MEMD(sprite_copy.box_right_x) + reg_ax); W_MEMW(reg_bp - 0xc, MEMW(reg_bp - 0xc) | 1); break; } } } } // seg000:3033 reg_ax = MEMW(reg_bp - 0xc); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:2C6D void compute_sprite_delta() { RETLOC(2C95); assert(reg_eip == 0x2c6d); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(sprite_copy.vel_x); unsigned long tmp = reg_ax * MEMW(sprite_sync); reg_ax = (Bit16u)(tmp & 0xffff); reg_dx = (Bit16u)(tmp >> 16); reg_dx = MEMW(sprite_copy.delta_x); reg_dx += reg_ax; W_MEMW(sprite_copy.delta_x, reg_dx); reg_ax = MEMW(sprite_copy.vel_y); tmp = reg_ax * MEMW(sprite_sync); reg_ax = (Bit16u)(tmp & 0xffff); reg_dx = (Bit16u)(tmp >> 16); reg_dx = MEMW(sprite_copy.delta_y); reg_dx += reg_ax; W_MEMW(sprite_copy.delta_y, reg_dx); EMU_CALL(a_check_ground, 2C95, compute_sprite_delta); POP(bp); RET; } // seg000:C05C void calc_jump_height() { PUSH(bp); MOV(bp, sp); PUSH(si); reg_ax = MEMW(reg_bp + 4); PUSH(ax); reg_dx = 0xffff; while(1) { // seg000:C067 bool cf = (reg_ax >> 15) & 1; reg_ax <<= 1; if (cf) break; reg_dx >>= 1; } // seg000:C06F reg_bx = MEMW(word_182A9); reg_si = MEMW(word_182AB); reg_ax = MEMW(word_182AD + reg_bx); reg_ax += MEMW(word_182AD + reg_si) + 1; W_MEMW(word_182AD + reg_bx, reg_ax); reg_ax += MEMW(word_182AD); W_MEMW(word_182AD, reg_ax); reg_bx -= 2; if (reg_bx == 0) reg_bx = 0x22; // seg000:C091 reg_si -= 2; if (reg_si == 0) reg_si = 0x22; // seg000:C098 W_MEMW(word_182A9, reg_bx); W_MEMW(word_182AB, reg_si); POP(cx); reg_ax &= reg_dx; if (reg_ax > reg_cx) reg_ax >>= 1; // seg000:C0A9 POP(si); POP(bp); RET; } // SEG000:0x194F void think_yorp_walk() { RETLOC(19B7); RETLOC(19B4); RETLOC(196A); RETLOC(1976); RETLOC(195D); assert(reg_eip == 0x194f); PUSH(bp); MOV(bp, sp); PUSH(si); // seg000:1953 if (MEMW(sprite_copy.vel_y) == 0) { EMU_CALL(a_get_random, 195D, think_yorp_walk); // seg000:195d if (reg_ax >= MEMW(sprite_sync)) { // seg000:1973 EMU_CALL(a_get_random, 1976, think_yorp_walk); // seg000:1976 if (reg_ax < MEMW(sprite_sync)) { // seg000:197c W_MEMW(sprite_copy.think_func, a_think_yorp_look); W_MEMW(sprite_copy.sync_time, 0); } } else { // seg000:1963 reg_ax = 0x80; PUSH(ax); EMU_CALL(a_calc_jump_height, 196A, think_yorp_walk); reg_sp += 2; reg_ax = -(short)reg_ax; W_MEMW(sprite_copy.vel_y, reg_ax); } } // seg000:0x1988 if ((short)MEMW(sprite_copy.vel_x) > 0) W_MEMW(sprite_copy.cur_frame, 0x34); else W_MEMW(sprite_copy.cur_frame, 0x36); // seg000:0x199D reg_ax = MEMW(tick_count); reg_ax >>= 4; reg_ax &= 1; reg_dx = MEMW(sprite_copy.cur_frame); reg_dx += reg_ax; W_MEMW(sprite_copy.cur_frame, reg_dx); EMU_CALL(a_do_fall, 19B4, think_yorp_walk); EMU_CALL(a_compute_sprite_delta, 19B7, think_yorp_walk); MOV(si, ax); if (reg_ax & 4) { // seg000:19BE W_MEMW(sprite_copy.vel_x, 0xFFC4); } if (reg_si & 1) { // seg000:19CA W_MEMW(sprite_copy.vel_x, 60); } POP(si); POP(bp); RET; } // seg000:35D2 - deals with switches void toggle_switch() { RETLOC(37F3); RETLOC(372A); RETLOC(3724); RETLOC(36B1); RETLOC(35E1); RETLOC(362A); RETLOC(3631); RETLOC(3654); RETLOC(3687); RETLOC(368D); RETLOC(369E); RETLOC(36A8); assert(reg_eip == 0x35d2); PUSH(bp); MOV(bp, sp); reg_sp -= 0x12; PUSH(si); PUSH(di); PUSHI(0x19); // flip lightswitch sound EMU_CALL(a_set_cur_sound, 35E1, toggle_switch); reg_sp += 2; // seg000:35E3 Check the tile reg_ax = MEMW(current_tile_y); reg_ax += 5; // 5 down reg_ax *= MEMW(map_width_intiles); reg_dx = MEMW(current_tile_x); reg_dx += reg_ax; reg_dx += 3; // and 3 over reg_dx <<= 1; // seg000:35F8 reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; // seg000:35FE if (mem_readw(SegPhys(es) + reg_bx) == 0x1DF) { // If tile is number 0x1DF, do shake screen code // seg000:3608 int tmp1 = MEMD(scroll_x_lo); W_MEMD(reg_bp - 0xe, tmp1); tmp1 = MEMD(scroll_y_lo); W_MEMD(reg_bp - 0x12, tmp1); reg_si <<= 1; // seg000:368E shake screen while ((short)reg_si < 0x50) { // length of time to shake screen // seg000:3627 EMU_CALL(a_sync_drawing, 362A, toggle_switch); PUSHI(0x40); EMU_CALL(a_calc_jump_height, 3631, toggle_switch); reg_sp += 2; reg_ax += 0xffe0; reg_cl = 8; reg_ax <<= reg_cl; int tmp1 = (short)reg_ax; int tmp2 = MEMD(reg_bp - 0xe); tmp2 -= tmp1; W_MEMD(scroll_x_lo, tmp2); // seg000:364D PUSHI(0x40); EMU_CALL(a_calc_jump_height, 3654, toggle_switch); reg_sp += 2; reg_ax += 0xffe0; reg_cl = 8; reg_ax <<= reg_cl; tmp1 = (short)reg_ax; tmp2 = MEMD(reg_bp - 0x12); tmp2 -= tmp1; W_MEMD(scroll_y_lo, tmp2); // seg000:3670 PUSHI(MEMW(sprite_copy.cur_frame)); PUSHI(MEMW(sprite_copy.pos_y_hi)); PUSHI(MEMW(sprite_copy.pos_y_lo)); PUSHI(MEMW(sprite_copy.pos_x_hi)); PUSHI(MEMW(sprite_copy.pos_x_lo)); EMU_CALL(a_draw_sprite_at, 3687, toggle_switch); reg_sp += 0xa; EMU_CALL(a_draw_screen, 368D, toggle_switch); reg_si++; } // seg000:3693 Print Oops PUSHI(1); PUSHI(5); EMU_CALL(a_draw_box_opening2, 369E, toggle_switch); reg_sp += 4; PUSHI(aOops_); EMU_CALL(a_draw_string, 36A8, toggle_switch); reg_sp += 2; // seg000:36AA Call function PUSHI(0x64); EMU_CALL(a_delay, 36B1, toggle_switch); reg_sp += 2; W_MEMW(level_finished, 3); } else { // seg000:36BC reg_ax = MEMW(current_tile_y); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(current_tile_x); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 4, reg_ax); // seg000:36D5 if (reg_ax == 0x10f) { // light switch tile // seg000:371A if (MEMW(toggle_lights) != 0) { // seg000:3721 EMU_CALL(a_lights_out, 3724, toggle_switch); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:3727 EMU_CALL(a_lights_on, 372A, toggle_switch); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } else if (reg_ax == 0x1e0) { // lever tile // seg000:36E6 toggle up to down reg_ax = MEMW(current_tile_y); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(current_tile_x); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x1ed); } else if (reg_ax == 0x1ed) { // seg000:3700 toggle down to up reg_ax = MEMW(current_tile_y); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(current_tile_x); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x1e0); } // seg000:372D reg_ax = MEMW(current_tile_y); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(current_tile_x); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 2, reg_ax); // seg000:3746 reg_al = MEMB(reg_bp - 2); reg_al &= 0xff; reg_ax = (char)reg_al; W_MEMW(reg_bp - 0xa, reg_ax); reg_ax = MEMW(current_tile_x); reg_ax += MEMW(reg_bp - 0xa); W_MEMW(reg_bp - 6, reg_ax); reg_ax = MEMW(reg_bp - 2); reg_cl = 8; reg_ax >>= reg_cl; reg_ax = (char)reg_al; reg_dx = MEMW(current_tile_y); reg_dx += reg_ax; W_MEMW(reg_bp - 8, reg_dx); // seg000:3769 reg_si = 0; // seg000:37B0 while ((short)reg_si < (short)MEMW(num_bodies)) { // seg000:376D MOV(ax, si); reg_dx = 0x24; reg_ax *= reg_dx; MOV(bx, ax); // seg000:3776 if (MEMW(word_1B02E + reg_bx) != 0) { // seg000:377D MOV(ax, si); reg_dx = 0x24; reg_ax *= reg_dx; PUSH(ax); reg_ax = MEMW(reg_bp - 6); int tmp1 = (short)reg_ax; reg_dx = tmp1 >> 16; POP(bx); // seg000:378A if (MEMW(word_1B028 + reg_bx) == reg_dx) { // seg000:3790 if (MEMW(bodies + reg_bx) == reg_ax) { // seg000:3796 MOV(ax, si); reg_dx = 0x24; reg_ax *= reg_dx; PUSH(ax); reg_ax = MEMW(reg_bp - 8); tmp1 = (short)reg_ax; reg_dx = tmp1 >> 16; POP(bx); if (MEMW(word_1B02C + reg_bx) == reg_dx) { // seg000:37A9 if (MEMW(word_1B02A + reg_bx) == reg_ax) { break; } } } } } // seg000:37AF reg_si++; } // seg000:37B6 if ((short)reg_si < (short)MEMW(num_bodies)) { // seg000:37BC MOV(ax, si); reg_dx = 0x24; reg_ax *= reg_dx; MOV(bx, ax); // seg000:37C5 if (MEMW(word_1B048 + reg_bx) == a_bridge_retract) { // seg000:37CD MOV(ax, si); reg_dx = 0x24; reg_ax *= reg_dx; MOV(bx, ax); W_MEMW(word_1B048 + reg_bx, a_bridge_extend); } else { // seg000:37DF MOV(ax, si); reg_dx = 0x24; reg_ax *= reg_dx; MOV(bx, ax); W_MEMW(word_1B048 + reg_bx, a_bridge_retract); } } else { // seg000:37F0 EMU_CALL(a_add_body, 37F3, toggle_switch); MOV(di, ax); W_MEMW(reg_di + 8, 2); W_MEMW(reg_di + 34, a_bridge_extend); reg_ax = MEMW(reg_bp - 6); int tmp1 = (short)reg_ax; W_MEMD(reg_di, tmp1); reg_ax = MEMW(reg_bp - 8); tmp1 = (short)reg_ax; W_MEMD(reg_di + 4, tmp1); W_MEMW(reg_di + 0xa, 0); reg_ax = MEMW(reg_bp - 8); reg_ax *= MEMW(map_width_intiles); reg_dx = MEMW(reg_bp - 6); reg_dx += reg_ax; reg_dx++; reg_dx <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; // seg000:3831 if (MEMW(word_148D6 + reg_bx) == 0) { // seg000:3838 W_MEMW(reg_di + 0xc, 0xffff); } else { // seg000:383F W_MEMW(reg_di + 0xc, 1); } // seg000:3844 reg_ax = MEMW(reg_bp - 8); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 6); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_di + 0xe, reg_ax); W_MEMW(reg_di + 0x10, 0); } } // seg000:3861 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:BEF3 void set_cur_sound() { PUSH(bp); MOV(bp, sp); PUSH(si); if ((MEMW(sound_disabled) & 0xffff) == 0) { // seg000:BF02 reg_ax = MEMW(reg_bp + 4); MOV(si, ax); reg_si <<= 4; reg_ax = MEMW(sound_data_hi); SegSet16(es, reg_ax); reg_al = mem_readb(SegPhys(es) + reg_si + 2); // seg000:BF18 if (reg_al >= MEMB(sound_limiter)) { // seg000:BF1E W_MEMB(sound_limiter, reg_al); reg_ax = mem_readw(SegPhys(es) + reg_si); W_MEMW(cur_sound_pos, reg_ax); } // seg000:BF27 } POP(si); POP(bp); RET; } // seg000:42AC void sub_42AC() { RETLOC(42E6); assert(reg_eip == 0x42ac); PUSH(bp); MOV(bp, sp); W_MEMW(sprite_copy.think_func, a_think_17); W_MEMW(sprite_copy.contact_func, a_think_contact_nop); W_MEMD(sprite_copy.pos_y_lo, MEMD(sprite_copy.pos_y_lo) + 0x800); W_MEMW(keen_vel_y, 0); W_MEMW(sprite_copy.vel_x, 0); // seg000:42D0 W_MEMW(keen_vel_y, 0); W_MEMW(keen_vel_x, 0); W_MEMW(sprite_copy.sync_time, 0); W_MEMW(sprite_copy.cur_frame, 0x16); reg_ax = 8; PUSH(ax); EMU_CALL(a_set_cur_sound, 42E6, sub_42AC); // seg000:42E6 reg_sp += 2; POP(bp); RET; } // seg000:7881 // decompress levels void init_background() { PUSH(bp); MOV(bp, sp); reg_sp -= 0xa; PUSH(si); PUSH(di); reg_bx = MEMW(reg_bp + 4); SegSet16(es, MEMW(reg_bp + 6)); int tmp1 = mem_readd(SegPhys(es) + reg_bx); W_MEMD(reg_bp - 4, tmp1); tmp1 /= 2; reg_ax = tmp1 & 0xffff; reg_ax <<= 1; reg_dx = MEMW(reg_bp + 8 + 2); reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; W_MEMW(reg_bp - 0xa, reg_bx); W_MEMW(reg_bp - 8, reg_dx); W_MEMW(reg_bp + 4, MEMW(reg_bp + 4) + 4); do { // seg000:78BD reg_bx = MEMW(reg_bp + 4); SegSet16(es, MEMW(reg_bp + 6)); reg_di = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp + 4, MEMW(reg_bp + 4) + 2); // seg000:78C7 if (reg_di != 0xFEFE) { // seg000:78CD reg_bx = MEMW(reg_bp + 8); SegSet16(es, MEMW(reg_bp + 10)); mem_writew(SegPhys(es) + reg_bx, reg_di); W_MEMW(reg_bp + 8, MEMW(reg_bp + 8) + 2); } else { // seg000:78D9 reg_bx = MEMW(reg_bp + 4); SegSet16(es, MEMW(reg_bp + 6)); reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 6, reg_ax); W_MEMW(reg_bp + 4, MEMW(reg_bp + 4) + 2); reg_bx = MEMW(reg_bp + 4); SegSet16(es, MEMW(reg_bp + 6)); reg_di = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp + 4, MEMW(reg_bp + 4) + 2); reg_si = 1; // seg000:7900 while (reg_si <= MEMW(reg_bp - 6)) { // seg000:78F5 reg_bx = MEMW(reg_bp + 8); SegSet16(es, MEMW(reg_bp + 10)); mem_writew(SegPhys(es) + reg_bx, reg_di); W_MEMW(reg_bp + 8, MEMW(reg_bp + 8) + 2); reg_si++; } } // seg000:7905 reg_ax = MEMW(reg_bp + 8); } while (reg_ax < MEMW(reg_bp - 0xa)); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:3365 void check_ceiling() { RETLOC(3413); RETLOC(3416); RETLOC(340E); assert(reg_eip == 0x3365); PUSH(bp); MOV(bp, sp); int tmp1 = MEMD(dword_1869A) + 8; if (tmp1 < (int)MEMD(sprite_copy.pos_x_lo)) { // seg000:339A tmp1 = MEMD(sprite_copy.pos_x_lo); if (tmp1 < (int)MEMD(dword_18DFC)) { // seg000:33C5 } else { // seg000:33AF W_MEMW(sprite_copy.delta_x, 0); W_MEMW(sprite_copy.vel_x, 0); tmp1 = MEMD(dword_18DFC); // seg000:33BE W_MEMD(sprite_copy.pos_x_lo, tmp1); } } else { // seg000:3383 W_MEMW(sprite_copy.delta_x, 0); W_MEMW(sprite_copy.vel_x, 0); tmp1 = MEMD(dword_1869A) + 8; // seg000:33BE W_MEMD(sprite_copy.pos_x_lo, tmp1); } // seg000:33C5 tmp1 = MEMD(sprite_copy.pos_y_lo); if (tmp1 < (int)MEMD(dword_1869E)) { // seg000:33DA W_MEMW(sprite_copy.delta_y, 0); W_MEMW(sprite_copy.vel_y, 0); tmp1 = MEMD(dword_1869E); W_MEMD(sprite_copy.pos_y_lo, tmp1); } else { // seg000:33F2 tmp1 = MEMD(sprite_copy.pos_y_lo); if (tmp1 >= (int)MEMD(dword_18E00)) { // seg000:3407 reg_ax = 0x1b; PUSH(ax); EMU_CALL(a_set_cur_sound, 340E, check_ceiling); reg_sp += 2; EMU_CALL(a_finish_cur_sound, 3413, check_ceiling); EMU_CALL(a_sub_42AC, 3416, check_ceiling); } } // seg000:3416 POP(bp); RET; } void move_left_right() { PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 4); reg_si = 1; // seg000:2BD5 while (reg_si <= MEMW(sprite_sync)) { // seg000:2BA7 W_MEMW(sprite_copy.vel_x, MEMW(sprite_copy.vel_x) + reg_di); if ((short)MEMW(sprite_copy.vel_x) > 120) { // seg000:2BB2 W_MEMW(sprite_copy.vel_x, 120); } else { // seg000:2BBA if ((short)MEMW(sprite_copy.vel_x) < -120) { // seg000:2BC1 W_MEMW(sprite_copy.vel_x, -120); } } // seg000:2BC7 if (reg_si != MEMW(sprite_sync)) { // seg000:2BCD reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(sprite_copy.delta_x, MEMW(sprite_copy.delta_x) + reg_ax); } // seg000:2BD4 reg_si++; } // seg000:2BDB POP(di); POP(si); POP(bp); RET; } // seg000:1A68 void contact_5_yorp() { RETLOC(1AA2); assert(reg_eip == 0x1a68); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_di = MEMW(reg_bp + 6); if (MEMW(reg_di) == 0x0a || MEMW(reg_di) == 0x0b) { // seg000:1A7D W_MEMW(reg_si + 42, 0); W_MEMW(reg_si + 44, 2); W_MEMW(reg_si + 40, 0x3a); W_MEMW(reg_si + 50, a_think_12); W_MEMW(reg_si + 52, a_think_contact_nop); W_MEMW(reg_si + 34, 0xffb0); reg_ax = 0x22; PUSH(ax); EMU_CALL(a_set_cur_sound, 1AA2, contact_5_yorp); reg_sp += 2; } // seg000:1AA4 POP(di); POP(si); POP(bp); RET; } // seg000:3418 void do_scrolling() { PUSH(bp); MOV(bp, sp); reg_sp -= 8; PUSH(si); PUSH(di); // seg000:3420 if (MEMW(keen_think_func) != a_think_18 && MEMW(keen_think_func) != a_think_17) { // seg000:3436 store keen position in ax:dx reg_ax = MEMW(keen_pos_x + 2); reg_dx = MEMW(keen_pos_x); W_MEMW(reg_ebp - 4, reg_dx); W_MEMW(reg_ebp - 2, reg_ax); // seg000:3443 reg_ax = MEMW(keen_pos_y + 2); reg_dx = MEMW(keen_pos_y); W_MEMW(reg_ebp - 8, reg_dx); W_MEMW(reg_ebp - 6, reg_ax); // seg000:3450 reg_di = MEMW(keen_delta_x); reg_si = MEMW(keen_delta_y); // seg000:3458 scroll right if ((short)reg_di > 0) { // seg000:345C reg_ax = MEMW(reg_ebp - 2); reg_dx = MEMW(reg_ebp - 4); int tmp1 = (reg_ax << 16) | reg_dx; int tmp2 = MEMD(scroll_x_lo); tmp1 -= tmp2; if (tmp1 > 0xB000) { // seg000:3476 W_MEMD(scroll_x_lo, MEMD(scroll_x_lo) + reg_di); tmp1 = MEMD(scroll_x_lo); // seg000:3488 if (tmp1 > (int)MEMD(dword_1B00E)) { // seg000:3496 tmp1 = MEMD(dword_1B00E); W_MEMD(scroll_x_lo, tmp1); } } } else { // seg000:34A6 scroll left if ((short)reg_di < 0) { // seg000:34AA int tmp1 = MEMD(reg_bp - 4); tmp1 -= MEMD(scroll_x_lo); if (tmp1 < 0x9000) { // seg000:34C4 W_MEMD(scroll_x_lo, MEMD(scroll_x_lo) + (short)reg_di); tmp1 = MEMD(scroll_x_lo); if (tmp1 < (int)MEMD(dword_1869A)) { // seg000:34E4 tmp1 = MEMD(dword_1869A); W_MEMD(scroll_x_lo, tmp1); } } } } // seg000:34F2 scroll down if ((short)reg_si > 0) { // seg000:34F6 int tmp1 = MEMD(reg_bp - 8); tmp1 -= MEMD(scroll_y_lo); if (tmp1 > 0x7000) { // seg000:3510 W_MEMD(scroll_y_lo, MEMD(scroll_y_lo) + (short)reg_si); tmp1 = MEMD(scroll_y_lo); if (tmp1 > (int)MEMD(dword_1B012)) { // seg000:3530 W_MEMD(scroll_y_lo, MEMD(dword_1B012)); } } } else if ((short)reg_si < 0) { // seg000:3544 scroll right int tmp1 = MEMD(reg_bp - 8); tmp1 -= MEMD(scroll_y_lo); if (tmp1 < 0x3000) { // seg000:355E W_MEMD(scroll_y_lo, MEMD(scroll_y_lo) + (short)reg_si); if (MEMD(scroll_y_lo) < MEMD(dword_1869E)) { // seg000:357E W_MEMD(scroll_y_lo, MEMD(dword_1869E)); } } } } // seg000:358C POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:2935 void add_monster() { RETLOC(2966); assert(reg_eip == 0x2935); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_di = 1; reg_si = monsters; while(1) { // seg000:2946 if (MEMW(reg_si) == 0) break; if ((short)reg_di >= (short)MEMW(num_monsters)) break; // seg000:2942 reg_di++; reg_si += 54; //size of sprite struct (036h) } // seg000:2951 if ((short)reg_di >= (short)MEMW(num_monsters)) { // seg000:2957 W_MEMW(num_monsters, MEMW(num_monsters) + 1); } // seg000:295B reg_ax = 54; PUSH(ax); reg_ax = 0; PUSH(ax); PUSH(si); EMU_CALL(a__memset, 2966, add_monster); // seg000:2966 reg_sp += 6; W_MEMW(reg_si + 50, a_default_think); W_MEMW(reg_si + 52, a_default_contact); W_MEMW(reg_si + 2, 1); MOV(ax, si); // seg000:297A POP(di); POP(si); POP(bp); RET; } // 015C void int0_handler() { reg_cx = 14; reg_dx = aDivideError; reg_eip = 0x0226; return; } // 0165 void setup_int_vecs() { RETLOC(01A6); RETLOC(0192); RETLOC(0185); RETLOC(0178); RETLOC(016B); PUSHI(SegValue(ds)); reg_ax = 0x3500; EMU_INSTR(0169, 016B, setup_int_vecs); W_MEMW(orig_int0_off, reg_bx); W_MEMW(orig_int0_seg, SegValue(es)); reg_ax = 0x3504; EMU_INSTR(0176, 0178, setup_int_vecs); W_MEMW(orig_int4_off, reg_bx); W_MEMW(orig_int4_seg, SegValue(es)); reg_ax = 0x3505; EMU_INSTR(0183, 0185, setup_int_vecs); W_MEMW(orig_int5_off, reg_bx); W_MEMW(orig_int5_seg, SegValue(es)); reg_ax = 0x3506; EMU_INSTR(0190, 0192, setup_int_vecs); W_MEMW(orig_int6_off, reg_bx); W_MEMW(orig_int6_seg, SegValue(es)); reg_ax = 0x2500; reg_dx = SegValue(cs); SegSet16(ds, reg_dx); reg_dx = a_int0_handler; EMU_INSTR(01A4, 01A6, setup_int_vecs); SegSet16(ds, mem_readw(SegPhys(ss) + reg_sp)); reg_sp += 2; RET; } // 0218 void output_error() { RETLOC(21F); reg_ah = 0x40; reg_bx = 2; EMU_INSTR(21D, 21F, output_error); RET; } // 0289 void draw_screen() { RETLOC(290); assert(reg_eip == 0x289); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_do_drawing, 290, draw_screen); reg_si = word_186B0; if (MEMW(word_186A2) != 0) { // seg000:02A8 while (reg_si < MEMW(sprite_scratch_back)) { // seg000:029C reg_bx = MEMW(reg_si); reg_bx <<= 1; W_MEMW(word_18B66 + reg_bx, 0xffff); reg_si += 2; } } else { // seg000:02BC while (reg_si < MEMW(sprite_scratch_back)) { reg_bx = MEMW(reg_si); reg_bx <<= 1; W_MEMW(word_18E08 + reg_bx, 0xffff); reg_si += 2; } } // seg000:02C2 POP(si); POP(bp); RET; } // 066B void load_level_data() { RETLOC(6DB); RETLOC(6CD); RETLOC(6BF); RETLOC(6B1); RETLOC(6A3); RETLOC(68D); RETLOC(732); RETLOC(71E); RETLOC(6FB); RETLOC(6F2); RETLOC(6E9); assert(reg_eip == 0x66B); PUSH(bp); MOV(bp, sp); reg_sp -= 0x16; PUSH(si); PUSH(di); reg_ax = MEMW(reg_bp + 4); //level number W_MEMW(current_level, reg_ax); // Reading file into buffer // Get Name // seg000:0679 if ((short)MEMW(reg_bp + 4) < 0x0a) { // "level0x.ckx" // seg000:067F PUSHI(10); // radix reg_ax = reg_bp - 0x0a; // return string address? PUSH(ax); PUSHI(MEMW(reg_bp + 4)); // int to convert EMU_CALL(a__itoa, 68D, load_level_data); reg_sp += 6; // seg000:0690 reg_ax = aLevel0; } else { // seg000:0695 level = "levelxx.ckx" PUSHI(10); reg_ax = reg_bp - 0xa; PUSH(ax); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a__itoa, 6A3, load_level_data); reg_sp += 6; // seg000:06A6 reg_ax = aLevel; } // seg000:06A9 PUSH(ax); // ax = *level PUSHI(reg_bp - 0x16); // bp-16= *dest EMU_CALL(a__strcpy, 6B1, load_level_data); reg_sp += 4; // seg000:06B4 PUSHI(reg_bp - 0xa); // bp-10 = *levelnumstring PUSHI(reg_bp - 0x16); // bp-16 = *levelstring EMU_CALL(a__strcat, 6BF, load_level_data); reg_sp += 4; // seg000:06C2 PUSHI(aDot); //add dot PUSHI(reg_bp - 0x16); EMU_CALL(a__strcat, 6CD, load_level_data); reg_sp += 4; // seg000:06D0 PUSHI(MEMW(pExt)); //add extension PUSHI(reg_bp - 0x16); EMU_CALL(a__strcat, 6DB, load_level_data); reg_sp += 4; // seg000:06DE // open file (8000=?? PUSHI(0x8000); // return handle in ax? PUSHI(reg_bp - 0x16); EMU_CALL(a__open, 6E9, load_level_data); reg_sp += 4; // seg000:06EC // return length in ax MOV(di, ax); PUSH(ax); EMU_CALL(a__filelen, 6F2, load_level_data); reg_sp += 2; // seg000:06F4 W_MEMW(reg_bp - 6, reg_ax); // save file length in bp-6 PUSH(di); // close file (handle saved to di) EMU_CALL(a__close, 6FB, load_level_data); reg_sp += 2; // seg000:06FD reg_ax = 0xffff; reg_ax -= MEMW(reg_bp - 6); // ax = -(length + 1) reg_dx = MEMW(level_data + 2); // dx:bx = far ptr to level data reg_bx = MEMW(level_data); reg_bx += reg_ax; W_MEMW(reg_bp - 4, reg_bx); W_MEMW(reg_bp - 2, reg_dx); // seg000:0713 PUSH(dx); // segment PUSHI(MEMW(reg_bp - 4)); // negative offset? PUSHI(reg_bp - 0x16); // filename EMU_CALL(a_map_file_to_mem, 71E, load_level_data); reg_sp += 6; // seg000:0721 PUSHI(MEMW(level_data + 2)); // far ptr to level data PUSHI(MEMW(level_data)); PUSHI(MEMW(reg_bp - 2)); // far ptr to level_data seg:-(length+1)... PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_init_background, 732, load_level_data); reg_sp += 8; // seg000:0735 reg_si = 0; // seg000:075F while(1) { reg_bx = MEMW(level_data); // es:bx = level data SegSet16(es, MEMW(level_data + 2)); if ((short)mem_readw(SegPhys(es) + reg_bx + 4) <= (short)reg_si) //number of planes break; // seg000:0739 reg_bx = MEMW(level_data); SegSet16(es, MEMW(level_data + 2)); reg_ax = mem_readw(SegPhys(es) + reg_bx + 0xe); //Planesize reg_ax *= (short)reg_si; reg_dx = MEMW(level_data + 2); reg_bx += reg_ax; //set segment for plane reg_bx += 0x20; //offest for header // seg000:074C PUSH(dx); PUSH(bx); MOV(bx, si); reg_bx <<= 2; POP(ax); W_MEMW(tile_data_1 + reg_bx, reg_ax); POP(ax); W_MEMW(tile_data_1 + 2 + reg_bx, reg_ax); //store far pointers to planes // seg000:075E reg_si++; } // seg000:0769 reg_ax = mem_readw(SegPhys(es) + reg_bx); //store map heigh/width W_MEMW(map_width_intiles, reg_ax); reg_ax = mem_readw(SegPhys(es) + reg_bx + 2); W_MEMW(map_height_in_tiles, reg_ax); // seg000:0776 reg_ax = MEMW(map_width_intiles); reg_ax <<= 1; W_MEMW(map_width_intiles_x2, reg_ax); reg_ax += 0xffd6; W_MEMW(word_186A4, reg_ax); //(map width x 2) -42 = 2(map width - 21) W_MEMW(dword_1869A, 0x2000); W_MEMW(dword_1869A + 2, 0); W_MEMW(dword_1869E, 0x2000); W_MEMW(dword_1869E + 2, 0); // seg000:079C reg_ax = mem_readw(SegPhys(es) + reg_bx); //es:bx = level_data reg_ax += 0xffea; // ax = level_data - 22 int tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; // tile2map(level_data - 22) W_MEMD(dword_1B00E, tmp1); // seg000:07AF reg_bx = MEMW(level_data); SegSet16(es, MEMW(level_data + 2)); reg_ax = mem_readw(SegPhys(es) + reg_bx); reg_ax += 0xfffe; tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; W_MEMD(background_width, tmp1); // seg000:07C6 reg_bx = MEMW(level_data); SegSet16(es, MEMW(level_data + 2)); reg_ax = mem_readw(SegPhys(es) + reg_bx + 2); tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; W_MEMD(background_height, tmp1); // seg000:07DB reg_bx = MEMW(level_data); SegSet16(es, MEMW(level_data + 2)); reg_ax = mem_readw(SegPhys(es) + reg_bx + 2); reg_ax += 0xfff1; tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; tmp1 += 0x800; W_MEMD(dword_1B012, tmp1); // seg000:07F9 reg_bx = MEMW(level_data); SegSet16(es, MEMW(level_data + 2)); reg_ax = mem_readw(SegPhys(es) + reg_bx); reg_ax += 0xfffd; tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; W_MEMD(dword_18DFC, tmp1); // seg000:0810 reg_bx = MEMW(level_data); SegSet16(es, MEMW(level_data + 2)); reg_ax = mem_readw(SegPhys(es) + reg_bx + 2); tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; W_MEMD(dword_18E00, tmp1); // seg000:0825 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 082B void handle_quit() { RETLOC(8A1); RETLOC(891); RETLOC(88D); RETLOC(888); RETLOC(87F); RETLOC(875); RETLOC(866); RETLOC(856); RETLOC(852); RETLOC(84D); RETLOC(843); RETLOC(831); assert(reg_eip == 0x82B); PUSH(bp); MOV(bp, sp); EMU_CALL(a_clear_keys, 831, handle_quit); // seg000:0831 if (MEMW(current_level) == 0x5a) { // seg000:0838 PUSHI(1); PUSHI(0xc); EMU_CALL(a_draw_box_opening2, 843, handle_quit); reg_sp += 4; reg_ax = aQuitYN; PUSH(ax); EMU_CALL(a_draw_string, 84D, handle_quit); reg_sp += 2; EMU_CALL(a_read_char_with_echo, 852, handle_quit); PUSH(ax); EMU_CALL(a_sub_CD36, 856, handle_quit); reg_sp += 2; W_MEMB(byte_1D732, reg_al); // seg000:085B Y not pressed if (reg_al != 0x59) { POP(bp); RET; } // seg000:085F reg_ax = unk_14DB7; PUSH(ax); EMU_CALL(a_chg_vid_and_error, 866, handle_quit); reg_sp += 2; POP(bp); RET; } // seg000:086A PUSHI(2); PUSHI(0x14); EMU_CALL(a_draw_box_opening2, 875, handle_quit); reg_sp += 4; PUSHI(aQuitToDOsOr); EMU_CALL(a_draw_string, 87F, handle_quit); reg_sp += 2; PUSHI(aTItle); EMU_CALL(a_draw_string, 888, handle_quit); reg_sp += 2; EMU_CALL(a_read_char_with_echo, 88D, handle_quit); PUSH(ax); EMU_CALL(a_sub_CD36, 891, handle_quit); reg_sp += 2; W_MEMB(byte_1D732, reg_al); // seg000:0896 if (reg_al == 0x44) { // seg000:089A PUSHI(unk_14DD3); EMU_CALL(a_chg_vid_and_error, 8A1, handle_quit); reg_sp += 2; } // seg000:08A3 if (MEMB(byte_1D732) == 0x54) { W_MEMW(quit_to_title, 1); } POP(bp); RET; } // 0AF2 void screenshot() { printf("screenshot\n"); reg_eip = 0x0AF2; return; } // 5C3A void clear_keys() { RETLOC(5C53); assert(reg_eip == 0x5C3A); PUSH(bp); MOV(bp, sp); W_MEMW(key_code, 0); W_MEMW(key_scan, 0); PUSHI(128); PUSHI(0); PUSHI(key_map); EMU_CALL(a__memset, 5C53, clear_keys); reg_sp += 6; POP(bp); RET; } // 0C51 void handle_global_keys() { RETLOC(0D46); RETLOC(0D43); RETLOC(0D40); RETLOC(0CD9); RETLOC(0CD5); RETLOC(0CD0); RETLOC(0CC6); RETLOC(0CB8); RETLOC(0CB2); RETLOC(0CAC); RETLOC(0D27); RETLOC(0D24); RETLOC(0D1E); RETLOC(0D1B); RETLOC(0D13); RETLOC(0D0C); RETLOC(0D09); RETLOC(0D03); RETLOC(0D00); RETLOC(0CFD); RETLOC(0CBB); RETLOC(0CAF); RETLOC(0C61); assert(reg_eip == 0xC51); PUSH(bp); MOV(bp, sp); reg_sp -= 4; PUSH(si); reg_si = 0; PUSHI(1); EMU_CALL(a_translate_key, 0C61, handle_global_keys); reg_sp += 2; // seg000:0C63 reg_ax = 0x82ea; if (reg_ax != 0) { // wtf? // seg000:0C6D int tmp1 = MEMD(tick_count); W_MEMD(reg_bp - 4, tmp1); // seg000:0C7A reg_ax = MEMW(key_scan); reg_ax &= 0x7f; // seg000:0C80 if (reg_ax == 0x3d) { // seg000:0CFA EMU_CALL(a_save_cur_sound, 0CFD, handle_global_keys); EMU_CALL(a_clear_keys, 0D00, handle_global_keys); EMU_CALL(a_handle_redef_keys, 0D03, handle_global_keys); reg_si++; } else if (reg_ax > 0x3d) { // seg000:0C9C if (reg_ax == 0x3e) { // seg000:0D06 EMU_CALL(a_save_cur_sound, 0D09, handle_global_keys); EMU_CALL(a_clear_keys, 0D0C, handle_global_keys); PUSHI(1); EMU_CALL(a_handle_joystick, 0D13, handle_global_keys); reg_sp += 2; reg_si++; } else if (reg_ax == 0x3f) { // seg000:0D18 EMU_CALL(a_save_cur_sound, 0D1B, handle_global_keys); EMU_CALL(a_save_game, 0D1E, handle_global_keys); reg_si++; } else { // seg000:0D2A reg_ax = 0; POP(si); MOV(sp, bp); POP(bp); RET; } } else if (reg_ax == 1) { // seg000:0D21 EMU_CALL(a_save_cur_sound, 0D24, handle_global_keys); EMU_CALL(a_handle_quit, 0D27, handle_global_keys); reg_si++; } else if (reg_ax == 0x3b) { // seg000:0CA9 EMU_CALL(a_save_cur_sound, 0CAC, handle_global_keys); EMU_CALL(a_clear_keys, 0CAF, handle_global_keys); EMU_CALL(a_do_help, 0CB2, handle_global_keys); reg_si++; } else if (reg_ax == 0x3c) { // seg000:0CB5 EMU_CALL(a_save_cur_sound, 0CB8, handle_global_keys); EMU_CALL(a_clear_keys, 0CBB, handle_global_keys); PUSHI(1); PUSHI(0xd); EMU_CALL(a_draw_box_opening2, 0CC6, handle_global_keys); reg_sp += 4; // seg000:0CC9 PUSHI(aSoundYN); EMU_CALL(a_draw_string, 0CD0, handle_global_keys); reg_sp += 2; // seg000:0CD2 EMU_CALL(a_read_char_with_echo, 0CD5, handle_global_keys); PUSH(ax); EMU_CALL(a_sub_CD36, 0CD9, handle_global_keys); reg_sp += 2; // seg000:0CDB W_MEMB(byte_1D732, reg_al); // seg000:0CDE if (reg_al == 'N') { // seg000:0CE2 W_MEMW(want_sound, 0); } else { // seg000:0CEA if (MEMB(byte_1D732) == 'Y') { // seg000:0CF1 W_MEMW(want_sound, 1); } } // seg000:0CF7 reg_si++; } else { // seg000:0D2A reg_ax = 0; POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:0D2C tmp1 = MEMD(reg_bp - 4); W_MEMD(tick_count, tmp1); // seg000:0D39 if (reg_si != 0) { // seg000:0D3D EMU_CALL(a_clear_keys, 0D40, handle_global_keys); EMU_CALL(a_restore_cur_sound, 0D43, handle_global_keys); EMU_CALL(a_clear_overlay, 0D46, handle_global_keys); // seg000:0D46 reg_ax = 1; POP(si); MOV(sp, bp); POP(bp); RET; } } // seg000:0D4B reg_ax = 0; POP(si); MOV(sp, bp); POP(bp); RET; } // 0DB0 void start_cheating() { RETLOC(0E35); RETLOC(0E25); RETLOC(0E22); RETLOC(0E1F); RETLOC(0E1C); RETLOC(0DF7); RETLOC(0DEE); RETLOC(0DE5); RETLOC(0DDC); RETLOC(0DD2); RETLOC(0DC7); assert(reg_eip == 0x0db0); PUSH(bp); MOV(bp, sp); reg_sp -= 4; PUSH(si); int tmp1 = MEMD(tick_count); W_MEMD(reg_bp - 4, tmp1); EMU_CALL(a_clear_keys, 0DC7, start_cheating); PUSHI(4); PUSHI(0x1a); EMU_CALL(a_draw_box_opening2, 0DD2, start_cheating); reg_sp += 4; PUSHI(aYouAreNowCheating); EMU_CALL(a_draw_string, 0DDC, start_cheating); reg_sp += 2; PUSHI(aYouJustGotAPogoSti); EMU_CALL(a_draw_string, 0DE5, start_cheating); reg_sp += 2; PUSHI(aAllTheKeyCardsAnd); EMU_CALL(a_draw_string, 0DEE, start_cheating); reg_sp += 2; PUSHI(aLotsOfRayGunCharge); EMU_CALL(a_draw_string, 0DF7, start_cheating); reg_sp += 2; W_MEMW(got_pogo, 1); W_MEMW(ray_gun_charge, 0x64); reg_si = 0; // seg000:0E14 while ((short)reg_si < 4) { // seg000:0E09 MOV(bx, si); reg_bx <<= 1; W_MEMW(got_yellow_keycard + reg_bx, 1); reg_si++; } // seg000:0E19 EMU_CALL(a_read_char_with_echo, 0E1C, start_cheating); EMU_CALL(a_clear_overlay, 0E1F, start_cheating); EMU_CALL(a_draw_screen, 0E22, start_cheating); EMU_CALL(a_draw_screen, 0E25, start_cheating); // seg000:0E25 tmp1 = MEMD(reg_bp - 4); W_MEMD(tick_count, tmp1); EMU_CALL(a_clear_keys, 0E35, start_cheating); POP(si); MOV(sp, bp); POP(bp); RET; } // 0E3A void show_pause_menu() { RETLOC(11DD); RETLOC(11DA); RETLOC(11D7); RETLOC(11D4); RETLOC(11CF); RETLOC(11C9); RETLOC(11C3); RETLOC(119D); RETLOC(1182); RETLOC(1162); RETLOC(113D); RETLOC(111B); RETLOC(10F6); RETLOC(10C3); RETLOC(1097); RETLOC(106B); RETLOC(103F); RETLOC(0FFB); RETLOC(0FD8); RETLOC(0FC4); RETLOC(0FBA); RETLOC(0F9D); RETLOC(0F82); RETLOC(0F78); RETLOC(0F63); RETLOC(0F5A); RETLOC(0F4C); RETLOC(0F3B); RETLOC(0F2D); RETLOC(0F24); RETLOC(0F16); RETLOC(0F05); RETLOC(0EF7); RETLOC(0EE6); RETLOC(0ED8); RETLOC(0EC7); RETLOC(0EBE); RETLOC(0EAD); RETLOC(0E9C); RETLOC(0E8B); RETLOC(0E82); RETLOC(0E71); RETLOC(0E5D); RETLOC(0E52); assert(reg_eip == 0xe3a); PUSH(bp); MOV(bp, sp); reg_sp -= 6; PUSH(si); PUSH(di); int tmp1 = MEMD(tick_count); W_MEMD(reg_bp - 6, tmp1); EMU_CALL(a_clear_keys, 0E52, show_pause_menu); PUSHI(0xd); PUSHI(0x1c); EMU_CALL(a_draw_box_opening2, 0E5D, show_pause_menu); reg_sp += 4; reg_si = MEMW(word_1B2D2); reg_ax = MEMW(word_1B348); W_MEMW(reg_bp - 2, reg_ax); PUSHI(aScoreExtraKeenAt); EMU_CALL(a_draw_invvid_string, 0E71, show_pause_menu); reg_sp += 2; // seg000:0E73 MOV(ax, si); reg_ax += 0xc; W_MEMW(word_1B2D2, reg_ax); PUSHI(asc_14E70); EMU_CALL(a_draw_invvid_string, 0E82, show_pause_menu); reg_sp += 2; PUSHI(aKeensShipParts); EMU_CALL(a_draw_invvid_string, 0E8B, show_pause_menu); reg_sp += 2; // seg000:0E8D MOV(ax, si); reg_ax += 0xe; W_MEMW(word_1B2D2, reg_ax); PUSHI(asc_14E91); EMU_CALL(a_draw_invvid_string, 0E9C, show_pause_menu); reg_sp += 2; // seg000:0E9E MOV(ax, si); reg_ax += 0xe; W_MEMW(word_1B2D2, reg_ax); PUSHI(asc_14E94); EMU_CALL(a_draw_invvid_string, 0EAD, show_pause_menu); reg_sp += 2; // seg000:0EAF MOV(ax, si); reg_ax += 0xe; W_MEMW(word_1B2D2, reg_ax); PUSHI(asc_14E97); EMU_CALL(a_draw_invvid_string, 0EBE, show_pause_menu); reg_sp += 2; PUSHI(aRaygunPogoKeycards); EMU_CALL(a_draw_invvid_string, 0EC7, show_pause_menu); reg_sp += 2; // seg000:0EC9 MOV(ax, si); reg_ax += 8; W_MEMW(word_1B2D2, reg_ax); PUSHI(asc_14EB8); EMU_CALL(a_draw_invvid_string, 0ED8, show_pause_menu); reg_sp += 2; W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 6); PUSHI(asc_14EBA); EMU_CALL(a_draw_invvid_string, 0EE6, show_pause_menu); reg_sp += 2; // seg000:0EE8 MOV(ax, si); reg_ax += 8; W_MEMW(word_1B2D2, reg_ax); PUSHI(asc_14EBD); EMU_CALL(a_draw_invvid_string, 0EF7, show_pause_menu); reg_sp += 2; W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 6); PUSHI(asc_14EBF); EMU_CALL(a_draw_invvid_string, 0F05, show_pause_menu); reg_sp += 2; // seg000:0F07 MOV(ax, si); reg_ax += 8; W_MEMW(word_1B2D2, reg_ax); PUSHI(asc_14EC2); EMU_CALL(a_draw_invvid_string, 0F16, show_pause_menu); reg_sp += 2; W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 6); PUSHI(asc_14EC4); EMU_CALL(a_draw_invvid_string, 0F24, show_pause_menu); reg_sp += 2; PUSHI(aCharge); EMU_CALL(a_draw_invvid_string, 0F2D, show_pause_menu); reg_sp += 2; W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 6); PUSHI(asc_14ED1); EMU_CALL(a_draw_invvid_string, 0F3B, show_pause_menu); reg_sp += 2; // seg000:0F3D MOV(ax, si); reg_ax += 8; W_MEMW(word_1B2D2, reg_ax); PUSHI(asc_14ED4); EMU_CALL(a_draw_invvid_string, 0F4C, show_pause_menu); reg_sp += 2; W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 6); PUSHI(asc_14ED6); EMU_CALL(a_draw_invvid_string, 0F5A, show_pause_menu); reg_sp += 2; PUSHI(aPleasePressAKey); EMU_CALL(a_draw_invvid_string, 0F63, show_pause_menu); reg_sp += 2; // seg000:0F65 PUSHI(0xa); PUSHI(unk_1B2E0); PUSHI(MEMW(value + 2)); PUSHI(MEMW(value)); EMU_CALL(a__ltoa, 0F78, show_pause_menu); reg_sp += 8; PUSHI(unk_1B2E0); EMU_CALL(a__strlen, 0F82, show_pause_menu); reg_sp += 2; // seg000:0F84 MOV(dx, si); reg_dx += 0xa; reg_dx -= reg_ax; W_MEMW(word_1B2D2, reg_dx); reg_ax = MEMW(reg_bp - 2); reg_ax++; W_MEMW(word_1B348, reg_ax); PUSHI(unk_1B2E0); EMU_CALL(a_draw_string, 0F9D, show_pause_menu); reg_sp += 2; // seg000:0F9F PUSHI(0xa); PUSHI(unk_1B2E0); tmp1 = MEMD(dword_19F12); tmp1 += 0x4e20; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a__ltoa, 0FBA, show_pause_menu); reg_sp += 8; PUSHI(unk_1B2E0); EMU_CALL(a__strlen, 0FC4, show_pause_menu); reg_sp += 2; // seg000:0FC6 MOV(dx, si); reg_dx += 0x1a; reg_dx -= reg_ax; W_MEMW(word_1B2D2, reg_dx); PUSHI(unk_1B2E0); EMU_CALL(a_draw_string, 0FD8, show_pause_menu); reg_sp += 2; // seg000:0FDA reg_di = 0; // seg000:0FFF while ((short)reg_di < (short)MEMW(num_keens_left) && (short)reg_di < 6) { // seg000:0FDE PUSHI(0); reg_ax = MEMW(reg_bp - 2); reg_ax += 3; reg_ax <<= 3; PUSH(ax); MOV(ax, di); reg_ax <<= 1; MOV(dx, si); reg_dx += reg_ax; reg_dx++; PUSH(dx); EMU_CALL(a_draw_sprite, 0FFB, show_pause_menu); reg_sp += 6; reg_di++; } // seg000:100A MOV(ax, si); reg_ax += 0x10; W_MEMW(word_1B2D2, reg_ax); reg_ax = MEMW(reg_bp - 2); reg_ax += 3; W_MEMW(word_1B348, reg_ax); // seg000:101B if (MEMW(got_part_1) != 0) { // seg000:1022 reg_ax = 0x1c0; } else { reg_ax = 0x141; } // seg000:102A PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += 4; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_do_overdraw, 103F, show_pause_menu); reg_sp += 6; W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 3); // seg000:1047 if (MEMW(got_part_2) != 0) { reg_ax = 0x1c1; } else { reg_ax = 0x142; } // seg000:1056 PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += 4; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_do_overdraw, 106B, show_pause_menu); reg_sp += 6; W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 3); // seg000:1073 if (MEMW(got_part_3) != 0) { reg_ax = 0x1c2; } else { reg_ax = 0x143; } // seg000:1082 PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += 4; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_do_overdraw, 1097, show_pause_menu); reg_sp += 6; W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 3); // seg000:109F if (MEMW(got_part_4) != 0) { // seg000:10A6 reg_ax = 0x1c3; } else { // seg000:10AB reg_ax = 0x144; } // seg000:10AE PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += 4; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_do_overdraw, 10C3, show_pause_menu); reg_sp += 6; // seg000:10C6 MOV(ax, si); reg_ax += 0x13; W_MEMW(word_1B2D2, reg_ax); reg_ax = MEMW(reg_bp - 2); reg_ax += 7; W_MEMW(word_1B348, reg_ax); // seg000:10D7 if (MEMW(got_yellow_keycard) != 0) { // seg000:10DE PUSHI(0x1a8); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_do_overdraw, 10F6, show_pause_menu); reg_sp += 6; } // seg000:10F9 if (MEMW(got_red_keycard) != 0) { // seg000:1100 PUSHI(0x1a9); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += 3; PUSH(ax); reg_ax = MEMW(word_1B2D2); reg_ax += 4; PUSH(ax); EMU_CALL(a_do_overdraw, 111B, show_pause_menu); reg_sp += 6; } // seg000:111E if (MEMW(got_green_keycard) != 0) { // seg000:1125 PUSHI(0x1aa); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += 0x15; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_do_overdraw, 113D, show_pause_menu); reg_sp += 6; } // seg000:1140 if (MEMW(got_blue_keycard) != 0) { // seg000:1147 PUSHI(0x1ab); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += 0x15; PUSH(ax); reg_ax = MEMW(word_1B2D2); reg_ax += 4; PUSH(ax); EMU_CALL(a_do_overdraw, 1162, show_pause_menu); reg_sp += 6; } // seg000:1165 PUSHI(0x19e); reg_ax = MEMW(reg_bp - 2); reg_ax += 7; reg_ax <<= 3; reg_ax += 4; PUSH(ax); MOV(ax, si); reg_ax += 3; PUSH(ax); EMU_CALL(a_do_overdraw, 1182, show_pause_menu); reg_sp += 6; // seg000:1185 MOV(ax, si); reg_ax += 3; W_MEMW(word_1B2D2, reg_ax); reg_ax = MEMW(reg_bp - 2); reg_ax += 0xb; W_MEMW(word_1B348, reg_ax); PUSHI(MEMW(ray_gun_charge)); EMU_CALL(a_draw_number, 119D, show_pause_menu); reg_sp += 2; // seg000:119F if (MEMW(got_pogo) != 0) { // seg000:11A6 PUSHI(0x19f); reg_ax = MEMW(reg_bp - 2); reg_ax += 8; reg_ax <<= 3; reg_ax += 4; PUSH(ax); MOV(ax, si); reg_ax += 0xb; PUSH(ax); EMU_CALL(a_do_overdraw, 11C3, show_pause_menu); reg_sp += 6; } // seg000:11C6 EMU_CALL(a_clear_keys, 11C9, show_pause_menu); PUSHI(0); EMU_CALL(a_translate_key, 11CF, show_pause_menu); reg_sp += 2; EMU_CALL(a_clear_overlay, 11D4, show_pause_menu); EMU_CALL(a_draw_screen, 11D7, show_pause_menu); EMU_CALL(a_draw_screen, 11DA, show_pause_menu); EMU_CALL(a_clear_keys, 11DD, show_pause_menu); tmp1 = MEMD(reg_bp - 6); W_MEMD(tick_count, tmp1); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 11F0 void handle_cheat_keys() { RETLOC(125F); RETLOC(125C); RETLOC(1259); RETLOC(124D); RETLOC(124A); RETLOC(1245); RETLOC(122E); RETLOC(1223); RETLOC(120B); assert(reg_eip == 0x11F0); PUSH(bp); MOV(bp, sp); // seg000:11F3 if (MEMB(byte_180AA) != 0 && MEMB(byte_18090) != 0 && MEMB(byte_180B5) != 0) { // seg000:1208 EMU_CALL(a_start_cheating, 120B, handle_cheat_keys); } // seg000:120B if (MEMB(byte_1809E) != 0 && MEMB(byte_18094) != 0 && MEMB(byte_1809C) != 0) { // seg000:1220 EMU_CALL(a_clear_keys, 1223, handle_cheat_keys); PUSHI(1); PUSHI(0x14); EMU_CALL(a_draw_box_opening2, 122E, handle_cheat_keys); reg_sp += 4; // seg000:1231 W_MEMW(god_mode, MEMW(god_mode) ^ 1); if (MEMW(god_mode) != 0) { // seg000:1239 reg_ax = aGodModeEnabled; } else { // seg000:123E reg_ax = aGodModeDisabled; } // seg000:1241 PUSH(ax); EMU_CALL(a_draw_string, 1245, handle_cheat_keys); reg_sp += 2; // seg000:1247 EMU_CALL(a_read_char_with_echo, 124A, handle_cheat_keys); EMU_CALL(a_clear_overlay, 124D, handle_cheat_keys); } else if (MEMB(byte_180B5) != 0) { // seg000:124F // seg000:1256 EMU_CALL(a_save_cur_sound, 1259, handle_cheat_keys); EMU_CALL(a_show_pause_menu, 125C, handle_cheat_keys); EMU_CALL(a_restore_cur_sound, 125F, handle_cheat_keys); } // seg000:125F POP(bp); RET; } // 1261 void chg_vid_and_error() { RETLOC(12CA); RETLOC(12C1); RETLOC(12B3); RETLOC(12AF); RETLOC(1293); RETLOC(1289); RETLOC(127D); RETLOC(1277); RETLOC(126D); assert(reg_eip == 0x1261); PUSH(bp); MOV(bp, sp); PUSH(si); reg_si = MEMW(reg_bp + 4); reg_ax = 3; EMU_INSTR(126B, 126D, chg_vid_and_error); // seg000:126D reg_ax = (char)MEMB(reg_si); // seg000:1270 if (reg_ax == 0) { // seg000:1274 EMU_CALL(a_save_ctrls, 1277, chg_vid_and_error); } else { // seg000:1279 PUSH(si); EMU_CALL(a_puts, 127D, chg_vid_and_error); reg_sp += 2; } // seg000:127F if (MEMW(word_1B00C) != 0) { // seg000:1286 EMU_CALL(a_restore_int9, 1289, chg_vid_and_error); } // seg000:1289 if (MEMW(word_1B016) != 0) { // seg000:1290 EMU_CALL(a_restore_int8, 1293, chg_vid_and_error); } // seg000:1293 reg_ax = (char)MEMB(reg_si); // seg000:1296 if (reg_ax == 0) { // seg000:129A PUSHI(0xfa0); PUSHI(0); PUSHI(0xb800); PUSHI(7); EMU_INSTR(12AC, 12AF, chg_vid_and_error); PUSH(ax); EMU_CALL(a__movedata, 12B3, chg_vid_and_error); reg_sp += 0xa; } // seg000:12B6 PUSHI(0x17); PUSHI(1); EMU_CALL(a__gotoxy, 12C1, chg_vid_and_error); reg_sp += 4; PUSHI(0); EMU_CALL(a__exit, 12CA, chg_vid_and_error); reg_sp += 2; POP(si); POP(bp); RET; } Bit16u dseg; // 12CF void keen_main() { RETLOC(15E5); RETLOC(15BA); RETLOC(15AA); RETLOC(15A1); RETLOC(1598); RETLOC(1593); RETLOC(158A); RETLOC(157A); RETLOC(1570); RETLOC(1562); RETLOC(13BD); RETLOC(13B8); RETLOC(13AF); RETLOC(139F); RETLOC(1396); RETLOC(1390); RETLOC(1382); RETLOC(1379); RETLOC(1369); RETLOC(135A); RETLOC(138B); RETLOC(1355); RETLOC(1311); RETLOC(1322); RETLOC(1300); RETLOC(12EF); RETLOC(12E5); assert(reg_eip == 0x12CF); dseg = SegValue(ds); PUSH(bp); MOV(bp, sp); reg_sp -= 4; PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 6); reg_ax = aCk1; PUSH(ax); PUSHI(MEMW(pExt)); EMU_CALL(a__strcpy, 12E5, keen_main); reg_sp += 4; reg_ax = aLoadingCommand; PUSH(ax); EMU_CALL(a_puts, 12EF, keen_main); reg_sp += 2; reg_ax = reg_bp - 4; PUSH(ax); reg_ax = reg_bp - 2; PUSH(ax); reg_ax = 1; PUSH(ax); EMU_CALL(a_poll_joystick, 1300, keen_main); reg_sp += 6; // seg000:1303 if ((short)MEMW(reg_bp - 2) < 0x1f4) { // seg000:130A reg_ax = aJoystickDetect; PUSH(ax); EMU_CALL(a_puts, 1311, keen_main); reg_sp += 2; W_MEMW(Joystick_Detect, 1); } else { // seg000:131B reg_ax = aJoystickNotDet; PUSH(ax); EMU_CALL(a_puts, 1322, keen_main); reg_sp += 2; W_MEMW(Joystick_Detect, 0); } // seg000:132A W_MEMW(pass_keys_to_bios, 1); // seg000:1330 if ((short)MEMW(reg_bp + 4) > 1) { // seg000:1336 reg_bx = MEMW(reg_di + 2); // seg000:1339 if (MEMB(reg_bx + 1) == 0x4b || MEMB(reg_bx + 1) == 0x6b) { // seg000:1348 W_MEMW(pass_keys_to_bios, 0); reg_ax = aKeystrokesWill; PUSH(ax); EMU_CALL(a_puts, 1355, keen_main); reg_sp += 2; } } // seg000:1357 EMU_CALL(a_detect_video, 135A, keen_main); W_MEMW(video_cap, reg_ax); // seg000:135D if (reg_ax == 3) { // seg000:1362 reg_ax = aEgaCardDetecte; PUSH(ax); EMU_CALL(a_puts, 1369, keen_main); } else if (MEMW(video_cap) == 5) { // seg000:1372 reg_ax = aVgaCardDetecte; PUSH(ax); EMU_CALL(a_puts, 1379, keen_main); } else { // seg000:137B reg_ax = aHeyIDonTSeeAnE; PUSH(ax); EMU_CALL(a_puts, 1382, keen_main); reg_sp += 2; reg_ax = aAnywayYGoAhead; PUSH(ax); EMU_CALL(a_puts, 138B, keen_main); reg_sp += 2; EMU_CALL(a_clear_keys, 1390, keen_main); reg_ax = 0; PUSH(ax); EMU_CALL(a_translate_key, 1396, keen_main); reg_sp += 2; reg_ax = 0xff; PUSH(ax); EMU_CALL(a_sub_CD36, 139F, keen_main); reg_sp += 2; MOV(si, ax); // seg000:13A3 if (reg_ax != 0x59) { // seg000:13A8 reg_ax = 1; PUSH(ax); EMU_CALL(a__exit, 13AF, keen_main); } goto loc_13b1; } // seg000:13AF reg_sp += 2; loc_13b1: // seg000:13B1 reg_ax = aDecompressingGraph; PUSH(ax); EMU_CALL(a_puts, 13B8, keen_main); reg_sp += 2; EMU_CALL(a_decomp_graphics, 13BD, keen_main); reg_si = 0; // seg000:154E // set up animation while ((short)reg_si < (short)MEMW(EGAHEAD_TileNum)) { // for all tiles // seg000:13C2 MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(tileinfo_start + reg_bx); // seg000:13CA if (reg_ax == 1) { // 1 animation frame (no animation) // seg000:13DF MOV(ax, si); reg_cl = 5; reg_ax <<= reg_cl; //ax = tile_num * 32 (tile offset in graphics) MOV(bx, si); reg_bx <<= 1; //bx = tile_num * 2 (tile offset in tileinfo) W_MEMW(anim_frame_tiles_4 + reg_bx, reg_ax); // spaced 1400 bytes apart = 700 words apart MOV(bx, si); // 1 word per tile reg_bx <<= 1; W_MEMW(anim_frame_tiles_3 + reg_bx, reg_ax); MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_2 + reg_bx, reg_ax); MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_1 + reg_bx, reg_ax); } else if (reg_ax == 2) { // seg000:1408 MOV(ax, si); reg_cl = 5; reg_ax <<= reg_cl; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_3 + reg_bx, reg_ax); MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_1 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0x20; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_4 + reg_bx, reg_ax); MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_2 + reg_bx, reg_ax); reg_si++; MOV(ax, si); reg_ax <<= reg_cl; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_3 + reg_bx, reg_ax); MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_1 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax &= 0xffe0; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_4 + reg_bx, reg_ax); MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_2 + reg_bx, reg_ax); } else if (reg_ax == 4) { // seg000:1464 MOV(ax, si); reg_cl = 5; reg_ax <<= reg_cl; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_1 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0x20; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_2 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0x40; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_3 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0x60; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_4 + reg_bx, reg_ax); reg_si++; MOV(ax, si); reg_ax <<= reg_cl; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_1 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0x20; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_2 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0x40; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_3 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0xffe0; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_4 + reg_bx, reg_ax); reg_si++; MOV(ax, si); reg_ax <<= reg_cl; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_1 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0x20; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_2 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0xffc0; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_3 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0xffe0; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_4 + reg_bx, reg_ax); reg_si++; MOV(ax, si); reg_ax <<= reg_cl; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_1 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0xffa0; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_2 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0xffc0; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_3 + reg_bx, reg_ax); MOV(ax, si); reg_ax <<= reg_cl; reg_ax += 0xffe0; MOV(bx, si); reg_bx <<= 1; W_MEMW(anim_frame_tiles_4 + reg_bx, reg_ax); } // seg000:154D reg_si++; } // seg000:1557 reg_ax = aSounds_; PUSH(ax); reg_ax = unk_1B2E0; PUSH(ax); EMU_CALL(a__strcpy, 1562, keen_main); reg_sp += 4; PUSHI(MEMW(pExt)); reg_ax = unk_1B2E0; PUSH(ax); EMU_CALL(a__strcat, 1570, keen_main); reg_sp += 4; reg_ax = unk_1B2E0; PUSH(ax); EMU_CALL(a_alloc_and_map_file, 157A, keen_main); reg_sp += 2; W_MEMW(word_1818F, reg_ax); W_MEMW(sound_data_hi, reg_dx); reg_ax = 1; PUSH(ax); EMU_CALL(a_init_rnd, 158A, keen_main); reg_sp += 2; reg_ax = 1; PUSH(ax); EMU_CALL(a_sub_C013, 1593, keen_main); reg_sp += 2; EMU_CALL(a_setup_int8, 1598, keen_main); W_MEMW(word_1B016, 1); EMU_CALL(a_setup_int9, 15A1, keen_main); W_MEMW(word_1B00C, 1); EMU_CALL(a_init_ctrls, 15AA, keen_main); W_MEMW(ctrl_type, 0); reg_ax = 1; reg_dx = 0; PUSH(ax); PUSH(dx); EMU_CALL(a_sub_5C58, 15BA, keen_main); reg_sp += 4; W_MEMW(level_data, reg_ax); W_MEMW(level_data + 2, reg_dx); W_MEMW(word_1551E, 0x17); W_MEMW(word_19CB2, 7); reg_ax = 0; reg_dx = 0; W_MEMW(tick_count_2, reg_dx); W_MEMW(tick_count_2 + 2, reg_ax); W_MEMW(tick_count, reg_dx); W_MEMW(tick_count + 2, reg_ax); EMU_CALL(a_main_loop, 15E5, keen_main); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 15EB void init_level() { RETLOC(1692); RETLOC(16AE); RETLOC(16A0); RETLOC(16C6); RETLOC(16BC); RETLOC(1685); RETLOC(167B); RETLOC(1671); RETLOC(1666); RETLOC(165B); RETLOC(15F8); PUSH(bp); MOV(bp, sp); reg_sp -= 2; PUSH(si); PUSH(di); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_load_level_data, 15F8, init_level); reg_sp += 2; reg_di = 0; // seg000:16FA while ((short)reg_di < (short)MEMW(map_height_in_tiles)) { // seg000:15FF reg_si = 0; // seg000:16F0 while ((short)reg_si < (short)MEMW(map_width_intiles)) { // seg000:1604 MOV(ax, di); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_si; reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 2, reg_ax); reg_bx = MEMW(reg_bp - 2); // seg000:161D if (reg_bx != 6) { // seg000:1622 if ((short)reg_bx <= 6) { // seg000:1624 reg_bx--; // seg000:1625 if (reg_bx <= 4) { // seg000:162D switch(reg_bx) { case 0: // seg000:1656 PUSH(di); PUSH(si); EMU_CALL(a_add_monster_5, 165B, init_level); reg_sp += 4; break; case 1: // seg000:1661 PUSH(di); PUSH(si); EMU_CALL(a_add_monster_4, 1666, init_level); break; case 2: // seg000:166C PUSH(di); PUSH(si); EMU_CALL(a_add_monster_5, 1671, init_level); reg_sp += 4; break; case 3: // seg000:1676 PUSH(di); PUSH(si); EMU_CALL(a_add_monster_2, 167B, init_level); reg_sp += 4; break; case 4: // seg000:1680 PUSH(di); PUSH(si); EMU_CALL(a_add_monster_1_tank_bot, 1685, init_level); reg_sp += 4; break; } } } else if (reg_bx == 9) { // seg000:16B3 PUSHI(3); PUSH(di); PUSH(si); EMU_CALL(a_add_special_body, 16BC, init_level); reg_sp += 6; } else if ((short)reg_bx > 9) { // seg000:1648 if (reg_bx == 0xa) { // seg000:16C1 PUSH(di); PUSH(si); EMU_CALL(a_add_monster_6, 16C6, init_level); reg_sp += 4; } else if (reg_bx == 0xff) { // seg000:16CB int tmp1 = (short)reg_si; tmp1 <<= 0xc; W_MEMD(keen_pos_x, tmp1); tmp1 = (short)reg_di; tmp1 <<= 0xc; tmp1 += 0x800; W_MEMD(keen_pos_y, tmp1); } } else if (reg_bx == 7) { // seg000:1697 PUSHI(1); PUSH(di); PUSH(si); EMU_CALL(a_add_special_body, 16A0, init_level); reg_sp += 6; } else if (reg_bx == 8) { // seg000:16A5 PUSHI(2); PUSH(di); PUSH(si); EMU_CALL(a_add_special_body, 16AE, init_level); reg_sp += 6; } } else { // seg000:168A Ice cube cannon up right PUSHI(0); PUSH(di); PUSH(si); EMU_CALL(a_add_special_body, 1692, init_level); reg_sp += 6; } // seg000:16EF reg_si++; } // seg000:16F9 reg_di++; } // seg000:1703 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 1713 void add_monster_1_tank_bot() { RETLOC(171A); assert(reg_eip == 0x1713); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_monster, 171A, add_monster_1_tank_bot); MOV(si, ax); W_MEMW(reg_si, 6); // seg000:1720 reg_ax = MEMW(reg_bp + 4); int tmp1 = (short)reg_ax; tmp1 <<= 0xc; W_MEMD(reg_si + 4, tmp1); // seg000:172F reg_ax = MEMW(reg_bp + 6); tmp1 = (short)reg_ax; tmp1 <<= 0xc; tmp1 += 0x800; W_MEMD(reg_si + 8, tmp1); // seg000:1744 W_MEMW(reg_si + 32, 0x5a); tmp1 = MEMD(reg_si + 4); // seg000:174F if (tmp1 < (int)MEMD(keen_pos_x)) { // seg000:175D reg_ax = MEMW(reg_si + 32); reg_ax = -(short)reg_ax; W_MEMW(reg_si + 32, reg_ax); } // seg000:1765 W_MEMW(reg_si + 50, a_think_1_tankbot_def); W_MEMW(reg_si + 52, a_contact_nop); W_MEMW(reg_si + 40, 0x6a); POP(si); POP(bp); RET; } // 1777 void add_monster_2() { RETLOC(177E); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_monster, 177E, add_monster_2); MOV(si, ax); W_MEMW(reg_si, 5); int tmp1 = (short)MEMW(reg_bp + 4); tmp1 <<= 0xc; W_MEMD(reg_si + 4, tmp1); tmp1 = (short)MEMW(reg_bp + 6); tmp1 <<= 0xc; W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 32, 0x5a); tmp1 = MEMD(reg_si + 4); if (tmp1 < (int)MEMD(keen_pos_x)) { // seg000:17BB reg_ax = MEMW(reg_si + 32); reg_ax = -(short)reg_ax; W_MEMW(reg_si + 32, reg_ax); } // seg000:17C3 W_MEMW(reg_si + 50, a_think_2); W_MEMW(reg_si + 52, a_contact_2); W_MEMW(reg_si + 40, 0x60); POP(si); POP(bp); RET; } // vorticon // 17D5 void add_monster_3() { RETLOC(17DC); assert(reg_eip == 0x17d5); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_monster, 17DC, add_monster_3); MOV(si, ax); W_MEMW(reg_si, 4); reg_ax = MEMW(reg_bp + 4); int tmp1 = (short)reg_ax; tmp1 <<= 0xc; W_MEMD(reg_si + 4, tmp1); reg_ax = MEMW(reg_bp + 6); tmp1 = (short)reg_ax; tmp1 <<= 0xc; W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 50, a_think_3); W_MEMW(reg_si + 52, a_contact_3); W_MEMW(reg_si + 36, 3); // seg000:180F if (MEMW(current_level) == 0x10) { // seg000:1816 W_MEMW(reg_si + 36, 0x68); } // seg000:181B tmp1 = MEMD(reg_si + 4); // seg000:1821 if (tmp1 > (int)MEMD(keen_pos_x)) { // seg000:182F W_MEMW(reg_si + 32, 0xffa6); } else { // seg000:1836 W_MEMW(reg_si + 32, 0x5a); } // seg000:183B W_MEMW(reg_si + 40, 0x4e); POP(si); POP(bp); RET; } // 1843 void add_monster_4() { RETLOC(184A); assert(reg_eip == 0x1843); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_monster, 184A, add_monster_4); // seg000:184A MOV(si, ax); W_MEMW(reg_si, 3); reg_ax = MEMW(reg_bp + 4); int tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; W_MEMD(reg_si + 4, tmp1); // seg000:185F reg_ax = MEMW(reg_bp + 6); tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; W_MEMD(reg_si + 8, tmp1); // seg000:186E W_MEMW(reg_si + 50, a_think_4_garg_look); W_MEMW(reg_si + 52, a_contact_4); W_MEMW(reg_si + 40, 0x3c); // seg000:187D POP(si); POP(bp); RET; } // yorp // 1880 void add_monster_5() { RETLOC(1887); assert(reg_eip == 0x1880); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_monster, 1887, add_monster_5); MOV(si, ax); W_MEMW(reg_si, 2); reg_ax = MEMW(reg_bp + 4); int tmp1 = (short)reg_ax; tmp1 = tmp1 << 12; W_MEMD(reg_si + 4, tmp1); reg_ax = MEMW(reg_bp + 6); tmp1 = (short)reg_ax; tmp1 = tmp1 << 12; tmp1 += 2048; W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 50, a_think_yorp_walk); tmp1 = MEMD(reg_si + 4); if (tmp1 < (int)MEMD(keen_pos_x)) { // seg000:18CA W_MEMW(reg_si + 32, 0x3c); } else { // seg000:18D1 W_MEMW(reg_si + 32, 0xffc4); } // seg000:18D6 W_MEMW(reg_si + 52, a_contact_5_yorp); W_MEMW(reg_si + 40, 0x30); POP(si); POP(bp); RET; } // 18E3 void add_monster_6() { RETLOC(18EA); assert(reg_eip == 0x18E3); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_monster, 18EA, add_monster_6); // seg000:18EA MOV(si, ax); W_MEMW(reg_si, 8); reg_ax = MEMW(reg_bp + 4); int tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; W_MEMD(reg_si + 4, tmp1); // seg000:18FF reg_ax = MEMW(reg_bp + 6); tmp1 = (short)reg_ax; tmp1 = tmp1 << 0xc; W_MEMD(reg_si + 8, tmp1); // seg000:190E W_MEMW(reg_si + 50, a_think_contact_nop); W_MEMW(reg_si + 52, a_contact_6); W_MEMW(reg_si + 40, 0x72); // seg000:191D POP(si); POP(bp); RET; } // 19D3 void think_yorp_look() { RETLOC(1A2A); RETLOC(1A27); assert(reg_eip == 0x19D3); PUSH(bp); MOV(bp, sp); W_MEMW(sprite_copy.vel_x, 0); reg_ax = ((MEMW(tick_count) >> 5) & 3) + 0x30; W_MEMW(sprite_copy.cur_frame, reg_ax); // seg000:19EC reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:19F6 if ((short)reg_ax >= 0xc8) { // seg000:19FB int tmp1 = MEMD(sprite_copy.pos_x_lo); if ((int)tmp1 <= (int)MEMD(keen_pos_x)) { // seg000:1A10 W_MEMW(sprite_copy.vel_x, 0x3c); } else { // seg000:1A18 W_MEMW(sprite_copy.vel_x, 0xffc4); } // seg000:1A1E W_MEMW(sprite_copy.think_func, a_think_yorp_walk); } // seg000:1A24 EMU_CALL(a_do_fall, 1A27, think_yorp_look); EMU_CALL(a_compute_sprite_delta, 1A2A, think_yorp_look); POP(bp); RET; } // 1A2C void think_20_yorp_incapacitated() { RETLOC(1A66); RETLOC(1A63); assert(reg_eip == 0x1a2c); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(tick_count); reg_cl = 4; reg_ax >>= reg_cl; reg_ax &= 1; reg_ax += 0x38; W_MEMW(sprite_copy.cur_frame, reg_ax); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seems to count how long the yorp has been incapacitated. // seg000:1A49 if ((short)reg_ax >= 0x320) { W_MEMW(sprite_copy.sync_time, 0); W_MEMW(sprite_copy.think_func, a_think_yorp_look); } // seg000:1A5A W_MEMW(sprite_copy.vel_x, 0); EMU_CALL(a_do_fall, 1A63, think_20_yorp_incapacitated); EMU_CALL(a_compute_sprite_delta, 1A66, think_20_yorp_incapacitated); POP(bp); RET; } // 1AA8 void think_22_garg_move() { RETLOC(1B07); RETLOC(1B04); RETLOC(1AC6); assert(reg_eip == 0x1AA8); PUSH(bp); MOV(bp, sp); PUSH(si); // seg000:1AAC if (MEMW(sprite_copy.vel_y) == 0 && (short)MEMW(sprite_copy.vel_x) > -220 && (short)MEMW(sprite_copy.vel_x) < 220) { // seg000:1AC3 EMU_CALL(a_get_random, 1AC6, think_22_garg_move); // seg000:1AC6 if (reg_ax < MEMW(sprite_sync)) { // seg000:1ACC W_MEMW(sprite_copy.think_func, a_think_4_garg_look); W_MEMW(sprite_copy.sync_time, 0); } } // seg000:1AD8 if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:1ADF W_MEMW(sprite_copy.cur_frame, 0x40); } else { // seg000:1AE7 W_MEMW(sprite_copy.cur_frame, 0x42); } // seg000:1AED reg_ax = MEMW(tick_count); reg_ax >>= 4; reg_ax &= 1; reg_dx = MEMW(sprite_copy.cur_frame); reg_dx += reg_ax; W_MEMW(sprite_copy.cur_frame, reg_dx); EMU_CALL(a_do_fall, 1B04, think_22_garg_move); EMU_CALL(a_compute_sprite_delta, 1B07, think_22_garg_move); MOV (si, ax); // seg000:1B09 if (reg_ax & 4) { // seg000:1B0E W_MEMW(sprite_copy.vel_x, 0xffc4); } // seg000:1B14 if (reg_si & 1) { // seg000:1B1A W_MEMW(sprite_copy.vel_x, 0x3c); } // seg000:1B20 if (reg_si & 2) { // seg000:1B1A W_MEMW(sprite_copy.sync_time, 0); } else { // seg000:1B2E int tmp1 = (short)MEMW(sprite_copy.vel_x); reg_ax = (tmp1 & 0xffff) ^ (tmp1 >> 16); reg_ax -= (tmp1 >> 16); // seg000:1B36 if (reg_ax == 0xdc && MEMW(sprite_copy.sync_time) == 0) { // seg000:1B42 W_MEMW(sprite_copy.sync_time, 1); W_MEMW(sprite_copy.vel_y, 0xFF38); } } // seg000:1B4E POP(si); POP(bp); RET; } // 1B51 void think_4_garg_look() { RETLOC(1B7A); RETLOC(1B77); assert(reg_eip == 0x1B51); PUSH(bp); MOV(bp, sp); W_MEMW(sprite_copy.vel_x, 0); reg_ax = MEMW(tick_count); reg_ax >>= 5; reg_ax &= 3; reg_ax += 0x3c; W_MEMW(sprite_copy.cur_frame, reg_ax); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); EMU_CALL(a_do_fall, 1B77, think_4_garg_look); EMU_CALL(a_compute_sprite_delta, 1B7A, think_4_garg_look); // seg000:1B7A if ((short)MEMW(sprite_copy.sync_time) >= 0x50) { // seg000:1B81 int tmp1 = MEMD(sprite_copy.pos_y_lo); tmp1 += 0x800; // seg000:1B8F if (tmp1 == MEMD(keen_pos_y)) { // seg000:1B9B W_MEMW(sprite_copy.vel_x, 0xdc); } else { // seg000:1BA3 W_MEMW(sprite_copy.vel_x, 0x3c); } // seg000:1BA9 tmp1 = MEMD(sprite_copy.pos_x_lo); if (tmp1 > (int)MEMD(keen_pos_x)) { // seg000:1BBE reg_ax = MEMW(sprite_copy.vel_x); reg_ax = -(short)reg_ax; W_MEMW(sprite_copy.vel_x, reg_ax); } // seg000:1BC6 W_MEMW(sprite_copy.think_func, a_think_22_garg_move); } // seg000:1BCC POP(bp); RET; } // 1BCE void contact_4() { RETLOC(1C08); assert(reg_eip == 0x1BCE); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_di = MEMW(reg_bp + 6); // seg000:1BD9 if (MEMW(reg_di) == 0xa || MEMW(reg_di) == 0xb) { // seg000:1BE3 W_MEMW(reg_si + 42, 0); W_MEMW(reg_si + 44, 2); W_MEMW(reg_si + 40, 0x44); W_MEMW(reg_si + 50, a_think_12); W_MEMW(reg_si + 52, a_think_contact_nop); W_MEMW(reg_si + 34, 0xffb0); PUSHI(0x23); EMU_CALL(a_set_cur_sound, 1C08, contact_4); reg_sp += 2; } // seg000:1C0A POP(di); POP(si); POP(bp); RET; } // 1C0E void think_3() { RETLOC(1CAC); RETLOC(1CA9); RETLOC(1C61); RETLOC(1C4F); RETLOC(1C3E); assert(reg_eip == 0x1c0e); PUSH(bp); MOV(bp, sp); PUSH(si); // seg000:1C12 if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:1C19 W_MEMW(sprite_copy.cur_frame, 0x4a); } else { // seg000:1C21 W_MEMW(sprite_copy.cur_frame, 0x46); } // seg000:1C27 reg_ax = MEMW(tick_count); reg_ax >>= 4; reg_ax &= 3; reg_dx = MEMW(sprite_copy.cur_frame); reg_dx += reg_ax; W_MEMW(sprite_copy.cur_frame, reg_dx); EMU_CALL(a_get_random, 1C3E, think_3); reg_dx = MEMW(sprite_sync); reg_dx <<= 1; // seg000:1C44 if (reg_ax < reg_dx) { // seg000:1C48 PUSHI(0x12c); EMU_CALL(a_calc_jump_height, 1C4F, think_3); reg_sp += 2; reg_ax = -(short)reg_ax; W_MEMW(sprite_copy.vel_y, reg_ax); W_MEMW(sprite_copy.think_func, a_think_23); } else { // seg000:1C5E EMU_CALL(a_get_random, 1C61, think_3); reg_dx = MEMW(sprite_sync); reg_dx <<= 1; // seg000:1C67 if (reg_ax < reg_dx) { // seg000:1C6B reg_ax = MEMW(sprite_copy.vel_x); // seg000:1C6E if (reg_ax == 0x5a) { // seg000:1C98 W_MEMW(sprite_copy.vel_x, 0x78); } else if (reg_ax == 0x78) { // seg000:1CA0 W_MEMW(sprite_copy.vel_x, 0x5a); } else if (reg_ax == 0xff88) { // seg000:1C90 W_MEMW(sprite_copy.vel_x, 0xffa6); } else if (reg_ax == 0xffa6) { // seg000:1C88 W_MEMW(sprite_copy.vel_x, 0xff88); } } } // seg000:1CA6 EMU_CALL(a_do_fall, 1CA9, think_3); EMU_CALL(a_compute_sprite_delta, 1CAC, think_3); MOV(si, ax); // seg000:1CAE if (reg_ax & 4) { // seg000:1CB3 W_MEMW(sprite_copy.vel_x, 0xffa6); } // seg000:1CB9 if (reg_si & 1) { // seg000:1CBF W_MEMW(sprite_copy.vel_x, 0x5a); } // seg000:1CC5 POP(si); POP(bp); RET; } // 1CC8 void think_23() { RETLOC(1CE7); RETLOC(1CE4); assert(reg_eip == 0x1cc8); PUSH(bp); MOV(bp, sp); PUSH(si); // seg000:1CCC if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:1CD3 W_MEMW(sprite_copy.cur_frame, 0x50); } else { // seg000:1CDB W_MEMW(sprite_copy.cur_frame, 0x51); } // seg000:1CE1 EMU_CALL(a_do_fall, 1CE4, think_23); EMU_CALL(a_compute_sprite_delta, 1CE7, think_23); MOV(si, ax); // seg000:1CE9 if (reg_ax != 2) { // seg000:1CEE W_MEMW(sprite_copy.think_func, a_think_24_vort_search); W_MEMW(sprite_copy.sync_time, 0); } // seg000:1CFA if (reg_si & 4) { // seg000:1D00 W_MEMW(sprite_copy.vel_x, 0xffa6); } // seg000:1D06 if (reg_si & 1) { // seg000:1D0C W_MEMW(sprite_copy.vel_x, 0x5a); } // seg000:1D12 POP(si); POP(bp); RET; } // 1D15 void think_24_vort_search() { RETLOC(1D6C); RETLOC(1D69); assert(reg_eip == 0x1d15); PUSH(bp); MOV(bp, sp); W_MEMW(sprite_copy.vel_x, 0); reg_ax = MEMW(tick_count); reg_ax >>= 5; reg_ax &= 3; reg_ax += 0x4e; W_MEMW(sprite_copy.cur_frame, reg_ax); // seg000:1D2E reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:1D38 if ((short)reg_ax >= 0x50) { // seg000:1D3D W_MEMW(sprite_copy.vel_x, 0x5a); int tmp1 = MEMD(sprite_copy.pos_x_lo); // seg000:1D4A if (tmp1 > (int)MEMD(keen_pos_x)) { // seg000:1D58 reg_ax = MEMW(sprite_copy.vel_x); reg_ax = -(short)reg_ax; W_MEMW(sprite_copy.vel_x, reg_ax); } // seg000:1D60 W_MEMW(sprite_copy.think_func, a_think_3); } // seg000:1D66 EMU_CALL(a_do_fall, 1D69, think_24_vort_search); EMU_CALL(a_compute_sprite_delta, 1D6C, think_24_vort_search); POP(bp); RET; } // 1D6E void contact_3() { RETLOC(1DB2); RETLOC(1D94); assert(reg_eip == 0x1D6E); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_bx = MEMW(reg_bp + 6); // seg000:1D79 if (MEMW(reg_bx) == 0xa || MEMW(reg_bx) == 0xb) { // seg000:1D83 reg_ax = MEMW(reg_si + 36); W_MEMW(reg_si + 36, MEMW(reg_si + 36) - 1); // seg000:1D89 if (reg_ax == 0) { // seg000:1D8D PUSHI(0x27); EMU_CALL(a_set_cur_sound, 1D94, contact_3); reg_sp += 2; W_MEMW(reg_si + 42, 0); W_MEMW(reg_si + 44, 6); W_MEMW(reg_si + 40, 0x52); W_MEMW(reg_si + 52, a_think_contact_nop); W_MEMW(reg_si + 50, a_think_12); EMU_CALL(a_add_body, 1DB2, contact_3); MOV(di, ax); W_MEMW(reg_di + 8, 5); W_MEMW(reg_di + 34, a_think_body_3); W_MEMW(reg_di + 10, 0); } } // seg000:1DC3 POP(di); POP(si); POP(bp); RET; } // 1DC7 void think_2() { RETLOC(1DFA); RETLOC(1DF7); assert(reg_eip == 0x1DC7); PUSH(bp); MOV(bp, sp); PUSH(si); // seg000:1DCB if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:1DD2 W_MEMW(sprite_copy.cur_frame, 0x58); } else { // seg000:1DDA W_MEMW(sprite_copy.cur_frame, 0x5c); } // seg000:1DE0 reg_ax = MEMW(tick_count); reg_ax >>= 5; reg_ax &= 3; reg_dx = MEMW(sprite_copy.cur_frame); reg_dx += reg_ax; W_MEMW(sprite_copy.cur_frame, reg_dx); EMU_CALL(a_do_fall, 1DF7, think_2); EMU_CALL(a_compute_sprite_delta, 1DFA, think_2); MOV(si, ax); // seg000:1DFC if ((reg_ax & 2) == 0) { // seg000:1E01 reg_ax = MEMW(sprite_copy.delta_x); reg_ax = -(short)reg_ax; reg_ax <<= 1; W_MEMW(sprite_copy.delta_x, reg_ax); W_MEMW(sprite_copy.delta_y, 0); reg_ax = MEMW(sprite_copy.vel_x); reg_ax = -(short)reg_ax; W_MEMW(sprite_copy.frame_countdown, reg_ax); W_MEMW(sprite_copy.think_func, a_think_25); W_MEMW(sprite_copy.vel_x, 0); W_MEMW(sprite_copy.sync_time, 0); } // seg000:1E27 if (reg_si & 4) { // seg000:1E2D W_MEMW(sprite_copy.frame_countdown, 0xffa6); W_MEMW(sprite_copy.think_func, a_think_25); W_MEMW(sprite_copy.vel_x, 0); W_MEMW(sprite_copy.sync_time, 0); } // seg000:1E41 if (reg_si & 1) { // seg000:1E47 W_MEMW(sprite_copy.frame_countdown, 0x5a); W_MEMW(sprite_copy.think_func, a_think_25); W_MEMW(sprite_copy.vel_x, 0); W_MEMW(sprite_copy.sync_time, 0); } // seg000:1E5B POP(si); POP(bp); RET; } // 1E5E void think_25() { RETLOC(1E92); RETLOC(1E8F); assert(reg_eip == 0x1e5e); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:1E6B if ((short)reg_ax > 0x32) { // seg000:1E70 W_MEMW(sprite_copy.think_func, a_think_2); reg_ax = MEMW(sprite_copy.frame_countdown); W_MEMW(sprite_copy.vel_x, reg_ax); } // seg000:1E7C reg_ax = ((MEMW(tick_count) >> 5) & 1) + 0x60; W_MEMW(sprite_copy.cur_frame, reg_ax); EMU_CALL(a_do_fall, 1E8F, think_25); EMU_CALL(a_compute_sprite_delta, 1E92, think_25); POP(bp); RET; } // 1E94 void contact_2() { PUSH(bp); MOV(bp, sp); reg_bx = MEMW(reg_bp + 6); // seg000:1E9A if (MEMW(reg_bx) == 0xa) { // seg000:1E9F reg_bx = MEMW(reg_bp + 4); W_MEMW(reg_bx + 0x2a, 0); } // seg000:1EA7 POP(bp); RET; } // 1EA9 void think_28_tankbot_move() { RETLOC(1F05); RETLOC(1F02); RETLOC(1EDB); assert(reg_eip == 0x1EA9); PUSH(bp); MOV(bp, sp); PUSH(si); // seg000:1EAD if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:1EB4 W_MEMW(sprite_copy.cur_frame, 0x62); } else { // seg000:1EBC W_MEMW(sprite_copy.cur_frame, 0x66); } // seg000:1EC2 reg_ax = MEMW(tick_count); reg_ax >>= 3; reg_ax &= 3; reg_dx = MEMW(sprite_copy.cur_frame); reg_dx += reg_ax; W_MEMW(sprite_copy.cur_frame, reg_dx); EMU_CALL(a_get_random, 1EDB, think_28_tankbot_move); // seg000:1EDB if (reg_ax < MEMW(sprite_sync)) { // seg000:1EE1 W_MEMW(sprite_copy.think_func, a_think_26_tankbot_shoot); W_MEMW(sprite_copy.sync_time, 0); W_MEMW(sprite_copy.frame_countdown, 0); reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(sprite_copy.unk_w_1, reg_ax); W_MEMW(sprite_copy.vel_x, 0); } // seg000:1EFF EMU_CALL(a_do_fall, 1F02, think_28_tankbot_move); EMU_CALL(a_compute_sprite_delta, 1F05, think_28_tankbot_move); // seg000:1F05 MOV(si, ax); W_MEMW(sprite_copy.vel_y, 0); W_MEMW(sprite_copy.delta_y, 0); // seg000:1F0F if ((reg_si & 2) == 0) { // seg000:1F15 if ((short)MEMW(sprite_copy.cur_frame) < 0x66) { // seg000:1F1C reg_ax = MEMW(sprite_sync); reg_ax *= 0xff4c; W_MEMW(sprite_copy.delta_x, reg_ax); W_MEMW(sprite_copy.frame_countdown, 0xffa6); } else { // seg000:1F2F reg_ax = MEMW(sprite_sync); reg_ax *= 0xb4; W_MEMW(sprite_copy.delta_x, reg_ax); // from seg000:1F58 W_MEMW(sprite_copy.frame_countdown, 0x5a); } } else { // seg000:1F3E if (reg_si & 4) { // seg000:1F44 W_MEMW(sprite_copy.frame_countdown, 0xffa6); W_MEMW(sprite_copy.think_func, a_think_27_tankbot_turn); W_MEMW(sprite_copy.vel_x, 0); W_MEMW(sprite_copy.sync_time, 0); } // seg000:1F58 if (reg_si & 1) { // seg000:1F5E W_MEMW(sprite_copy.frame_countdown, 0x5a); } else { // from seg000:1F72 POP(si); POP(bp); RET; } } // seg000:1F64 W_MEMW(sprite_copy.think_func, a_think_27_tankbot_turn); W_MEMW(sprite_copy.vel_x, 0); W_MEMW(sprite_copy.sync_time, 0); // seg000:1F72 POP(si); POP(bp); RET; } // 1F75 void think_1_tankbot_default() { RETLOC(1F7F); RETLOC(1F7C); assert(reg_eip == 0x1f75); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_do_fall, 1F7C, think_1_tankbot_default); EMU_CALL(a_compute_sprite_delta, 1F7F, think_1_tankbot_default); MOV(si, ax); // seg000:1F81 if (reg_ax & 2) { // seg000:1F86 W_MEMW(sprite_copy.think_func, a_think_28_tankbot_move); } // seg000:1F8C POP(si); POP(bp); RET; } // 1F8F void think_27_tankbot_turn() { PUSH(bp); MOV(bp, sp); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); reg_ax = ((MEMW(tick_count) >> 4) & 1) + 0x6a; W_MEMW(sprite_copy.cur_frame, reg_ax); // seg000:1FAC if ((short)MEMW(sprite_copy.sync_time) > 0x32) { // seg000:1FB3 W_MEMW(sprite_copy.think_func, a_think_28_tankbot_move); reg_ax = MEMW(sprite_copy.frame_countdown); W_MEMW(sprite_copy.vel_x, reg_ax); } // seg000:1FBF POP(bp); RET; } // 1FC1 void think_26_tankbot_shoot_tankbot_shoot() { RETLOC(2005); RETLOC(1FE2); assert(reg_eip == 0x1fc1); PUSH(bp); MOV(bp, sp); PUSH(si); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:1FCF if (MEMW(sprite_copy.frame_countdown) == 0 && (short)reg_ax > 0x50) { // seg000:1FDB PUSHI(0x26); EMU_CALL(a_set_cur_sound, 1FE2, think_26_tankbot_shoot); reg_sp += 2; reg_si = 0x15e; // seg000:1FE7 if ((short)MEMW(sprite_copy.unk_w_1) < 0) { // seg000:1FEE reg_si = 0xfea2; } // seg000:1FF1 PUSH(si); PUSHI(MEMW(sprite_copy.pos_y_hi)); PUSHI(MEMW(sprite_copy.pos_y_lo)); PUSHI(MEMW(sprite_copy.pos_x_hi)); PUSHI(MEMW(sprite_copy.pos_x_lo)); EMU_CALL(a_add_monster_9_tank_shot, 2005, think_26_tankbot_shoot); reg_sp += 0xa; W_MEMW(sprite_copy.frame_countdown, 1); } // seg000:200E if ((short)MEMW(sprite_copy.sync_time) > 0x78) { // seg000:2015 W_MEMW(sprite_copy.frame_countdown, 0x5a); int tmp1 = MEMD(sprite_copy.pos_x_lo); if (tmp1 > (int)MEMD(keen_pos_x)) { // seg000:2030 W_MEMW(sprite_copy.frame_countdown, 0xffa6); } // seg000:2036 W_MEMW(sprite_copy.sync_time, 0); W_MEMW(sprite_copy.think_func, a_think_27_tankbot_turn); } // seg000:2042 POP(si); POP(bp); RET; } // 2045 void contact_nop() { PUSH(bp); MOV(bp, sp); POP(bp); RET; } // 204A void think_15() { RETLOC(20C2); RETLOC(20A1); assert(reg_eip == 0x204A); PUSH(bp); MOV(bp, sp); reg_sp -= 2; PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_ax = MEMW(tick_count); reg_ax >>= 7; // seg000:205B if (reg_ax != MEMW(reg_si + 0xc)) { // seg000:2060 reg_ax = MEMW(tick_count); reg_ax >>= 7; W_MEMW(reg_si + 0xc, reg_ax); reg_ax = MEMW(reg_si); W_MEMW(reg_bp - 2, reg_ax); reg_di = MEMW(reg_si + 4); reg_ax = MEMW(word_186A6); reg_ax += 0xfffc; // seg000:2076 if ((short)reg_ax < (short)MEMW(reg_bp - 2)) { // seg000:207B reg_ax = MEMW(word_18B62); reg_ax += 0xfffc; // seg000:2081 if ((short)reg_ax < (short)reg_di) { // seg000:2085 reg_ax = MEMW(word_186A6); reg_ax += 0x18; // seg000:208B if ((short)reg_ax > (short)MEMW(reg_bp - 2)) { // seg000:2090 reg_ax = MEMW(word_18B62); reg_ax += 0xe; // seg000:2096 if ((short)reg_ax > (short)reg_di) { // seg000:209A PUSHI(0x17); EMU_CALL(a_set_cur_sound, 20A1, think_15); reg_sp += 2; PUSHI(MEMW(reg_si + 0xa)); int tmp1 = MEMD(reg_si + 4); tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_si); tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a_add_monster_7, 20C2, think_15); reg_sp += 0xa; } } } } } // seg000:20C5 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 20CB void add_monster_7() { RETLOC(20D2); assert(reg_eip == 0x20cb); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_monster, 20D2, add_monster_7); MOV(si, ax); W_MEMW(reg_si, 0xf); int tmp1 = MEMD(reg_bp + 4); W_MEMD(reg_si + 4, tmp1); tmp1 = MEMD(reg_bp + 8); W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 50, a_think_7); reg_bx = MEMW(reg_bp + 12); // seg000:20F8 if (reg_bx <= 3) { switch(reg_bx) { case 0: // seg000:2104 W_MEMD(reg_si + 4, MEMD(reg_si + 4) + 0x1000); W_MEMW(reg_si + 34, 0xff38); W_MEMW(reg_si + 32, 0xc8); break; case 1: // seg000:2119 W_MEMW(reg_si + 34, 0xff38); W_MEMW(reg_si + 32, 0); break; case 2: // seg000:2125 W_MEMW(reg_si + 34, 0xc8); W_MEMW(reg_si + 32, 0); break; case 3: // seg000:2131 W_MEMW(reg_si + 34, 0xff38); W_MEMW(reg_si + 32, 0xff38); break; } } // seg000:213B W_MEMW(reg_si + 52, a_contact_7); W_MEMW(reg_si + 40, 0x70); POP(si); POP(bp); RET; } // 2151 void think_8() { RETLOC(216E); assert(reg_eip == 0x2151); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:215E if ((short)reg_ax > 0x3c) { // seg000:2163 W_MEMW(sprite_copy.type, 0); } else { // seg000:216B EMU_CALL(a_do_fall, 216E, think_8); reg_ax = MEMW(sprite_copy.vel_x); reg_ax *= MEMW(sprite_sync); reg_dx = MEMW(sprite_copy.delta_x); reg_dx += reg_ax; W_MEMW(sprite_copy.delta_x, reg_dx); reg_ax = MEMW(sprite_copy.vel_y); reg_ax *= MEMW(sprite_sync); reg_dx = MEMW(sprite_copy.delta_y); reg_dx += reg_ax; W_MEMW(sprite_copy.delta_y, reg_dx); } // seg000:2190 POP(bp); RET; } // 2192 void think_7() { RETLOC(22A0); RETLOC(2260); RETLOC(2224); RETLOC(21E8); RETLOC(21AC); RETLOC(219A); assert(reg_eip == 0x2192); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); EMU_CALL(a_compute_sprite_delta, 219A, think_7); MOV(di, ax); // seg000:219C if (reg_ax != 0) { // seg000:21A3 W_MEMW(sprite_copy.type, 0); EMU_CALL(a_add_monster, 21AC, think_7); MOV(si, ax); W_MEMW(reg_si, 0xc); W_MEMW(reg_si + 50, a_think_8); W_MEMW(reg_si + 52, a_think_contact_nop); int tmp1 = MEMD(sprite_copy.pos_x_lo); W_MEMD(reg_si + 4, tmp1); tmp1 = MEMD(sprite_copy.pos_y_lo); W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 32, 0x12c); W_MEMW(reg_si + 34, 0x12c); W_MEMW(reg_si + 40, 0x71); EMU_CALL(a_add_monster, 21E8, think_7); MOV(si, ax); W_MEMW(reg_si, 0xc); W_MEMW(reg_si + 50, a_think_8); W_MEMW(reg_si + 52, a_think_contact_nop); tmp1 = MEMD(sprite_copy.pos_x_lo); W_MEMD(reg_si + 4, tmp1); tmp1 = MEMD(sprite_copy.pos_y_lo); W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 32, 0x12c); W_MEMW(reg_si + 34, 0xfed4); W_MEMW(reg_si + 40, 0x71); EMU_CALL(a_add_monster, 2224, think_7); MOV(si, ax); W_MEMW(reg_si, 0xc); W_MEMW(reg_si + 50, a_think_8); W_MEMW(reg_si + 52, a_think_contact_nop); tmp1 = MEMD(sprite_copy.pos_x_lo); W_MEMW(reg_si + 4, tmp1); tmp1 = MEMD(sprite_copy.pos_y_lo); W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 32, 0xfed4); W_MEMW(reg_si + 34, 0x12c); W_MEMW(reg_si + 40, 0x71); EMU_CALL(a_add_monster, 2260, think_7); MOV(si, ax); W_MEMW(reg_si, 0xc); W_MEMW(reg_si + 50, a_think_8); W_MEMW(reg_si + 52, a_think_contact_nop); tmp1 = MEMD(sprite_copy.pos_x_lo); W_MEMW(reg_si + 4, tmp1); tmp1 = MEMD(sprite_copy.pos_y_lo); W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 32, 0xfed4); W_MEMW(reg_si + 34, 0xfed4); W_MEMW(reg_si + 40, 0x71); PUSHI(0x13); EMU_CALL(a_set_cur_sound, 22A0, think_7); reg_sp += 2; } // seg000:22A2 POP(di); POP(si); POP(bp); RET; } // 22A6 void contact_7() { PUSH(bp); MOV(bp, sp); reg_bx = MEMW(reg_bp + 6); // seg000:22AC if (MEMW(reg_bx) == 1) { // seg000:22B1 reg_bx = MEMW(reg_bp + 4); W_MEMW(reg_bx + 50, a_think_19); } // seg000:22B9 POP(bp); RET; } // 22BB void contact_6() { RETLOC(234A); RETLOC(22F4); RETLOC(22E0); assert(reg_eip == 0x22bb); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_bx = MEMW(reg_bp + 6); // seg000:22C6 if (MEMW(reg_bx) == 0xa) { // seg000:22CE W_MEMW(reg_si + 50, a_think_11); W_MEMW(reg_si + 43, 0); W_MEMW(reg_si + 54, a_think_contact_nop); EMU_CALL(a_get_random, 22E0, contact_6); // seg000:22E0 if ((short)reg_ax > 0x80) { // seg000:22E5 W_MEMW(reg_si + 40, 0x6e); } else { // seg000:22EC W_MEMW(reg_si + 40, 0x6f); } // seg000:22F1 EMU_CALL(a_add_body, 22F4, contact_6); MOV(di, ax); W_MEMW(reg_di + 8, 4); W_MEMW(reg_di + 34, a_think_body_6); int tmp1 = MEMD(reg_si + 4); tmp1 >>= 0xc; W_MEMD(reg_di, tmp1); tmp1 = MEMD(reg_si + 8); tmp1 >>= 0xc; tmp1 += 1; W_MEMD(reg_di + 4, tmp1); W_MEMW(reg_di + 0xa, 0); reg_ax = MEMW(num_monsters); reg_ax *= 54; reg_ax += sprite_array_offset; MOV(si, ax); // seg000:233E while (MEMW(reg_si) != 4) { // seg000:233B reg_si -= 0x36; } // seg000:2343 PUSHI(0x27); EMU_CALL(a_set_cur_sound, 234A, contact_6); reg_sp += 2; W_MEMW(reg_si + 42, 0); W_MEMW(reg_si + 44, 6); W_MEMW(reg_si + 40, 0x52); W_MEMW(reg_si + 54, a_think_contact_nop); W_MEMW(reg_si + 50, a_think_12); } // seg000:2365 POP(di); POP(si); POP(bp); RET; } // 24F4 void show_message() { RETLOC(26D1); RETLOC(26CE); RETLOC(26C3); RETLOC(26C0); RETLOC(26BB); RETLOC(26A9); RETLOC(26A0); RETLOC(2697); RETLOC(268E); RETLOC(2685); RETLOC(267C); RETLOC(266E); RETLOC(2665); RETLOC(265C); RETLOC(2653); RETLOC(264A); RETLOC(2641); RETLOC(2633); RETLOC(262A); RETLOC(2621); RETLOC(2612); RETLOC(2609); RETLOC(2600); RETLOC(25F7); RETLOC(25EE); RETLOC(25E5); RETLOC(25D6); RETLOC(25CD); RETLOC(25C4); RETLOC(25BB); RETLOC(25B2); RETLOC(25A9); RETLOC(259A); RETLOC(2591); RETLOC(2588); RETLOC(257F); RETLOC(2576); RETLOC(256D); RETLOC(255E); RETLOC(2555); RETLOC(254C); RETLOC(2543); RETLOC(253A); RETLOC(2531); RETLOC(2512); assert(reg_eip == 0x24f4); PUSH(bp); MOV(bp, sp); reg_sp -= 4; int tmp1 = MEMD(tick_count); W_MEMD(reg_bp - 4, tmp1); PUSHI(0xa); PUSHI(0x15); EMU_CALL(a_draw_box, 2512, show_message); reg_sp += 4; reg_bx = MEMW(current_level); reg_bx -= 2; // seg000:251B if (reg_bx <= 0xd) { // seg000:2523 switch(reg_bx) { case 0: // seg000:252A PUSHI(aYouHearInYour); EMU_CALL(a_draw_string, 2531, show_message); reg_sp += 2; PUSHI(aMind); EMU_CALL(a_draw_string, 253A, show_message); reg_sp += 2; PUSHI(asc_150AC); EMU_CALL(a_draw_string, 2543, show_message); reg_sp += 2; PUSHI(aItIsTooBadThat); EMU_CALL(a_draw_string, 254C, show_message); reg_sp += 2; PUSHI(aYouCannotReadThe); EMU_CALL(a_draw_string, 2555, show_message); reg_sp += 2; PUSHI(aStandardGalactic); EMU_CALL(a_draw_string, 255E, show_message); reg_sp += 2; reg_ax = aAlphabetHuman_; break; case 4: // seg000:2566 PUSHI(aAMessageEchoesIn); EMU_CALL(a_draw_string, 256D, show_message); reg_sp += 2; PUSHI(aYourHead); EMU_CALL(a_draw_string, 2576, show_message); reg_sp += 2; PUSHI(asc_15146); EMU_CALL(a_draw_string, 257F, show_message); reg_sp += 2; PUSHI(aTheTeleporterIn); EMU_CALL(a_draw_string, 2588, show_message); reg_sp += 2; PUSHI(aTheIceWillSend); EMU_CALL(a_draw_string, 2591, show_message); reg_sp += 2; PUSHI(aYouToTheDarkSide); EMU_CALL(a_draw_string, 259A, show_message); reg_sp += 2; reg_ax = aOfMars_; break; case 7: // seg000:25A2 PUSHI(aAVoiceBuzzesIn); EMU_CALL(a_draw_string, 25A9, show_message); reg_sp += 2; PUSHI(aYourMind); EMU_CALL(a_draw_string, 25B2, show_message); reg_sp += 2; PUSHI(asc_151E0); EMU_CALL(a_draw_string, 25BB, show_message); reg_sp += 2; PUSHI(aThereIsAHidden); EMU_CALL(a_draw_string, 25C4, show_message); reg_sp += 2; PUSHI(aCity_LookInThe); EMU_CALL(a_draw_string, 25CD, show_message); reg_sp += 2; PUSHI(aDarkAreaOfThe); EMU_CALL(a_draw_string, 25D6, show_message); reg_sp += 2; reg_ax = aCityToTheSouth_; break; case 8: // seg000:25DE PUSHI(aYouSeeTheseWords); EMU_CALL(a_draw_string, 25E5, show_message); reg_sp += 2; PUSHI(aInYourHead); EMU_CALL(a_draw_string, 25EE, show_message); reg_sp += 2; PUSHI(asc_1527A); EMU_CALL(a_draw_string, 25F7, show_message); reg_sp += 2; PUSHI(aYouWillNeedA); EMU_CALL(a_draw_string, 2600, show_message); reg_sp += 2; PUSHI(aRaygunInTheEnd); EMU_CALL(a_draw_string, 2609, show_message); reg_sp += 2; PUSHI(aButNotToShootThe); EMU_CALL(a_draw_string, 2612, show_message); reg_sp += 2; reg_ax = aVorticon___; break; case 9: // seg000:261A PUSHI(aYouHearInYour_0); EMU_CALL(a_draw_string, 2621, show_message); reg_sp += 2; PUSHI(aMind_0); EMU_CALL(a_draw_string, 262A, show_message); reg_sp += 2; PUSHI(asc_15314); EMU_CALL(a_draw_string, 2633, show_message); reg_sp += 2; reg_ax = aGaaarrrrrgg; break; case 10: // seg000:263A PUSHI(aAYorpishWhisper); EMU_CALL(a_draw_string, 2641, show_message); reg_sp += 2; PUSHI(aSays); EMU_CALL(a_draw_string, 264A, show_message); reg_sp += 2; PUSHI(asc_1536C); EMU_CALL(a_draw_string, 2653, show_message); reg_sp += 2; PUSHI(aLookForDarkHidden); EMU_CALL(a_draw_string, 265C, show_message); reg_sp += 2; PUSHI(aBricks_YouCanSee); EMU_CALL(a_draw_string, 2665, show_message); reg_sp += 2; PUSHI(aNaughtButTheir); EMU_CALL(a_draw_string, 266E, show_message); reg_sp += 2; reg_ax = aUpperLeftCorner_; break; case 13: // seg000:2675 PUSHI(aAYorpyMindThought); EMU_CALL(a_draw_string, 267C, show_message); reg_sp += 2; PUSHI(aBellows); EMU_CALL(a_draw_string, 2685, show_message); reg_sp += 2; PUSHI(asc_15407); EMU_CALL(a_draw_string, 268E, show_message); reg_sp += 2; PUSHI(aYouCannotKillThe); EMU_CALL(a_draw_string, 2697, show_message); reg_sp += 2; PUSHI(aVorticonCommander); EMU_CALL(a_draw_string, 26A0, show_message); reg_sp += 2; reg_ax = aDirectly_; break; } // seg000:26A5 PUSH(ax); EMU_CALL(a_draw_string, 26A9, show_message); reg_sp += 2; } // seg000:26AB reg_ax = MEMW(word_15520); reg_ax += 5; W_MEMW(word_1B348, reg_ax); PUSHI(aPressEnter); EMU_CALL(a_draw_stringz, 26BB, show_message); reg_sp += 2; EMU_CALL(a_clear_keys, 26C0, show_message); do { // seg000:26C0 EMU_CALL(a_read_char_with_echo, 26C3, show_message); reg_ax &= 0xff; // seg000:26C6 } while (reg_ax != 0xd); // seg000:26CB EMU_CALL(a_clear_overlay, 26CE, show_message); EMU_CALL(a_clear_keys, 26D1, show_message); tmp1 = MEMD(reg_bp - 4); W_MEMD(tick_count, tmp1); MOV(sp, bp); POP(bp); RET; } // 26FE void think_14() { RETLOC(273B); RETLOC(2738); RETLOC(2735); assert(reg_eip == 0x26FE); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(tick_count); reg_ax >>= 5; reg_ax &= 1; reg_ax += 0x1c; W_MEMW(sprite_copy.cur_frame, reg_ax); reg_ax = MEMW(sprite_copy.sync_time); reg_ax -= MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:271B if ((short)reg_ax < 0) { // seg000:271F W_MEMW(sprite_copy.cur_frame, 0x1f); // seg000:2725 if ((short)MEMW(sprite_copy.sync_time) < -32) { // seg000:272C W_MEMW(sprite_copy.think_func, a_think_13); } } // seg000:2732 EMU_CALL(a_do_fall, 2735, think_14); EMU_CALL(a_compute_sprite_delta, 2738, think_14); EMU_CALL(a_check_ceiling, 273B, think_14); POP(bp); RET; } // 27F8 void open_door() { RETLOC(2859); RETLOC(2807); assert(reg_eip == 0x27F8); PUSH(bp); MOV(bp, sp); reg_sp -= 4; PUSH(si); PUSH(di); PUSHI(0x21); EMU_CALL(a_set_cur_sound, 2807, open_door); reg_sp += 2; // seg000:2809 reg_ax = MEMW(reg_bp + 6); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp + 4); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; reg_ax = MEMW(tile_kind_tbl + reg_bx); W_MEMW(reg_bp - 2, reg_ax); reg_ax = MEMW(reg_bp + 6); reg_ax--; reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp + 4); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; reg_ax = MEMW(tile_kind_tbl + reg_bx); W_MEMW(reg_bp - 4, reg_ax); // seg000:2846 if (reg_ax == MEMW(reg_bp - 2)) { // seg000:284B reg_ax = MEMW(reg_bp + 6); reg_ax--; MOV(di, ax); } else { // seg000:2853 reg_di = MEMW(reg_bp + 6); } // seg000:2856 EMU_CALL(a_add_body, 2859, open_door); MOV(si, ax); W_MEMW(reg_si + 8, 1); W_MEMW(reg_si + 34, a_slide_door); // seg000:2865 reg_ax = MEMW(reg_bp + 4); int tmp1 = (short)reg_ax; tmp1 <<= 0xc; W_MEMD(reg_si, tmp1); // seg000:2873 tmp1 = (short)reg_di; tmp1 <<= 0xc; W_MEMD(reg_si + 4, tmp1); // seg000:2881 W_MEMW(reg_si + 0xa, 0); MOV(ax, di); reg_ax += 3; reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp + 4); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_si + 0xc, reg_ax); // seg000:28A0 MOV(ax, di); reg_ax += 2; reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp + 4); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_si + 0xe, reg_ax); // seg000:28B9 MOV(ax, di); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp + 4); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_si + 0x10, reg_ax); // seg000:28D0 reg_bx = MEMW(reg_bp - 2); reg_bx <<= 1; W_MEMW(got_pogo + reg_bx, 0); // seg000:28DB MOV(ax, di); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp + 4); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x8f); // seg000:28F1 MOV(ax, di); reg_ax++; reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp + 4); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x8f); // seg000:2908 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 290E void think_19() { PUSH(bp); MOV(bp, sp); W_MEMW(sprite_copy.type, 0); POP(bp); RET; } // 2919 void default_think() { RETLOC(2923); assert(reg_eip == 0x2919); PUSH(bp); MOV(bp, sp); PUSHI(aBadThinkPointer); EMU_CALL(a_chg_vid_and_error, 2923, default_think); reg_sp += 2; POP(bp); RET; } // 2927 void default_contact() { RETLOC(2931); assert(reg_eip == 0x2927); PUSH(bp); MOV(bp, sp); PUSHI(aBadContactPointer); EMU_CALL(a_chg_vid_and_error, 2931, default_contact); reg_sp += 2; POP(bp); RET; } // 297E - creates space for new "body" at bodies array, returns pointer in ax void add_body() { RETLOC(29AF); assert(reg_eip == 0x297e); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); // seg000:2983 reg_di = 0; reg_si = bodies; // seg000:298E while (MEMW(reg_si + 8) != 0 && (short)reg_di < (short)MEMW(num_bodies)) { // seg000:298A reg_di++; reg_si += 36; } // seg000:299A if ((short)reg_di >= (short)MEMW(num_bodies)) { W_MEMW(num_bodies, MEMW(num_bodies) + 1); } // seg000:29A4 clear spot in array PUSHI(36); PUSHI(0); PUSH(si); EMU_CALL(a__memset, 29AF, add_body); reg_sp += 6; // seg000:29B2 W_MEMW(reg_si + 34, a_default_think); MOV(ax, si); POP(di); POP(si); POP(bp); RET; } // seg000:29BD void detect_mnstr_col() { PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 4); reg_si = MEMW(reg_bp + 6); // seg000:29C8 if (MEMD(reg_di + 0xc) == 0 || MEMD(reg_si + 0xc) == 0) { // seg000:29D8 reg_ax = 0; // seg000:2A37 POP(di); POP(si); POP(bp); RET; } // seg000:29DC if ((int)MEMD(reg_di + 0x14) < (int)MEMD(reg_si + 0xc)) { // seg000:29EE reg_ax = 0; // seg000:2A37 POP(di); POP(si); POP(bp); RET; } // seg000:29F2 if ((int)MEMD(reg_di + 0x18) < (int)MEMD(reg_si + 0x10)) { // seg000:2A04 reg_ax = 0; // seg000:2A37 POP(di); POP(si); POP(bp); RET; } // seg000:2A08 if ((int)MEMD(reg_di + 0xc) > (int)MEMD(reg_si + 0x14)) { // seg000:2A1A reg_ax = 0; // seg000:2A37 POP(di); POP(si); POP(bp); RET; } // seg000:2A1E if ((int)MEMD(reg_di + 0x10) > (int)MEMD(reg_si + 0x18)) { // seg000:2A30 reg_ax = 0; // seg000:2A37 POP(di); POP(si); POP(bp); RET; } // seg000:2A34 reg_ax = 1; // seg000:2A37 POP(di); POP(si); POP(bp); RET; } // 2BDF void pogo_jump() { PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 4); reg_dx = MEMW(reg_bp + 6); reg_si = 1; // seg000:2C20 while (reg_si <= MEMW(sprite_sync)) { // seg000:2BEF MOV(ax, dx); W_MEMW(sprite_copy.vel_y, MEMW(sprite_copy.vel_y) + reg_ax); // seg000:2BF5 if ((short)MEMW(sprite_copy.vel_y) > (short)reg_di) { // seg000:2BFB W_MEMW(sprite_copy.vel_y, reg_di); } else { // seg000:2C01 MOV(ax, di); reg_ax = -(short)reg_ax; if ((short)reg_ax > (short)MEMW(sprite_copy.vel_y)) { // seg000:2C0B MOV(ax, di); reg_ax = -(short)reg_ax; W_MEMW(sprite_copy.vel_y, reg_ax); } } // seg000:2C12 if (reg_si != MEMW(sprite_sync)) { // seg000:2C18 reg_ax = MEMW(sprite_copy.vel_y); W_MEMW(sprite_copy.delta_y, MEMW(sprite_copy.delta_y) + reg_ax); } // seg000:2C1F reg_si++; } // seg000:2C26 POP(di); POP(si); POP(bp); RET; } // 3360 void think_contact_nop() { PUSH(bp); MOV(bp, sp); POP(bp); RET; } // 3867 void think_13() { RETLOC(3B02); RETLOC(3AAB); RETLOC(3A8E); RETLOC(3A6D); RETLOC(3A67); RETLOC(3A64); RETLOC(3A5F); RETLOC(3992); RETLOC(3973); RETLOC(394A); RETLOC(3932); assert(reg_eip == 0x3867); PUSH(bp); MOV(bp, sp); reg_sp -= 0xa; PUSH(si); PUSH(di); // seg000:386F if (MEMW(sprite_copy.unk_w_2) != 0) { // seg000:3876 reg_di = 1; } else { // seg000:387B int tmp1 = MEMD(sprite_copy.box_left_x) >> 0xc; W_MEMW(reg_bp - 4, tmp1 & 0xffff); tmp1 = MEMD(sprite_copy.box_right_x) >> 0xc; W_MEMW(reg_bp - 6, tmp1 & 0xffff); tmp1 = MEMD(sprite_copy.box_bottom_y) >> 0xc; W_MEMW(reg_bp - 8, (tmp1 + 1) & 0xffff); reg_di = 1; reg_si = MEMW(reg_bp - 4); // seg000:38D6 while ((short)reg_si <= (short)MEMW(reg_bp - 6)) { // seg000:38B1 reg_ax = MEMW(reg_bp - 8); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_si; reg_ax <<= 1; // seg000:38BC reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; reg_ax = MEMW(word_13A84 + reg_bx); W_MEMW(reg_bp - 0xa, reg_ax); // seg000:38CE if ((short)reg_ax > 1) { // seg000:38D3 MOV(di, ax); } // seg000:38D5 reg_si++; } } // seg000:38DB if (MEMW(input.jump) != 0) { // seg000:38E2 reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(sprite_copy.unk_w_1, reg_ax); W_MEMW(sprite_copy.vel_x, 0); W_MEMW(sprite_copy.frame_countdown, 0); W_MEMW(sprite_copy.sync_time, 0); // seg000:38FA if ((short)MEMW(word_1909C) >= 0) { // seg000:3901 W_MEMW(sprite_copy.frame_var2, 8); } else { // seg000:3909 W_MEMW(sprite_copy.frame_var2, 0xe); } // seg000:390F W_MEMW(sprite_copy.think_func, a_think_32); } // seg000:3915 if ((short)reg_di < 3) { // seg000:391A reg_bx = MEMW(input.direction); reg_bx--; // seg000:391F if (reg_bx <= 6) { // seg000:3924 switch(reg_bx) { case 0: case 1: case 2: // seg000:392B PUSHI(2); EMU_CALL(a_move_left_right, 3932, think_13); reg_sp += 2; // seg000:3934 if ((short)MEMW(sprite_copy.vel_x) < 0) { // seg000:393B W_MEMW(input.direction, 8); } break; case 4: case 5: case 6: // seg000:3943 PUSHI(0xfffe); EMU_CALL(a_move_left_right, 394A, think_13); reg_sp += 2; // seg000:394C if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:3953 W_MEMW(input.direction, 8); } break; } } } // seg000:3959 if (reg_di == 1 && MEMW(input.direction) == 8) { // seg000:3965 if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:396C PUSHI(0xfffd); EMU_CALL(a_move_left_right, 3973, think_13); reg_sp += 2; // seg000:3975 if ((short)MEMW(sprite_copy.vel_x) < 0) { // seg000:397C W_MEMW(sprite_copy.vel_x, 0); } } else if ((short)MEMW(sprite_copy.vel_x) < 0) { // seg000:3984 // seg000:398B PUSHI(3); EMU_CALL(a_move_left_right, 3992, think_13); reg_sp += 2; // seg000:3994 if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:399B W_MEMW(sprite_copy.vel_x, 0); } } } // seg000:39A1 if (reg_di == 3) { // seg000:39A6 if ((short)MEMW(word_1909C) > 0) { // seg000:39AD W_MEMW(sprite_copy.vel_x, 0xb4); } else { // seg000:39B5 if ((short)MEMW(word_1909C) < 0) { // seg000:39BC W_MEMW(sprite_copy.vel_x, 0xFF4C); } } } // seg000:39C2 if (MEMW(sprite_copy.vel_x) == 0) { // seg000:39C9 if ((short)MEMW(word_1909C) >= 0) { // seg000:39D0 W_MEMW(sprite_copy.cur_frame, 0); } else { // seg000:39D8 W_MEMW(sprite_copy.cur_frame, 4); } } else { // seg000:39E0 if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:39E7 W_MEMW(sprite_copy.cur_frame, 0); // seg000:39ED if ((short)reg_di < 3) { // seg000:39F2 reg_ax = (MEMW(tick_count) >> 4) & 3; reg_dx = MEMW(sprite_copy.cur_frame); reg_dx += reg_ax; W_MEMW(sprite_copy.cur_frame, reg_dx); } } else { // seg000:3A0A W_MEMW(sprite_copy.cur_frame, 4); // seg000:3A10 if ((short)reg_di < 3) { // seg000:3A15 reg_ax = (MEMW(tick_count) >> 4) & 3; reg_dx = MEMW(sprite_copy.cur_frame); reg_dx += reg_ax; W_MEMW(sprite_copy.cur_frame, reg_dx); } } // seg000:3A29 reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(word_1909C, reg_ax); } // seg000:3A2F if (MEMW(sprite_copy.vel_x) != 0) { // seg000:3A36 reg_ax = MEMW(tick_count) >> 4; if ((reg_ax & 1) && (short)reg_di < 3) { // seg000:3A47 reg_ax = MEMW(tick_count) >> 5; if (reg_ax & 1) { // seg000:3A53 reg_ax = 0x1e; } else { // seg000:3A58 reg_ax = 4; } // seg000:3A5B PUSH(ax); EMU_CALL(a_set_cur_sound, 3A5F, think_13); reg_sp += 2; } } // seg000:3A61 EMU_CALL(a_do_fall, 3A64, think_13); EMU_CALL(a_compute_sprite_delta, 3A67, think_13); W_MEMW(reg_bp - 2, reg_ax); EMU_CALL(a_check_ceiling, 3A6D, think_13); // seg000:3A6D if ((MEMW(reg_bp - 2) & 4) || (MEMW(reg_bp - 2) & 1)) { // seg000:3A7B reg_ax = MEMW(tick_count) >> 4; if (reg_ax & 1) { // seg000:3A87 PUSHI(5); EMU_CALL(a_set_cur_sound, 3A8E, think_13); reg_sp += 2; } } // seg000:3A90 if ((MEMW(reg_bp - 2) & 2) == 0 && MEMW(sprite_copy.unk_w_2) == 0) { // seg000:3A9E W_MEMW(sprite_copy.think_func, a_think_29); PUSHI(0x1b); EMU_CALL(a_set_cur_sound, 3AAB, think_13); reg_sp += 2; } else { // seg000:3AB0 if (MEMW(input.jump) != 0) { // seg000:3AB7 reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(sprite_copy.unk_w_1, reg_ax); W_MEMW(sprite_copy.vel_x, 0); // seg000:3AC3 W_MEMW(sprite_copy.frame_countdown, 0); W_MEMW(sprite_copy.sync_time, 0); // seg000:3ACF if ((short)MEMW(word_1909C) >= 0) { // seg000:3AD6 W_MEMW(sprite_copy.frame_var2, 8); } else { // seg000:3ADE W_MEMW(sprite_copy.frame_var2, 0xe); } // seg000:3AE4 W_MEMW(sprite_copy.think_func, a_think_32); } // seg000:3AEA if (MEMW(input.pogo) != 0 && MEMW(input_old.pogo) == 0) { // seg000:3AF8 if (MEMW(word_1B2A8) != 0) { // seg000:3AFF EMU_CALL(a_toggle_switch, 3B02, think_13); } else { // seg000:3B04 W_MEMW(sprite_copy.sync_time, 0); reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(sprite_copy.frame_countdown, reg_ax); W_MEMW(sprite_copy.vel_x, 0); // seg000:3B16 if (MEMW(got_pogo) != 0) { // seg000:3B1D W_MEMW(sprite_copy.think_func, a_think_31); } } // seg000:3B23 if (MEMW(input.jump) != 0 && MEMW(input.pogo) != 0 && MEMW(input_old.jump) == 0 && MEMW(input_old.pogo) == 0) { // seg000:3B3F W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); W_MEMW(sprite_copy.delta_x, 0); W_MEMW(sprite_copy.frame_countdown, 0); W_MEMW(sprite_copy.sync_time, 0); W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); // seg000:3B56 if ((short)MEMW(word_1909C) > 0) { // seg000:3B5D W_MEMW(sprite_copy.cur_frame, 0x14); } else { // seg000:3B65 W_MEMW(sprite_copy.cur_frame, 0x15); } } // seg000:3B6B if (MEMW(sprite_copy.unk_w_2) != 0) { // seg000:3B72 W_MEMW(sprite_copy.unk_w_2, MEMW(sprite_copy.unk_w_2) - 1); } } } // seg000:3B76 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 3B8B void think_32() { RETLOC(3C4E); RETLOC(3C4B); RETLOC(3C48); RETLOC(3C43); assert(reg_eip == 0x3b8b); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(sprite_copy.sync_time); reg_bx = 6; int tmp1 = (short)reg_ax; tmp1 /= (short)reg_bx; reg_dx = MEMW(sprite_copy.frame_var2); reg_dx += (tmp1 & 0xffff); W_MEMW(sprite_copy.cur_frame, reg_dx); // seg000:3BA1 if (MEMW(input.jump) != 0) { // seg000:3BA8 reg_ax = MEMW(sprite_sync); reg_ax *= 6; reg_dx = MEMW(sprite_copy.frame_countdown); reg_dx += reg_ax; W_MEMW(sprite_copy.frame_countdown, reg_dx); } else { // seg000:3BBC if ((short)MEMW(sprite_copy.sync_time) < 0xc) { // seg000:3BC3 reg_ax = 0x18; reg_ax -= MEMW(sprite_copy.sync_time); W_MEMW(sprite_copy.sync_time, reg_ax); } } // seg000:3BCD reg_bx = MEMW(input.direction); reg_bx--; if (reg_bx <= 6) { // seg000:3BD7 switch(reg_bx) { case 0: case 1: case 2: // seg000:3BDE reg_ax = MEMW(sprite_sync); reg_ax <<= 1; reg_dx = MEMW(sprite_copy.unk_w_1); reg_dx += reg_ax; W_MEMW(sprite_copy.unk_w_1, reg_dx); // seg000:3BED if ((short)reg_dx > 0x78) { // seg000:3BF2 W_MEMW(sprite_copy.unk_w_1, 0x78); } break; case 4: case 5: case 6: // seg000:3BFA reg_ax = MEMW(sprite_sync); reg_ax <<= 1; reg_dx = MEMW(sprite_copy.unk_w_1); reg_dx -= reg_ax; W_MEMW(sprite_copy.unk_w_1, reg_dx); // seg000:3C09 if ((short)reg_dx < -0x78) { W_MEMW(sprite_copy.unk_w_1, -0x78); } break; } } // seg000:3C14 W_MEMW(sprite_copy.vel_x, 0); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:3C24 if ((short)reg_ax >= 0x24) { // seg000:3C29 W_MEMW(sprite_copy.think_func, a_think_29); reg_ax = MEMW(sprite_copy.frame_countdown); W_MEMW(sprite_copy.vel_y, MEMW(sprite_copy.vel_y) - reg_ax); reg_ax = MEMW(sprite_copy.unk_w_1); W_MEMW(sprite_copy.vel_x, reg_ax); PUSHI(6); EMU_CALL(a_set_cur_sound, 3C43, think_32); reg_sp += 2; } // seg000:3C45 EMU_CALL(a_do_fall, 3C48, think_32); EMU_CALL(a_compute_sprite_delta, 3C4B, think_32); EMU_CALL(a_check_ceiling, 3C4E, think_32); // seg000:3C4E if (MEMW(input.jump) != 0 && MEMW(input.pogo) != 0) { // seg000:3C5C W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); W_MEMW(sprite_copy.delta_x, 0); W_MEMW(sprite_copy.frame_countdown, 0); W_MEMW(sprite_copy.sync_time, 0); W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); // seg000:3C73 if ((short)MEMW(word_1909C) > 0) { // seg000:3C7A W_MEMW(sprite_copy.cur_frame, 0x14); } else { // seg000:3C82 W_MEMW(sprite_copy.cur_frame, 0x15); } } // seg000:3C88 POP(bp); RET; } // 3C99 void think_29() { RETLOC(3DAA); RETLOC(3D92); RETLOC(3D8D); RETLOC(3D7B); RETLOC(3D66); RETLOC(3D47); RETLOC(3D10); RETLOC(3CF1); RETLOC(3D44); RETLOC(3CCD); RETLOC(3CB5); assert(reg_eip == 0x3c99); PUSH(bp); MOV(bp, sp); PUSH(si); reg_bx = MEMW(input.direction); reg_bx--; // seg000:3CA2 if (reg_bx <= 6) { // seg000:3CA7 switch(reg_bx) { case 0: case 1: case 2: // seg000:3CAE PUSHI(2); EMU_CALL(a_move_left_right, 3CB5, think_29); reg_sp += 2; // seg000:3CB7 if ((short)MEMW(sprite_copy.vel_x) < 0) { // seg000:3CBE W_MEMW(input.direction, 8); } break; case 4: case 5: case 6: // seg000:3CC6 PUSHI(0xfffe); EMU_CALL(a_move_left_right, 3CCD, think_29); reg_sp += 2; // seg000:3CCF if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:3CD6 W_MEMW(input.direction, 8); } break; } } // seg000:3CDC if (MEMW(input.direction) == 8) { // seg000:3CE3 if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:3CEA PUSHI(0xffff); EMU_CALL(a_move_left_right, 3CF1, think_29); reg_sp += 2; // seg000:3CF3 if ((short)MEMW(sprite_copy.vel_x) < 0) { // seg000:3CFA W_MEMW(sprite_copy.vel_x, 0); } } else { // seg000:3D02 if ((short)MEMW(sprite_copy.vel_x) < 0) { // seg000:3D09 PUSHI(1); EMU_CALL(a_move_left_right, 3D10, think_29); reg_sp += 2; // seg000:3D12 if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:3D19 W_MEMW(sprite_copy.vel_x, 0); } } } } // seg000:3D1F if ((short)MEMW(word_1909C) > 0) { // seg000:3D26 W_MEMW(sprite_copy.cur_frame, 0xd); } else { // seg000:3D2E W_MEMW(sprite_copy.cur_frame, 0x13); } // seg000:3D34 if (MEMW(sprite_copy.vel_x) != 0) { // seg000:3D3B reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(word_1909C, reg_ax); } // seg000:3D41 EMU_CALL(a_do_fall, 3D44, think_29); EMU_CALL(a_compute_sprite_delta, 3D47, think_29); MOV(si, ax); // seg000:3D49 if ((reg_ax & 4) || (reg_ax & 1)) { // seg000:3D53 reg_ax = MEMW(tick_count); reg_ax >>= 4; // seg000:3D5A if (reg_ax & 1) { PUSHI(5); EMU_CALL(a_set_cur_sound, 3D66, think_29); reg_sp += 2; } } // seg000:3D68 if (reg_si & 2) { // seg000:3D6E W_MEMW(sprite_copy.think_func, a_think_13); PUSHI(7); EMU_CALL(a_set_cur_sound, 3D7B, think_29); reg_sp += 2; } else { // seg000:3D80 if (reg_si & 8) { // seg000:3D86 PUSHI(0x15); EMU_CALL(a_set_cur_sound, 3D8D, think_29); reg_sp += 2; } // seg000:3D8F EMU_CALL(a_check_ceiling, 3D92, think_29); // seg000:3D92 if (MEMW(input.pogo) != 0 && MEMW(input_old.pogo) == 0) { // seg000:3DA0 if (MEMW(word_1B2A8) != 0) { // seg000:3DA7 EMU_CALL(a_toggle_switch, 3DAA, think_29); } else { // seg000:3DAC if (MEMW(got_pogo) != 0) { // seg000:3DB3 W_MEMW(sprite_copy.think_func, a_think_30); } } } // seg000:3DB9 if (MEMW(input.jump) != 0 && MEMW(input.pogo) != 0 && MEMW(input_old.jump) == 0 && MEMW(input_old.pogo) == 0) { // seg000:3DD5 W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); W_MEMW(sprite_copy.delta_x, 0); W_MEMW(sprite_copy.frame_countdown, 0); W_MEMW(sprite_copy.sync_time, 0); W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); // seg000:3DEC if ((short)MEMW(word_1909C) > 0) { // seg000:3DF3 W_MEMW(sprite_copy.cur_frame, 0x14); } else { // seg000:3DFB W_MEMW(sprite_copy.cur_frame, 0x15); } } } // seg000:3E01 POP(si); POP(bp); RET; } // 3E12 void think_33_fire_raygun() { RETLOC(3EC6); RETLOC(3EC3); RETLOC(3EC0); RETLOC(3EAE); RETLOC(3E8F); RETLOC(3E5E); RETLOC(3E52); RETLOC(3E39); assert(reg_eip == 0x3e12); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:3E1F if (MEMW(sprite_copy.frame_countdown) == 0 && (short)reg_ax > 1) { // seg000:3E2B if (MEMW(ray_gun_charge) != 0) { // seg000:3E32 PUSHI(0xc); EMU_CALL(a_set_cur_sound, 3E39, think_33_fire_raygun); reg_sp += 2; W_MEMW(ray_gun_charge, MEMW(ray_gun_charge) - 1); PUSHI(MEMW(sprite_copy.pos_y_hi)); PUSHI(MEMW(sprite_copy.pos_y_lo)); PUSHI(MEMW(sprite_copy.pos_x_hi)); PUSHI(MEMW(sprite_copy.pos_x_lo)); EMU_CALL(a_add_monster_8, 3E52, think_33_fire_raygun); reg_sp += 8; } else { // seg000:3E57 PUSHI(0x24); EMU_CALL(a_set_cur_sound, 3E5E, think_33_fire_raygun); reg_sp += 2; } // seg000:3E60 W_MEMW(sprite_copy.frame_countdown, 1); } // seg000:3E66 if ((short)MEMW(sprite_copy.sync_time) > 0x1e && MEMW(input.jump) == 0 && MEMW(input.pogo) == 0) { // seg000:3E7B W_MEMW(sprite_copy.think_func, a_think_13); } // seg000:3E81 if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:3E88 PUSHI(0xffff); EMU_CALL(a_move_left_right, 3E8F, think_33_fire_raygun); reg_sp += 2; if ((short)MEMW(sprite_copy.vel_x) < 0) { // seg000:3E98 W_MEMW(sprite_copy.vel_x, 0); } } else if ((short)MEMW(sprite_copy.vel_x) < 0) { // seg000:3EA7 PUSHI(1); EMU_CALL(a_move_left_right, 3EAE, think_33_fire_raygun); reg_sp += 2; if ((short)MEMW(sprite_copy.vel_x) > 0) { // seg000:3EB7 W_MEMW(sprite_copy.vel_x, 0); } } // seg000:3EBD EMU_CALL(a_do_fall, 3EC0, think_33_fire_raygun); EMU_CALL(a_compute_sprite_delta, 3EC3, think_33_fire_raygun); EMU_CALL(a_check_ceiling, 3EC6, think_33_fire_raygun); POP(bp); RET; } // 3EC8 void think_30() { RETLOC(3FF4); RETLOC(3FDC); RETLOC(3FD7); RETLOC(3FAA); RETLOC(3F8B); RETLOC(3F88); RETLOC(3F46); RETLOC(3F1E); RETLOC(3F06); RETLOC(3EEE); RETLOC(3EE0); assert(reg_eip == 0x3ec8); PUSH(bp); MOV(bp, sp); reg_sp -= 6; PUSH(si); reg_ax = input.direction; PUSHI(SegValue(ds)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 6; PUSH(ax); EMU_CALL(a_handle_ctrl, 3EE0, think_30); reg_sp += 6; reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 3EEE, think_30); reg_bx = MEMW(input.direction); reg_bx--; // seg000:3EF3 if ((short)reg_bx <= 6) { // seg000:3EF8 switch(reg_bx) { case 0: case 1: case 2: // seg000:3EFF PUSHI(1); EMU_CALL(a_move_left_right, 3F06, think_30); reg_sp += 2; // seg000:3F08 if ((short)MEMW(sprite_copy.vel_x) < 0) { // seg000:3F0F W_MEMW(input.direction, 8); } break; case 4: case 5: case 6: // seg000:3F17 PUSHI(0xffff); EMU_CALL(a_move_left_right, 3F1E, think_30); reg_sp += 2; // seg000:3F20 if ((short)MEMW(sprite_copy.vel_x) > 0) { W_MEMW(input.direction, 8); } break; } } // seg000:3F2D if (MEMW(input.jump) != 0 && (short)MEMW(sprite_copy.vel_y) < 0) { // seg000:3F3B PUSHI(0xffff); PUSHI(0xc8); EMU_CALL(a_pogo_jump, 3F46, think_30); reg_sp += 4; } // seg000:3F49 if (MEMW(god_mode) != 0 && MEMW(input.jump) != 0) { // seg000:3F57 W_MEMW(sprite_copy.vel_y, 0xff38); } // seg000:3F5D if (MEMW(sprite_copy.vel_x) != 0) { // seg000:3F64 reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(word_1909C, reg_ax); } // seg000:3F6A if ((short)MEMW(word_1909C) >= 0) { // seg000:3F71 W_MEMW(sprite_copy.frame_var2, 0x18); } else { // seg000:3F79 W_MEMW(sprite_copy.frame_var2, 0x1a); } // seg000:3F7F reg_ax = MEMW(sprite_copy.frame_var2); W_MEMW(sprite_copy.cur_frame, reg_ax); EMU_CALL(a_do_fall, 3F88, think_30); EMU_CALL(a_compute_sprite_delta, 3F8B, think_30); MOV(si, ax); // seg000:3F8D if ((reg_ax & 4) || (reg_ax & 1)) { // seg000:3F97 reg_ax = MEMW(tick_count); reg_ax >>= 4; // seg000:3F9E if (reg_ax & 1) { // seg000:3FA3 PUSHI(5); EMU_CALL(a_set_cur_sound, 3FAA, think_30); reg_sp += 2; } } // seg000:3FAC if (reg_si & 2) { // seg000:3FB2 W_MEMW(sprite_copy.think_func, a_think_31); W_MEMW(sprite_copy.sync_time, 0); reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(sprite_copy.frame_countdown, reg_ax); W_MEMW(sprite_copy.vel_x, 0); } // seg000:3FCA if (reg_si & 8) { // seg000:3FD0 PUSHI(0x15); EMU_CALL(a_set_cur_sound, 3FD7, think_30); reg_sp += 2; } // seg000:3FD9 EMU_CALL(a_check_ceiling, 3FDC, think_30); // seg000:3FDC if (MEMW(input.pogo) != 0 && MEMW(input_old.pogo) == 0) { // seg000:3FEA if (MEMW(word_1B2A8) != 0) { // seg000:3FF1 EMU_CALL(a_toggle_switch, 3FF4, think_30); } else { // seg000:3FF6 W_MEMW(sprite_copy.think_func, a_think_29); } } // seg000:3FFC if (MEMW(input.jump) != 0 && MEMW(input.pogo) != 0) { // seg000:400A W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); W_MEMW(sprite_copy.delta_x, 0); W_MEMW(sprite_copy.frame_countdown, 0); W_MEMW(sprite_copy.sync_time, 0); W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); // seg000:4021 if ((short)MEMW(word_1909C) > 0) { // seg000:4028 W_MEMW(sprite_copy.cur_frame, 0x14); } else { // seg000:4030 W_MEMW(sprite_copy.cur_frame, 0x15); } } // seg000:4036 if (MEMW(sprite_copy.unk_w_2) != 0) { // seg000:403D W_MEMW(sprite_copy.unk_w_2, MEMW(sprite_copy.unk_w_2) - 1); } // seg000:4041 POP(si); MOV(sp, bp); POP(bp); RET; } // 4054 void think_31() { RETLOC(40E7); RETLOC(4094); assert(reg_eip == 0x4054); PUSH(bp); MOV(bp, sp); W_MEMW(sprite_copy.vel_x, 0); W_MEMW(sprite_copy.delta_x, 0); reg_ax = MEMW(sprite_copy.frame_var2); reg_ax++; W_MEMW(sprite_copy.cur_frame, reg_ax); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:4070 if ((short)reg_ax > 22) { // seg000:4075 W_MEMW(sprite_copy.think_func, a_think_30); W_MEMW(sprite_copy.unk_w_2, 0); W_MEMW(sprite_copy.vel_y, MEMW(sprite_copy.vel_y) - 0xc8); reg_ax = MEMW(sprite_copy.frame_countdown); W_MEMW(sprite_copy.vel_x, reg_ax); PUSHI(6); EMU_CALL(a_set_cur_sound, 4094, think_31); reg_sp += 2; } // seg000:4096 if (MEMW(input.pogo) != 0 && MEMW(input_old.pogo) == 0) { // seg000:40A4 W_MEMW(sprite_copy.think_func, a_think_13); } // seg000:40AA if (MEMW(input.jump) != 0 && MEMW(input.pogo) != 0) { // seg000:40B8 W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); W_MEMW(sprite_copy.delta_x, 0); W_MEMW(sprite_copy.frame_countdown, 0); W_MEMW(sprite_copy.sync_time, 0); W_MEMW(sprite_copy.think_func, a_think_33_fire_raygun); // seg000:40CF if ((short)MEMW(word_1909C) > 0) { // seg000:40D6 W_MEMW(sprite_copy.cur_frame, 0x14); } else { // seg000:40DE W_MEMW(sprite_copy.cur_frame, 0x15); } } // seg000:40E4 EMU_CALL(a_compute_sprite_delta, 40E7, think_31); W_MEMW(sprite_copy.unk_w_2, 0); POP(bp); RET; } // 40EF void think_18_keen_exit() { RETLOC(41CC); RETLOC(419C); RETLOC(4172); RETLOC(4148); assert(reg_eip == 0x40EF); PUSH(bp); MOV(bp, sp); reg_sp -= 8; reg_ax = MEMW(sprite_copy.sync_time); int tmp1 = (short)reg_ax; W_MEMD(reg_bp - 4, tmp1); reg_ax = MEMW(sprite_copy.frame_countdown); tmp1 = (short)reg_ax; W_MEMD(reg_bp - 8, tmp1); // seg000:4109 reg_ax = MEMW(sprite_sync); reg_ax *= 0x3c; W_MEMW(sprite_copy.delta_x, reg_ax); // seg000:4114 reg_ax = MEMW(tick_count); reg_ax >>= 4; reg_ax &= 3; W_MEMW(sprite_copy.cur_frame, reg_ax); // seg000:4121 reg_ax = MEMW(sprite_copy.vel_x); W_MEMW(word_1909C, reg_ax); PUSHI(0xa0); tmp1 = MEMD(reg_bp - 8); tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp - 4); tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a_slide_sprite, 4148, think_18_keen_exit); reg_sp += 0xa; // seg000:414B PUSHI(0xa0); tmp1 = MEMD(reg_bp - 8); tmp1 += 1; tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp - 4); tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a_slide_sprite, 4172, think_18_keen_exit); reg_sp += 0xa; // seg000:4175 PUSHI(0x8f); tmp1 = MEMD(reg_bp - 8); tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp - 4); tmp1 += 1; tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a_slide_sprite, 419C, think_18_keen_exit); reg_sp += 0xa; // seg000:419F PUSHI(0x8f); tmp1 = MEMD(reg_bp - 8); tmp1 += 1; tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp - 4); tmp1 += 1; tmp1 <<= 0xc; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a_slide_sprite, 41CC, think_18_keen_exit); reg_sp += 0xa; // seg000:41CF tmp1 = MEMD(reg_bp - 4); tmp1 <<= 0xc; // seg000:41DA if (tmp1 <= (int)MEMD(sprite_copy.pos_x_lo)) { // seg000:41E8 W_MEMW(sprite_copy.type, 0); W_MEMW(level_finished, 1); } // seg000:41F4 MOV(sp, bp); POP(bp); RET; } // 41F8 void think_17() { RETLOC(4213); assert(reg_eip == 0x41F8); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:4205 if ((short)reg_ax >= 0xc8) { // seg000:420A W_MEMW(sprite_copy.sync_time, 0xfc19); EMU_CALL(a_get_random, 4213, think_17); reg_ax += 0xff80; W_MEMW(sprite_copy.vel_x, reg_ax); W_MEMW(sprite_copy.vel_y, 0xfe70); } // seg000:421F reg_ax = MEMW(tick_count); reg_ax >>= 4; reg_ax &= 1; reg_ax += 0x16; W_MEMW(sprite_copy.cur_frame, reg_ax); reg_ax = MEMW(sprite_copy.vel_x); reg_ax *= MEMW(sprite_sync); W_MEMW(sprite_copy.delta_x, reg_ax); reg_ax = MEMW(sprite_copy.vel_y); reg_ax *= MEMW(sprite_sync); W_MEMW(sprite_copy.delta_y, reg_ax); int tmp1 = MEMD(sprite_copy.box_bottom_y); if (tmp1 < (int)MEMD(scroll_y_lo)) { // seg000:4258 W_MEMW(sprite_copy.type, 0); } // seg000:425E POP(bp); RET; } // 4260 void kill_keen() { RETLOC(42A8); assert(reg_eip == 0x4260); PUSH(bp); MOV(bp, sp); // seg000:4263 if (MEMW(god_mode) == 0 && MEMW(word_1B2A6) == 0) { // seg000:4271 W_MEMW(keen_think_func, a_think_17); W_MEMW(keen_contact_func, a_think_contact_nop); W_MEMD(keen_pos_y, MEMD(keen_pos_y) + 0x800); W_MEMW(keen_vel_y, 0); W_MEMW(keen_vel_x, 0); W_MEMW(keen_sync_time, 0); W_MEMW(keen_cur_frame, 0x16); PUSHI(8); EMU_CALL(a_set_cur_sound, 42A8, kill_keen); reg_sp += 2; } // seg000:42AA POP(bp); RET; } // 42EA void detect_background_col()() { RETLOC(452D); RETLOC(4477); RETLOC(43EE); RETLOC(439E); RETLOC(438A); RETLOC(4511); RETLOC(44E4); RETLOC(44B8); RETLOC(4480); RETLOC(43F7); assert(reg_eip == 0x42ea); PUSH(bp); MOV(bp, sp); reg_sp -= 0xc; PUSH(si); PUSH(di); // seg000:42F2 if (MEMW(keen_think_func) == a_think_17) { // seg000:458A POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:42FD store all tiles that keen touches in reg_bp - 2 to reg bp -8 W_MEMW(word_1B2A8, 0); int tmp1 = MEMD(keen_box_left_x) >> 0xc; W_MEMW(reg_bp - 2, tmp1 & 0xffff); tmp1 = MEMD(keen_box_right_x) >> 0xc; W_MEMW(reg_bp - 6, tmp1 & 0xffff); tmp1 = MEMD(keen_box_top_y) >> 0xc; W_MEMW(reg_bp - 4, tmp1 & 0xffff); tmp1 = MEMD(keen_box_bottom_y) >> 0xc; W_MEMW(reg_bp - 8, tmp1 & 0xffff); // seg000:433F reg_di = MEMW(reg_bp - 2); // seg000:4582 while ((short)reg_di <= (short)MEMW(reg_bp - 6)) { //tile x coordinate // seg000:4345 reg_si = MEMW(reg_bp - 4); // seg000:4579 while ((short)reg_si <= (short)MEMW(reg_bp - 8)) { //tile y coordinate // seg000:434B MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 0xc, reg_ax); reg_bx = MEMW(reg_bp - 0xc); reg_bx <<= 1; reg_ax = MEMW(tile_kind_tbl + reg_bx); W_MEMW(reg_bp - 0xa, reg_ax); // seg000:436D if (reg_ax != 0) { // seg000:4374 reg_bx = MEMW(reg_bp - 0xa); reg_bx--; // seg000:4378 if (reg_bx <= 0x19) { // seg000:4380 switch(reg_bx) { case 0: // nasties // seg000:4387 EMU_CALL(a_kill_keen, 438A, detect_background_col()); break; case 1: // doors case 2: case 3: case 4: // seg000:438D reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 1; if (MEMW(got_pogo + reg_bx) != 0) { // seg000:4399 PUSH(si); PUSH(di); EMU_CALL(a_open_door, 439E, detect_background_col()); reg_sp += 4; } else if ((short)MEMW(keen_delta_x) > 0) { // seg000:43A4 // seg000:43AB tmp1 = MEMD(keen_pos_x); tmp1 &= 0xfffff000; W_MEMD(keen_pos_x, tmp1); } else { // seg000:43C3 tmp1 = MEMD(keen_pos_x); tmp1 += 0x1000; tmp1 &= 0xfffff000; W_MEMD(keen_pos_x, tmp1); } break; case 5: // treasure case 6: case 7: case 8: case 9: // seg000:43E2 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 1; PUSHI(MEMW(reg_bx + points_tbl - 12)); EMU_CALL(a_add_score, 43EE, detect_background_col()); reg_sp += 2; // seg000:43F0 PUSHI(9); EMU_CALL(a_set_cur_sound, 43F7, detect_background_col()); reg_sp += 2; // seg000:43F9 MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; // seg000:4409 if (mem_readw(SegPhys(es) + reg_bx) < 0x131) { // seg000:4410 MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x8f); break; } // seg000:4428 MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x114); break; case 10: // parts case 11: case 12: case 13: // seg000:4440 if (MEMW(reg_bp - 0xa) == 0xb) { // seg000:4446 W_MEMW(got_part_1, 1); } // seg000:444C if (MEMW(reg_bp - 0xa) == 0xc) { // seg000:4452 W_MEMW(got_part_2, 1); } // seg000:4458 if (MEMW(reg_bp - 0xa) == 0xd) { // seg000:445E W_MEMW(got_part_3, 1); } // seg000:4464 if (MEMW(reg_bp - 0xa) == 0xe) { // seg000:446A W_MEMW(got_part_4, 1); } // seg000:4470 PUSHI(10000); EMU_CALL(a_add_score, 4477, detect_background_col()); reg_sp += 2; // seg000:4479 PUSHI(0x0b); EMU_CALL(a_set_cur_sound, 4480, detect_background_col()); reg_sp += 2; // seg000:4482 MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x8f); break; case 14: // raygun case 15: // pogo // seg000:449A if (MEMW(reg_bp - 0xa) == 15) { // seg000:44A0 W_MEMW(ray_gun_charge, MEMW(ray_gun_charge) + 5); } // seg000:44A5 if (MEMW(reg_bp - 0xa) == 0x10) { // seg000:44AB W_MEMW(got_pogo, 1); } // seg000:44B1 PUSHI(0x0a); EMU_CALL(a_set_cur_sound, 44B8, detect_background_col()); reg_sp += 2; // seg000:44BA MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x8f); break; case 16: // exit // seg000:44D2 if (MEMW(keen_think_func) == a_think_13) { // seg000:44DD PUSHI(0xf); EMU_CALL(a_set_cur_sound, 44E4, detect_background_col()); reg_sp += 2; // seg000:44E6 W_MEMW(keen_think_func, a_think_18); W_MEMW(keen_contact_func, a_think_contact_nop); MOV(ax, di); reg_ax += 2; W_MEMW(keen_sync_time, reg_ax); W_MEMW(keen_frame_countdown, reg_si); } break; case 17: // keycards case 18: case 19: case 20: // seg000:44FF reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 1; W_MEMW(word_1DACA + reg_bx, 1); PUSHI(0x20); EMU_CALL(a_set_cur_sound, 4511, detect_background_col()); reg_sp += 2; // seg000:4513 MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x8f); break; case 21: // message giver // seg000:452A EMU_CALL(a_show_message, 452D, detect_background_col()); // seg000:452D if (MEMW(current_level) == 0xb) { //11 = garg statue level // seg000:4534 MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x1b2); } else { // seg000:454B MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x13b); } break; case 22: // switches case 24: case 25: // seg000:4562 W_MEMW(word_1B2A8, 1); W_MEMW(current_tile_x, reg_di); //x W_MEMW(current_tile_y, reg_si); //y break; case 23: // teleporter to secret city // seg000:4572 W_MEMW(level_finished, 2); break; } } } // seg000:4578 reg_si++; } // seg000:4581 reg_di++; } // seg000:458A POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 45C4 void think_16() { RETLOC(4694); RETLOC(4678); RETLOC(4642); assert(reg_eip == 0x45c4); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_di = MEMW(reg_bp + 6); reg_bx = MEMW(reg_di); reg_bx -= 2; // seg000:45D3 if (reg_bx <= 0xd) { // seg000:45DB bool do_4693 = false; switch(reg_bx) { case 0: // seg000:45E2 if (MEMW(reg_di + 50) != a_think_20_yorp_incapacitated) { // seg000:45EC if ((short)MEMW(reg_si + 24) > 0) { // seg000:45F2 int tmp1 = (int)MEMD(reg_si + 8); tmp1 += 0x800; if (tmp1 < (int)MEMD(reg_di + 8)) { // seg000:4627 W_MEMW(reg_di + 50, a_think_20_yorp_incapacitated); W_MEMW(reg_di + 42, 0); W_MEMW(reg_si + 34, 0); W_MEMW(reg_si + 50, a_think_13); PUSHI(0x1f); EMU_CALL(a_set_cur_sound, 4642, think_16); reg_sp += 2; break; } } // seg000:460B W_MEMW(reg_si + 34, 0); // seg000:4610 if ((short)MEMW(reg_di + 32) > 0) { // seg000:4616 W_MEMW(reg_si + 32, 0xf0); } else { // seg000:461D W_MEMW(reg_si + 32, 0xff10); } // seg000:4622 reg_ax = 0x1d; do_4693 = true; } break; case 1: case 2: case 9: // seg000:4662 if (MEMW(reg_di) == 0xb && MEMW(reg_si + 50) == a_think_14) { // seg000:466E W_MEMW(reg_si + 42, 0); } else { // seg000:4675 EMU_CALL(a_kill_keen, 4678, think_16); } break; case 3: case 4: // seg000:4646 W_MEMW(reg_si + 34, 0); // seg000:464B if ((short)MEMW(reg_di + 32) > 0) { // seg000:4651 W_MEMW(reg_si + 32, 0xf0); } else { // seg000:4658 W_MEMW(reg_si + 32, 0xff10); } // seg000:465D reg_ax = 0x1d; do_4693 = true; break; case 13: // seg000:467A W_MEMW(reg_si + 50, a_think_14); reg_ax = MEMW(reg_di + 32); W_MEMW(reg_si + 32, reg_ax); reg_ax = MEMW(reg_di + 34); W_MEMW(reg_si + 34, reg_ax); W_MEMW(reg_si + 42, 0x320); reg_ax = 0x28; do_4693 = true; break; } if (do_4693) { // seg000:4693 PUSH(ax); EMU_CALL(a_set_cur_sound, 4694, think_16); reg_sp += 2; } } // seg000:4699 POP(di); POP(si); POP(bp); RET; } // 46BA void add_monster_8() { RETLOC(47D4); RETLOC(47C1); RETLOC(4797); RETLOC(4763); RETLOC(4750); RETLOC(472E); RETLOC(46C1); assert(reg_eip == 0x46ba); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_monster, 46C1, add_monster_8); MOV(si, ax); W_MEMW(reg_si, 0xa); int tmp1 = MEMD(reg_bp + 4); W_MEMD(reg_si + 4, tmp1); tmp1 = MEMD(reg_bp + 8); tmp1 += 0x900; W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 50, a_think_9_raygun_flight); W_MEMW(reg_si + 34, 0); W_MEMW(reg_si + 52, a_contact_9_raygun); W_MEMW(reg_si + 40, 0x6c); // seg000:46FA The rest of this routine is to make a "zot" if the shot is spawned inside a block if ((short)MEMW(word_1909C) >= 0) { // seg000:4701 W_MEMW(reg_si + 32, 0x190); tmp1 = MEMD(reg_bp + 4); tmp1 >>= 0xc; PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp + 8); tmp1 >>= 0xc; tmp1 += 1; PUSHI(tmp1 & 0xffff); PUSHI(tmp1 >> 16); tmp1 = (short)MEMW(map_width_intiles); reg_dx = tmp1 >> 16; reg_ax = tmp1 & 0xffff; POP(cx); POP(bx); EMU_CALL(a__LXMUL, 472E, add_monster_8); POP(dx); reg_dx += reg_ax; reg_dx++; reg_dx <<= 1; // seg000:4734 reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; // seg000:473F if (MEMW(word_13F4A + reg_bx) != 0) { // seg000:4749 PUSHI(0x25); EMU_CALL(a_set_cur_sound, 4750, add_monster_8); reg_sp += 2; W_MEMW(reg_si, 0xd); W_MEMW(reg_si + 50, a_think_11); W_MEMW(reg_si + 42, 0); EMU_CALL(a_get_random, 4763, add_monster_8); // seg000:4763 if (reg_ax > 0x80) { // seg000:4768 W_MEMW(reg_si + 40, 0x6e); } else { // seg000:476F W_MEMW(reg_si + 40, 0x6f); } } } else { // seg000:4776 W_MEMW(reg_si + 32, 0xfe70); int tmp1 = MEMD(reg_bp + 8); tmp1 >>= 0xc; tmp1++; PUSHI(tmp1 & 0xffff); PUSHI(tmp1 >> 16); tmp1 = (short)MEMW(map_width_intiles); reg_dx = tmp1 >> 16; reg_ax = tmp1 & 0xffff; POP(cx); POP(bx); EMU_CALL(a__LXMUL, 4797, add_monster_8); PUSH(ax); tmp1 = MEMD(reg_bp + 4); tmp1 >>= 0xc; POP(dx); reg_dx += reg_ax; reg_dx <<= 1; // seg000:47A8 reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; // seg000:47B3 if (MEMW(word_148D6 + reg_bx) != 0) { // seg000:47BA PUSHI(0x25); EMU_CALL(a_set_cur_sound, 47C1, add_monster_8); reg_sp += 2; W_MEMW(reg_si, 0xd); W_MEMW(reg_si + 50, a_think_11); W_MEMW(reg_si + 42, 0); EMU_CALL(a_get_random, 47D4, add_monster_8); // seg000:47D4 if ((short)reg_ax > 0x80) { // seg000:47D9 W_MEMW(reg_si + 40, 0x6e); } else { // seg000:47E0 W_MEMW(reg_si + 40, 0x6f); } } } // seg000:47E5 POP(si); POP(bp); RET; } // 47E8 void think_11() { PUSH(bp); MOV(bp, sp); W_MEMW(sprite_copy.type, 0xe); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:47FB if ((short)reg_ax > 0x14) { // seg000:4800 W_MEMW(sprite_copy.type, 0); } // seg000:4806 POP(bp); RET; } // 4808 void think_9_raygun_flight() { RETLOC(4833); RETLOC(4819); RETLOC(480F); assert(reg_eip == 0x4808); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_compute_sprite_delta, 480F, think_9_raygun_flight); MOV(si, ax); // seg000:4811 if (reg_ax != 0) { // seg000:4815 PUSHI(0x25); EMU_CALL(a_set_cur_sound, 4819, think_9_raygun_flight); reg_sp += 2; // seg000:481E W_MEMW(sprite_copy.type, 0x0d); W_MEMW(sprite_copy.think_func, a_think_11); W_MEMW(sprite_copy.sync_time, 0); EMU_CALL(a_get_random, 4833, think_9_raygun_flight); // seg000:4833 if ((short)reg_ax > 0x80) { // seg000:4838 W_MEMW(sprite_copy.cur_frame, 0x6e); } else { // seg000:4840 W_MEMW(sprite_copy.cur_frame, 0x6f); } } // seg000:4846 POP(si); POP(bp); RET; } // 4849 void contact_9_raygun() { RETLOC(4879); RETLOC(4865); assert(reg_eip == 0x4849); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_di = MEMW(reg_bp + 6); // seg000:4854 if (MEMW(reg_di) != 1 && MEMW(reg_di) != 0xe) { // seg000:485E PUSHI(0x25); EMU_CALL(a_set_cur_sound, 4865, contact_9_raygun); reg_sp += 2; W_MEMW(reg_si + 50, a_think_11); W_MEMW(reg_si + 52, a_think_contact_nop); W_MEMW(reg_si + 42, 0); EMU_CALL(a_get_random, 4879, contact_9_raygun); // seg000:4879 if ((short)reg_ax > 0x80) { // seg000:487E W_MEMW(reg_si + 40, 0x6e); } else { // seg000:4885 W_MEMW(reg_si + 40, 0x6f); } } // seg000:488A POP(di); POP(si); POP(bp); RET; } // 488E void think_34() { // dead yorp? (dead anything?) RETLOC(489B); RETLOC(4898); assert(reg_eip == 0x488e); PUSH(bp); MOV(bp, sp); W_MEMW(sprite_copy.sync_time, MEMW(sprite_copy.sync_time) + 1); EMU_CALL(a_do_fall, 4898, think_34); EMU_CALL(a_compute_sprite_delta, 489B, think_34); POP(bp); RET; } // 489D void think_12() { //dying yorp? RETLOC(48DC); RETLOC(48D9); assert(reg_eip == 0x489d); PUSH(bp); MOV(bp, sp); W_MEMW(sprite_copy.type, 0xe); reg_ax = MEMW(sprite_copy.sync_time); reg_ax += MEMW(sprite_sync); W_MEMW(sprite_copy.sync_time, reg_ax); // seg000:48B0 if ((short)reg_ax > 0x28) { // seg000:48B5 W_MEMW(sprite_copy.sync_time, MEMW(sprite_copy.sync_time) - 0x28); W_MEMW(sprite_copy.cur_frame, MEMW(sprite_copy.cur_frame) + 1); // move from zapping to zapped frame W_MEMW(sprite_copy.frame_countdown, MEMW(sprite_copy.frame_countdown) - 1); reg_ax = MEMW(sprite_copy.frame_countdown); if (reg_ax == 1) { // seg000:48CA W_MEMW(sprite_copy.think_func, a_think_34); } } // seg000:48D0 W_MEMW(sprite_copy.vel_x, 0); EMU_CALL(a_do_fall, 48D9, think_12); EMU_CALL(a_compute_sprite_delta, 48DC, think_12); POP(bp); RET; } // 48DE void add_monster_9_tank_shot() { RETLOC(49EC); RETLOC(49D9); RETLOC(49AF); RETLOC(4980); RETLOC(496D); RETLOC(494B); RETLOC(48E5); assert(reg_eip == 0x48DE); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_monster, 48E5, add_monster_9_tank_shot); MOV(si, ax); W_MEMW(reg_si , 0xb); int tmp1 = MEMD(reg_bp + 4); W_MEMD(reg_si + 4, tmp1); tmp1 = MEMD(reg_bp + 8); tmp1 += 0x500; W_MEMD(reg_si + 8, tmp1); W_MEMW(reg_si + 50, a_think_9_raygun_flight); reg_ax = MEMW(reg_bp + 12); W_MEMW(reg_si + 32, reg_ax); W_MEMW(reg_si + 52, a_contact_10); W_MEMW(reg_si + 40, 0x6d); // seg000:491F if ((short)reg_ax >= 0) { // seg000:4923 tmp1 = MEMD(reg_bp + 4); tmp1 >>= 0xc; PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp + 8); tmp1 >>= 0xc; tmp1 += 1; PUSHI(tmp1 & 0xffff); PUSHI(tmp1 >> 16); tmp1 = (short)MEMW(map_width_intiles); reg_ax = tmp1 & 0xffff; reg_dx = tmp1 >> 16; POP(cx); POP(bx); EMU_CALL(a__LXMUL, 494B, add_monster_9_tank_shot); // seg000:494B POP(dx); reg_dx += reg_ax; reg_dx++; reg_dx <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; // seg000:495C if (MEMW(word_13F4A + reg_bx) != 0) { //blocking right // seg000:4966 PUSHI(0x25); EMU_CALL(a_set_cur_sound, 496D, add_monster_9_tank_shot); reg_sp += 2; W_MEMW(reg_si, 0xd); W_MEMW(reg_si + 50, a_think_11); W_MEMW(reg_si + 42, 0); EMU_CALL(a_get_random, 4980, add_monster_9_tank_shot); // seg000:4980 if ((short)reg_ax > 0x80) { // seg000:4985 W_MEMW(reg_si + 40, 0x6e); } else { // seg000:498C W_MEMW(reg_si + 40, 0x6f); } } } else { // seg000:4993 tmp1 = MEMD(reg_bp + 8); tmp1 >>= 0xc; tmp1++; PUSHI(tmp1 & 0xffff); PUSHI(tmp1 >> 16); tmp1 = (short)MEMW(map_width_intiles); reg_ax = tmp1 & 0xffff; reg_dx = tmp1 >> 16; POP(cx); POP(bx); EMU_CALL(a__LXMUL, 49AF, add_monster_9_tank_shot); // seg000:49AF PUSH(ax); tmp1 = MEMD(reg_bp + 4); tmp1 >>= 0xc; POP(dx); reg_dx += tmp1 & 0xffff; reg_dx <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; // seg000:49CB if (MEMW(word_148D6 + reg_bx) != 0) { //blocking left // seg000:49D2 PUSHI(0x25); EMU_CALL(a_set_cur_sound, 49D9, add_monster_9_tank_shot); reg_sp += 2; W_MEMW(reg_si, 0xd); W_MEMW(reg_si + 50, a_think_11); W_MEMW(reg_si + 42, 0); EMU_CALL(a_get_random, 49EC, add_monster_9_tank_shot); // seg000:49EC if ((short)reg_ax > 0x80) { // seg000:49F1 W_MEMW(reg_si + 40, 0x6e); } else { // seg000:49F8 W_MEMW(reg_si + 40, 0x6f); } } } // seg000:49FD POP(si); POP(bp); RET; } // 4A00 void contact_10() { RETLOC(4A30); RETLOC(4A1C); assert(reg_eip == 0x4A00); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_di = MEMW(reg_bp + 6); // seg000:4A0B if (MEMW(reg_di) != 6 && MEMW(reg_di) != 0xe) { // seg000:4A15 PUSHI(0x25); EMU_CALL(a_set_cur_sound, 4A1C, contact_10); reg_sp += 2; W_MEMW(reg_si + 50, a_think_11); W_MEMW(reg_si + 42, 0); W_MEMW(reg_si + 52, a_think_contact_nop); EMU_CALL(a_get_random, 4A30, contact_10); // seg000:4A30 if ((short)reg_ax > 0x80) { // seg000:4A35 W_MEMW(reg_si + 40, 0x6e); } else { // seg000:4A3C W_MEMW(reg_si + 40, 0x6f); } } // seg000:4A41 POP(di); POP(si); POP(bp); RET; } // 4B69 void draw_level() { RETLOC(4BD4); RETLOC(4F43); RETLOC(4F40); RETLOC(4CA4); RETLOC(4CA1); RETLOC(4C9E); RETLOC(4C9B); RETLOC(4C92); RETLOC(4C8F); RETLOC(4E47); RETLOC(4E3F); RETLOC(4E33); RETLOC(4DF8); RETLOC(4CE4); RETLOC(4CD6); RETLOC(4CC5); RETLOC(4DE3); RETLOC(4D45); RETLOC(4D2A); RETLOC(4D1E); RETLOC(4D14); RETLOC(4DD6); RETLOC(4DBB); RETLOC(4DAF); RETLOC(4D04); RETLOC(4F0F); RETLOC(4F0C); RETLOC(4F09); RETLOC(4EF9); RETLOC(4EE4); RETLOC(4ECB); RETLOC(4EB9); assert(reg_eip == 0x4b69); PUSH(bp); MOV(bp, sp); reg_sp -= 0x12; PUSH(si); PUSH(di); W_MEMW(sprite_array_offset, 1); W_MEMW(keen_think_func, a_think_13); W_MEMW(keen_contact_func, a_think_16); W_MEMW(keen_vel_y, 0); W_MEMW(keen_vel_x, 0); W_MEMW(keen_cur_frame, 4); W_MEMW(keen_active, 1); W_MEMW(num_monsters, 1); W_MEMW(num_bodies, 0); W_MEMW(reg_bp - 2, 1); W_MEMW(word_1909C, 1); W_MEMW(sprite_sync, 0); W_MEMW(tick_count_2, 0); W_MEMW(tick_count_2 + 2, 0); W_MEMW(tick_count, 0); W_MEMW(tick_count + 2, 0); W_MEMW(word_1B2A6, 0); W_MEMW(god_mode, 0); W_MEMW(level_finished, 0); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_init_level, 4BD4, draw_level); reg_sp += 2; // seg000:4BD6 set screen position int tmp1 = MEMD(keen_pos_x); tmp1 += 0xffff6000; W_MEMD(scroll_x_lo, tmp1); // seg000:4BEB tmp1 = MEMD(keen_pos_y); tmp1 += 0xffffb000; W_MEMD(scroll_y_lo, tmp1); // seg000:4C00 within map border tmp1 = MEMD(scroll_x_lo); if (tmp1 < (int)MEMD(dword_1869A)) { // seg000:4C15 tmp1 = MEMD(dword_1869A); W_MEMD(scroll_x_lo, tmp1); } // seg000:4C23 tmp1 = MEMD(scroll_y_lo); if (tmp1 < (int)MEMD(dword_1869E)) { // seg000:4C38 tmp1 = MEMD(dword_1869E); W_MEMD(scroll_y_lo, tmp1); } // seg000:4C46 tmp1 = MEMD(scroll_x_lo); if (tmp1 > (int)MEMD(dword_1B00E)) { // seg000:4C5B tmp1 = MEMD(dword_1B00E); W_MEMD(scroll_x_lo, tmp1); } // seg000:4C69 tmp1 = MEMD(scroll_y_lo); if (tmp1 > (int)MEMD(dword_1B012)) { // seg000:4C7E tmp1 = MEMD(dword_1B012); W_MEMD(scroll_y_lo, tmp1); } // seg000:4C8C EMU_CALL(a_sync_drawing, 4C8F, draw_level); EMU_CALL(a_fade_out, 4C92, draw_level); W_MEMW(toggle_lights, 1); EMU_CALL(a_clear_overlay, 4C9B, draw_level); EMU_CALL(a_draw_screen, 4C9E, draw_level); EMU_CALL(a_draw_screen, 4CA1, draw_level); EMU_CALL(a_fade_in, 4CA4, draw_level); // seg000:4CA4 tmp1 = MEMD(scroll_x_lo); tmp1 >>= 0xc; W_MEMW(word_186A6, tmp1 & 0xffff); // seg000:4CB3 tmp1 = MEMD(scroll_y_lo); tmp1 >>= 0xc; W_MEMW(word_18B62, tmp1 & 0xffff); do { // main in level loop // seg000:4CC2 EMU_CALL(a_sync_drawing, 4CC5, draw_level); reg_ax = input.direction; PUSHI(SegValue(ds)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x12; PUSH(ax); EMU_CALL(a_handle_ctrl, 4CD6, draw_level); reg_sp += 6; // seg000:4CD9 reg_ax = reg_bp - 0x12; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 4CE4, draw_level); // seg000:4CE4 reg_si = sprite_array_offset; // start of sprite array W_MEMW(reg_bp - 8, 0); while (1) { // sprite think loop // seg000:4DE9 reg_ax = MEMW(reg_bp - 8); //break loop after all monsters updated if ((short)reg_ax >= (short)MEMW(num_monsters)) break; // seg000:4CEF if (MEMW(reg_si) != 0) { // don't update if sprite is "ID: 0" // seg000:4CF7 reg_ax = sprite_copy.type; //copy 36 bytes PUSHI(SegValue(ds)); //to sprite_copy PUSH(ax); PUSHI(SegValue(ds)); //from current sprite in sprite array PUSH(si); reg_cx = 0x36; EMU_CALL(a_N_SCOPY, 4D04, draw_level); // seg000:4D04 if (MEMW(sprite_copy.active) == 0) { // if sprite isn't active // seg000:4D48 tmp1 = MEMD(sprite_copy.pos_x_lo); tmp1 >>= 0xc; W_MEMW(reg_bp - 4, tmp1 & 0xffff); tmp1 = MEMD(sprite_copy.pos_y_lo); tmp1 >>= 0xc; W_MEMW(reg_bp - 6, tmp1 & 0xffff); reg_ax = MEMW(word_186A6); reg_ax += 0xfffe; // seg000:4D6C if ((short)reg_ax < (short)MEMW(reg_bp - 4)) { // seg000:4D71 reg_ax = MEMW(word_18B62); reg_ax += 0xfffe; // seg000:4D77 if ((short)reg_ax < (short)MEMW(reg_bp - 6)) { // seg000:4D7C reg_ax = MEMW(word_186A6); reg_ax += 0x17; // seg000:4D82 if ((short)reg_ax > (short)MEMW(reg_bp - 4)) { // seg000:4D87 reg_ax = MEMW(word_18B62); reg_ax += 0xc; // seg000:4D8D if ((short)reg_ax > (short)MEMW(reg_bp - 6)) { // seg000:4D92 W_MEMW(sprite_copy.active, 1); // seg000:4D98 if (MEMW(sprite_copy.think_func) == a_think_20_yorp_incapacitated) { // seg000:4DA0 W_MEMW(sprite_copy.think_func, a_think_yorp_look); W_MEMW(sprite_copy.sync_time, 0); } // seg000:4DAC EMU_CALL(a_sub_2A3B, 4DAF, draw_level); W_MEMW(sprite_copy.delta_y, 0); W_MEMW(sprite_copy.delta_x, 0); EMU_CALL(MEMW(sprite_copy.think_func), 4DBB, draw_level); tmp1 = (short)MEMW(sprite_copy.delta_x); W_MEMD(sprite_copy.pos_x_lo, MEMD(sprite_copy.pos_x_lo) + tmp1); tmp1 = (short)MEMW(sprite_copy.delta_y); W_MEMD(sprite_copy.pos_y_lo, MEMD(sprite_copy.pos_y_lo) + tmp1); EMU_CALL(a_sub_2A3B, 4DD6, draw_level); } } } } } else if (MEMW(reg_bp - 8) != 0) { // if sprite is active // seg000:4D11 EMU_CALL(a_sprite_active_screen, 4D14, draw_level); // seg000:4D14 if (reg_ax == 0) //sprite_active_screen() determines sprite inbounds, returned in ax goto loc_4D1B; } else { loc_4D1B: // seg000:4D1B EMU_CALL(a_sub_2A3B, 4D1E, draw_level); // update sprite position W_MEMW(sprite_copy.delta_y, 0); W_MEMW(sprite_copy.delta_x, 0); EMU_CALL(MEMW(sprite_copy.think_func), 4D2A, draw_level); // call sprite think function tmp1 = (short)MEMW(sprite_copy.delta_x); W_MEMD(sprite_copy.pos_x_lo, MEMD(sprite_copy.pos_x_lo) + tmp1); tmp1 = (short)MEMW(sprite_copy.delta_y); W_MEMD(sprite_copy.pos_y_lo, MEMD(sprite_copy.pos_y_lo) + tmp1); EMU_CALL(a_sub_2A3B, 4D45, draw_level); // update sprite position again } // seg000:4DD6 PUSHI(SegValue(ds)); //copy current_sprite back to sprite array PUSH(si); reg_ax = sprite_copy.type; PUSHI(SegValue(ds)); PUSH(ax); reg_cx = 0x36; EMU_CALL(a_N_SCOPY, 4DE3, draw_level); } // seg000:4DE3 W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) + 1); // one less sprite to update reg_si += 0x36; // move pointer to next sprite struct } //end think loop // seg000:4DF5 EMU_CALL(a_do_scrolling, 4DF8, draw_level); // scroll screen reg_si = sprite_array_offset; // point si to first sprite (i.e. keen) W_MEMW(reg_bp - 8, 0); // num_monsters = 0 while(1) { // collision detection loop: outer loop // seg000:4E5F reg_ax = MEMW(reg_bp - 8); if ((short)reg_ax >= (short)MEMW(num_monsters)) break; // seg000:4E02 if (MEMW(reg_si) != 0 && MEMW(reg_si + 2) != 0) { //sprite type != 0 and sprite is active // seg000:4E0D reg_ax = MEMW(reg_bp - 8); reg_ax *= 54; reg_ax += monsters; MOV(di, ax); // point di to next sprite reg_ax = MEMW(reg_bp - 8); reg_ax++; W_MEMW(reg_bp - 0xa, reg_ax); // while (1) { // inner loop checks collisions of all sprite pointed to by di // seg000:4E50 // against the one pointed to by si reg_ax = MEMW(reg_bp - 0xa); // (i.e. "triangular" looping pattern) if ((short)reg_ax >= (short)MEMW(num_monsters)) break; // seg000:4E23 if (MEMW(reg_di) != 0 && MEMW(reg_di + 2) != 0) { // if sprite_di type != 0 and is active // seg000:4E2E PUSH(di); PUSH(si); EMU_CALL(a_detect_mnstr_col, 4E33, draw_level); //ax == 0 is no collision, ax == 1 is collision reg_sp += 4; // seg000:4E36 if (reg_ax != 0) { // if collision call the contact functions for both sprites // seg000:4E3A // passing offsets to beginning of sprite struct for collider and collidee PUSH(di); PUSH(si); EMU_CALL(MEMW(reg_si + 52), 4E3F, draw_level); reg_sp += 4; PUSH(si); PUSH(di); EMU_CALL(MEMW(reg_di + 52), 4E47, draw_level); reg_sp += 4; } } // seg000:4E4A W_MEMW(reg_bp - 0xa, MEMW(reg_bp - 0xa) + 1); // one less collision to check (inner loop) reg_di += 54; // point di to next sprite struct } } // seg000:4E59 W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) + 1); // one less sprite to check collisions for (outer loop) reg_si += 54; // point si to next sprite } // seg000:4E68 tmp1 = MEMD(scroll_x_lo); tmp1 >>= 0xc; W_MEMW(word_186A6, tmp1 & 0xffff); // seg000:4E77 tmp1 = MEMD(scroll_y_lo); tmp1 >>= 0xc; W_MEMW(word_18B62, tmp1 & 0xffff); // seg000:4E86 reg_ax = MEMW(num_monsters); reg_ax *= 54; reg_ax += unk_19EF4; // seems to be 0 MOV(si, ax); reg_ax = MEMW(num_monsters); reg_ax--; W_MEMW(reg_bp - 8, reg_ax); // seg000:4EC2 while ((short)MEMW(reg_bp - 8) >= 0) { //draw sprites // seg000:4E9C if (MEMW(reg_si) != 0 && MEMW(reg_si + 2) != 0) { // if type !=0 and active !=0 // seg000:4EA7 PUSHI(MEMW(reg_si + 40)); //current_frame PUSHI(MEMW(reg_si + 10)); //sprite_copy.pos_x_hi PUSHI(MEMW(reg_si + 8)); //pos_y_lo PUSHI(MEMW(reg_si + 6)); //sprite_copy.pos_y_hi PUSHI(MEMW(reg_si + 4)); //pos_x_lo EMU_CALL(a_draw_sprite_at, 4EB9, draw_level); reg_sp += 0xa; } // seg000:4EBC W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) - 1); reg_si -= 54; } // seg000:4EC8 EMU_CALL(a_detect_background_col(), 4ECB, draw_level); //keen level_data-tile collisions W_MEMW(reg_bp - 0xc, bodies); W_MEMW(reg_bp - 8, 0); while (1) { // required for sliding door // seg000:4EED reg_ax = MEMW(reg_bp - 8); if ((short)reg_ax >= (short)MEMW(num_bodies)) break; // seg000:4ED7 reg_bx = MEMW(reg_bp - 0xc); // seg000:4EDA, Also required for sliding door if (MEMW(reg_bx + 8) != 0) { // seg000:4EE0 called when vorticon shot --> flashes border PUSH(bx); EMU_CALL(MEMW(reg_bx + 34), 4EE4, draw_level); reg_sp += 2; } // seg000:4EE6 W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) + 1); W_MEMW(reg_bp - 0xc, MEMW(reg_bp - 0xc) + 0x24); } // seg000:4EF6 EMU_CALL(a_draw_screen, 4EF9, draw_level); reg_ax = input_old.direction; // copy input from this loop into previous frame input location PUSHI(SegValue(ds)); PUSH(ax); reg_ax = input.direction; PUSHI(SegValue(ds)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 4F09, draw_level); EMU_CALL(a_handle_cheat_keys, 4F0C, draw_level); EMU_CALL(a_handle_global_keys, 4F0F, draw_level); // seg000:4F0F if (reg_ax != 0) { // seg000:4F13 tmp1 = MEMD(tick_count); W_MEMW(tick_count_2, tmp1); } // seg000:4F21 if (MEMW(quit_to_title) != 0) { // quit to title // seg000:4F28 reg_ax = 0; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:4F2C } while (MEMW(level_finished) == 0 && MEMW(sprite_array_offset) != 0); // level not finished, keen still in level // seg000:4F3D EMU_CALL(a_finish_cur_sound, 4F40, draw_level); EMU_CALL(a_fade_out, 4F43, draw_level); W_MEMW(reg_bp - 4, 0); // seg000:4F58 remove keycards while ((short)MEMW(reg_bp - 4) < 4) { // seg000:4F4A reg_bx = MEMW(reg_bp - 4); reg_bx <<= 1; W_MEMW(got_yellow_keycard + reg_bx, 0); W_MEMW(reg_bp - 4, MEMW(reg_bp - 4) + 1); } // Lose BWB parts if you exit the level by dying // and that level has a part in it. // seg000:4F5E if (MEMW(level_finished) == 0) { // seg000:4F65 reg_ax = MEMW(reg_bp + 4); ///current level // seg000:4F68 if (reg_ax == 8) { // seg000:4F92 W_MEMW(got_part_3, 0); } else if ((short)reg_ax > 8) { // seg000:4F7B if (reg_ax == 0x10) { // seg000:4F9A W_MEMW(got_part_4, 0); } } else if (reg_ax == 3) { // seg000:4F82 W_MEMW(got_part_2, 0); } else if (reg_ax == 4) { // seg000:4F8A W_MEMW(got_part_1, 0); } } // seg000:4FA0 // return level_finished in ax reg_ax = MEMW(level_finished); // seg000:4FA3 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 4FA9 void handle_joystick() { RETLOC(51F4); RETLOC(5192); RETLOC(5184); RETLOC(5173); RETLOC(514E); RETLOC(5140); RETLOC(512F); RETLOC(5116); RETLOC(510C); RETLOC(50F8); RETLOC(50EF); RETLOC(50E6); RETLOC(50DD); RETLOC(50D0); RETLOC(50C2); RETLOC(50B1); RETLOC(508C); RETLOC(507E); RETLOC(506D); RETLOC(5054); RETLOC(504A); RETLOC(5033); RETLOC(502A); RETLOC(5021); RETLOC(5018); RETLOC(500F); RETLOC(4FF9); RETLOC(4FDB); RETLOC(4FBF); assert(reg_eip == 0x4fa9); PUSH(bp); MOV(bp, sp); reg_sp -= 0x32; PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 4); PUSHI(9); PUSHI(0x1c); EMU_CALL(a_draw_box_opening2, 4FBF, handle_joystick); reg_sp += 4; W_MEMW(reg_bp - 2, 0); W_MEMW(reg_bp - 4, 0); reg_ax = reg_bp - 8; PUSH(ax); reg_ax = reg_bp - 6; PUSH(ax); PUSHI(1); EMU_CALL(a_poll_joystick, 4FDB, handle_joystick); reg_sp += 6; // seg000:4FDE if ((short)MEMW(reg_bp - 6) < 0x1f4) { // seg000:4FE5 W_MEMW(reg_bp - 2, 1); } // seg000:4FEA reg_ax = reg_bp - 8; PUSH(ax); reg_ax = reg_bp - 6; PUSH(ax); PUSHI(2); EMU_CALL(a_poll_joystick, 4FF9, handle_joystick); reg_sp += 6; // seg000:4FFC if ((short)MEMW(reg_bp - 6) < 0x1f4) { // seg000:5003 W_MEMW(reg_bp - 2, 2); } // seg000:5008 PUSHI(aJoystickConfigurat); EMU_CALL(a_draw_string, 500F, handle_joystick); reg_sp += 2; // seg000:5011 PUSHI(asc_155C4); EMU_CALL(a_draw_string, 5018, handle_joystick); reg_sp += 2; // seg000:501A PUSHI(aHoldTheJoystickInT); EMU_CALL(a_draw_string, 5021, handle_joystick); reg_sp += 2; // seg000:5023 PUSHI(aUpperLeft); EMU_CALL(a_draw_string, 502A, handle_joystick); reg_sp += 2; // seg000:502C PUSHI(aCornerAndPressButt); EMU_CALL(a_draw_string, 5033, handle_joystick); reg_sp += 2; // seg000:5035 reg_si = 9; do { // seg000:5038 PUSH(si); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 504A, handle_joystick); reg_sp += 6; // seg000:504D PUSHI(3); EMU_CALL(a_delay, 5054, handle_joystick); reg_sp += 2; // seg000:5056 reg_si++; MOV(ax, si); // seg000:5059 if (reg_ax == 0xc) { // seg000:505E reg_si = 9; } // seg000:5061 reg_ax = reg_bp - 0x10; PUSH(ax); reg_ax = reg_bp - 0xe; PUSH(ax); PUSH(di); EMU_CALL(a_poll_joystick, 506D, handle_joystick); reg_sp += 6; // seg000:5070 reg_ax = reg_bp - 0x1a; PUSHI(SegValue(ss)); PUSH(ax); PUSH(di); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x20; PUSH(ax); EMU_CALL(a_get_joystick_ctrl, 507E, handle_joystick); reg_sp += 6; // seg000:5081 reg_ax = reg_bp - 0x20; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 508C, handle_joystick); // seg000:508C if (MEMB(byte_1807D) != 0) { // seg000:5093 goto loc_51F1; } // seg000:5096 } while (MEMW(reg_bp - 0x18) != 1); // seg000:509C PUSHI(0x20); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 50B1, handle_joystick); reg_sp += 6; do { // seg000:50B4 reg_ax = reg_bp - 0x1a; PUSHI(SegValue(ss)); PUSH(ax); PUSH(di); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x26; PUSH(ax); EMU_CALL(a_get_joystick_ctrl, 50C2, handle_joystick); reg_sp += 6; reg_ax = reg_bp - 0x26; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 50D0, handle_joystick); // seg000:50D0 } while (MEMW(reg_bp - 0x18) != 0); // seg000:50D6 PUSHI(2); EMU_CALL(a_delay, 50DD, handle_joystick); reg_sp += 2; // seg000:50DF PUSHI(aHoldTheJoystickI_0); EMU_CALL(a_draw_string, 50E6, handle_joystick); reg_sp += 2; // seg000:50E8 PUSHI(aLowerRight); EMU_CALL(a_draw_string, 50EF, handle_joystick); reg_sp += 2; // seg000:50F1 PUSHI(aCornerAndPressBu_0); EMU_CALL(a_draw_string, 50F8, handle_joystick); reg_sp += 2; do { // seg000:50FA PUSH(si); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 510C, handle_joystick); reg_sp += 6; // seg000:510F PUSHI(3); EMU_CALL(a_delay, 5116, handle_joystick); reg_sp += 2; // seg000:5118 reg_si++; MOV(ax, si); // seg000:511B if (reg_ax == 0xc) { // seg000:5120 reg_si = 9; } // seg000:5123 reg_ax = reg_bp - 0x14; PUSH(ax); reg_ax = reg_bp - 0x12; PUSH(ax); PUSH(di); EMU_CALL(a_poll_joystick, 512F, handle_joystick); reg_sp += 6; // seg000:5132 reg_ax = reg_bp - 0x1a; PUSHI(SegValue(ss)); PUSH(ax); PUSH(di); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x2c; PUSH(ax); EMU_CALL(a_get_joystick_ctrl, 5140, handle_joystick); reg_sp += 6; // seg000:5143 reg_ax = reg_bp - 0x2c; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 514E, handle_joystick); // seg000:514E if (MEMB(byte_1807D) != 0) { // seg000:5155 goto loc_51F1; } // seg000:5158 } while (MEMW(reg_bp - 0x18) != 1); // seg000:515E PUSHI(0x20); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 5173, handle_joystick); reg_sp += 6; do { // seg000:5176 reg_ax = reg_bp - 0x1a; PUSHI(SegValue(ss)); PUSH(ax); PUSH(di); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x32; PUSH(ax); EMU_CALL(a_get_joystick_ctrl, 5184, handle_joystick); reg_sp += 6; // seg000:5187 reg_ax = reg_bp - 0x32; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 5192, handle_joystick); // seg000:5192 } while (MEMW(reg_bp - 0x18) != 0); // seg000:5198 reg_ax = MEMW(reg_bp - 0x12); reg_ax -= MEMW(reg_bp - 0xe); int tmp1 = (short)reg_ax; tmp1 /= 4; W_MEMW(reg_bp - 0xa, tmp1 & 0xffff); // seg000:51A7 reg_ax = MEMW(reg_bp - 0x14); reg_ax -= MEMW(reg_bp - 0x10); tmp1 = (short)reg_ax; tmp1 /= 4; W_MEMW(reg_bp - 0xc, tmp1 & 0xffff); // seg000:51B3 MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(reg_bp - 0xe); reg_ax += MEMW(reg_bp - 0xa); W_MEMW(word_1B2BA + reg_bx, reg_ax); // seg000:51C1 MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(reg_bp - 0x12); reg_ax -= MEMW(reg_bp - 0xa); W_MEMW(word_1B2C0 + reg_bx, reg_ax); // seg000:51CF MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(reg_bp - 0x10); reg_ax += MEMW(reg_bp - 0xc); W_MEMW(word_1B2C6 + reg_bx, reg_ax); // seg000:51CF MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(reg_bp - 0x14); reg_ax -= MEMW(reg_bp - 0xc); W_MEMW(word_1B2CC + reg_bx, reg_ax); // seg000:51EB W_MEMW(ctrl_type, 2); loc_51F1: // seg000:51F1 EMU_CALL(a_clear_keys, 51F4, handle_joystick); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 51FA void draw_keyname() { RETLOC(53B8); RETLOC(5399); RETLOC(5389); RETLOC(5379); RETLOC(5369); RETLOC(5359); RETLOC(5349); RETLOC(5338); RETLOC(5327); RETLOC(5316); RETLOC(5305); RETLOC(52F4); RETLOC(52E3); RETLOC(52D2); RETLOC(52C1); RETLOC(52B0); RETLOC(52A6); RETLOC(5293); RETLOC(527D); RETLOC(526C); RETLOC(525B); RETLOC(524A); RETLOC(5239); RETLOC(5228); RETLOC(5217); assert(reg_eip == 0x51fa); PUSH(bp); MOV(bp, sp); reg_sp -= 4; PUSH(si); reg_si = MEMW(reg_bp + 4); MOV(ax, si); reg_ax &= 0x7f; MOV(si, ax); // seg000:520B if (reg_ax == 1) { // seg000:5210 PUSHI(aEsc); EMU_CALL(a_draw_string, 5217, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:521C if (reg_si == 0xe) { // seg000:5221 PUSHI(aBksp); EMU_CALL(a_draw_string, 5228, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:522D if (reg_si == 0xf) { // seg000:5232 PUSHI(aTab); EMU_CALL(a_draw_string, 5239, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:523E if (reg_si == 0x1d) { // seg000:5243 PUSHI(aCtrl); EMU_CALL(a_draw_string, 524A, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:524F if (reg_si == 0x2a) { // seg000:5254 PUSHI(aLshift); EMU_CALL(a_draw_string, 525B, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:5260 if (reg_si == 0x2a) { // seg000:5265 PUSHI(aSpace); EMU_CALL(a_draw_string, 526C, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:5271 if (reg_si == 0x3a) { // seg000:5276 PUSHI(aCapslk); EMU_CALL(a_draw_string, 527D, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:5282 if (reg_si >= 0x3b && reg_si <= 0x44) { // seg000:528C PUSHI(aF); EMU_CALL(a_draw_string, 5293, draw_keyname); reg_sp += 2; // seg000:5295 PUSHI(0xa); reg_ax = reg_bp - 4; PUSH(ax); MOV(ax, si); reg_ax += 0xffc6; PUSH(ax); EMU_CALL(a__itoa, 52A6, draw_keyname); reg_sp += 6; // seg000:52A9 PUSHI(reg_bp - 4); EMU_CALL(a_draw_string, 52B0, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:52B5 if (reg_si == 0x57) { // seg000:52BA PUSHI(aF11); EMU_CALL(a_draw_string, 52C1, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:52C6 if (reg_si == 0x59) { // seg000:52CB PUSHI(aF12); EMU_CALL(a_draw_string, 52D2, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:52D7 if (reg_si == 0x46) { // seg000:52CB PUSHI(aScrllk); EMU_CALL(a_draw_string, 52E3, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:52E8 if (reg_si == 0x1c) { // seg000:52ED PUSHI(aEnter); EMU_CALL(a_draw_string, 52F4, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:52F9 if (reg_si == 0x36) { // seg000:52FE PUSHI(aRshift); EMU_CALL(a_draw_string, 5305, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:530A if (reg_si == 0x37) { // seg000:530F PUSHI(aPrtsc); EMU_CALL(a_draw_string, 5316, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:531B if (reg_si == 0x38) { // seg000:5320 PUSHI(aAlt); EMU_CALL(a_draw_string, 5327, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:532C if (reg_si == 0x47) { // seg000:5331 PUSHI(aHome); EMU_CALL(a_draw_string, 5338, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:533D if (reg_si == 0x49) { // seg000:5342 PUSHI(aPgup); EMU_CALL(a_draw_string, 5349, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:534D if (reg_si == 0x4f) { // seg000:5352 PUSHI(aEnd); EMU_CALL(a_draw_string, 5359, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:535D if (reg_si == 0x51) { // seg000:5362 PUSHI(aPgdn); EMU_CALL(a_draw_string, 5369, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:536D if (reg_si == 0x52) { // seg000:5372 PUSHI(aIns); EMU_CALL(a_draw_string, 5379, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:537D if (reg_si == 0x53) { // seg000:5382 PUSHI(aDel); EMU_CALL(a_draw_string, 5389, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:538D if (reg_si == 0x45) { // seg000:5392 PUSHI(aNumlk); EMU_CALL(a_draw_string, 5399, draw_keyname); reg_sp += 2; // from 53BB POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:539D reg_ax = (char)MEMB(char_map + reg_si); PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B2D2); W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 1); PUSH(ax); EMU_CALL(a_draw_char, 53B8, draw_keyname); reg_sp += 6; // seg000:53BB POP(si); MOV(sp, bp); POP(bp); RET; } // 53C0 void handle_redef_keys() { RETLOC(5582); RETLOC(5574); RETLOC(553B); RETLOC(5534); RETLOC(5505); RETLOC(5500); RETLOC(54ED); RETLOC(54B5); RETLOC(54A4); RETLOC(548E); RETLOC(5472); RETLOC(5449); RETLOC(5440); RETLOC(5437); RETLOC(542E); RETLOC(5425); RETLOC(541C); RETLOC(5413); RETLOC(540A); RETLOC(5401); RETLOC(53F8); RETLOC(53EF); RETLOC(53E6); RETLOC(53DD); RETLOC(53D3); RETLOC(552D); assert(reg_eip == 0x53c0); PUSH(bp); MOV(bp, sp); reg_sp -= 8; PUSH(si); PUSH(di); PUSHI(0xe); PUSHI(0x16); EMU_CALL(a_draw_box_opening2, 53D3, handle_redef_keys); reg_sp += 4; PUSHI(aKeyboardCommands); EMU_CALL(a_draw_string, 53DD, handle_redef_keys); reg_sp += 2; PUSHI(asc_156EB); EMU_CALL(a_draw_string, 53E6, handle_redef_keys); reg_sp += 2; PUSHI(a0North); EMU_CALL(a_draw_string, 53EF, handle_redef_keys); reg_sp += 2; PUSHI(a1Northeast); EMU_CALL(a_draw_string, 53F8, handle_redef_keys); reg_sp += 2; PUSHI(a2East); EMU_CALL(a_draw_string, 5401, handle_redef_keys); reg_sp += 2; PUSHI(a3Southeast); EMU_CALL(a_draw_string, 540A, handle_redef_keys); reg_sp += 2; PUSHI(a4South); EMU_CALL(a_draw_string, 5413, handle_redef_keys); reg_sp += 2; PUSHI(a5Southwest); EMU_CALL(a_draw_string, 541C, handle_redef_keys); reg_sp += 2; PUSHI(a6West); EMU_CALL(a_draw_string, 5425, handle_redef_keys); reg_sp += 2; PUSHI(a7Northwest); EMU_CALL(a_draw_string, 542E, handle_redef_keys); reg_sp += 2; PUSHI(a8Button1); EMU_CALL(a_draw_string, 5437, handle_redef_keys); reg_sp += 2; PUSHI(a9Button2); EMU_CALL(a_draw_string, 5440, handle_redef_keys); reg_sp += 2; PUSHI(aModifyWhichAction); EMU_CALL(a_draw_string, 5449, handle_redef_keys); reg_sp += 2; // seg000:544B reg_ax = MEMW(word_1B2D2); W_MEMW(reg_bp - 4, reg_ax); reg_ax = MEMW(word_1B348); W_MEMW(reg_bp - 6, reg_ax); reg_di = 0; // seg000:5475 while ((short)reg_di < 8) { // seg000:545B W_MEMW(word_1B2D2, 0x1a); MOV(ax, di); reg_ax += 7; W_MEMW(word_1B348, reg_ax); reg_ax = (char)MEMB(sc_up + reg_di); PUSH(ax); EMU_CALL(a_draw_keyname, 5472, handle_redef_keys); reg_sp += 2; reg_di++; } // seg000:547A W_MEMW(word_1B2D2, 0x1a); W_MEMW(word_1B348, 0xf); reg_ax = (char)MEMB(sc_ctrl); PUSH(ax); EMU_CALL(a_draw_keyname, 548E, handle_redef_keys); reg_sp += 2; // seg000:5490 W_MEMW(word_1B2D2, 0x1a); W_MEMW(word_1B348, 0x10); reg_ax = (char)MEMB(sc_alt); PUSH(ax); EMU_CALL(a_draw_keyname, 54A4, handle_redef_keys); reg_sp += 2; do { // seg000:54A6 reg_ax = MEMW(reg_bp - 4); W_MEMW(word_1B2D2, reg_ax); reg_ax = MEMW(reg_bp - 6); W_MEMW(word_1B348, reg_ax); EMU_CALL(a_read_char_with_echo, 54B5, handle_redef_keys); // seg000:54B5 int tmp1 = (short)reg_ax; tmp1 %= 0x100; reg_dl = tmp1 & 0xff; W_MEMB(reg_bp - 1, reg_dl); // seg000:54BE if ((char)reg_dl >= '0' && (char)reg_dl <= '9') { // seg000:54CE reg_ax = (char)MEMB(reg_bp - 1); reg_ax += 0xffd0; MOV(si, ax); reg_ax = (char)MEMB(reg_bp - 1); PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 54ED, handle_redef_keys); reg_sp += 6; // seg000:54F0 reg_ax = (char)MEMB(reg_bp - 1); reg_ax += 0xffd0; MOV(si, ax); PUSHI(aPressTheNewKey); EMU_CALL(a_draw_string, 5500, handle_redef_keys); reg_sp += 2; EMU_CALL(a_clear_keys, 5505, handle_redef_keys); W_MEMW(reg_bp - 8, 0xffff); while (1) { // seg000:5522 W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) + 1); reg_bx = MEMW(reg_bp - 8); reg_al = (char)MEMB(key_map + reg_bx); EMU_INSTR(552C, 552D, handle_redef_keys); // because we're looping until key_map changes // seg000:552D if (reg_ax != 0) break; // seg000:550C if (MEMW(reg_bp - 8) == 0x79) { // seg000:5512 W_MEMW(reg_bp - 8, 0xffff); } else if (MEMW(reg_bp - 8) == 0x29) { // seg000:551F W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) + 1); } } reg_eip = 0x5531; return; // seg000:5531 EMU_CALL(a_clear_keys, 5534, handle_redef_keys); PUSHI(asc_157B4); EMU_CALL(a_draw_string, 553B, handle_redef_keys); reg_sp += 2; // seg000:553D if ((short)reg_si < 8) { // seg000:5542 reg_al = MEMB(reg_bp - 8); W_MEMB(sc_up + reg_si, reg_al); } // seg000:5549 if (reg_si == 8) { // seg000:554E reg_al = MEMB(reg_bp - 8); W_MEMB(sc_ctrl, reg_al); } // seg000:5554 if (reg_si == 9) { // seg000:5559 reg_al = MEMB(reg_bp - 8); W_MEMB(sc_alt, reg_al); } // seg000:555F MOV(ax, si); reg_ax += 7; W_MEMW(word_1B348, reg_ax); W_MEMW(word_1B2D2, 0x1a); PUSHI(asc_157C8); EMU_CALL(a_draw_string, 5574, handle_redef_keys); reg_sp += 2; // seg000:5576 W_MEMW(word_1B2D2, 0x1a); PUSHI(MEMW(reg_bp - 8)); EMU_CALL(a_draw_keyname, 5582, handle_redef_keys); reg_sp += 2; W_MEMW(reg_bp - 1, 0x30); } // seg000:5588 } while (MEMB(reg_bp - 1) >= '0' && MEMB(reg_bp - 1) <= '9'); // seg000:5597 W_MEMW(ctrl_type, 0); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 55A3 void get_keyb_ctrl_state() { RETLOC(56BF); assert(reg_eip == 0x55a3); PUSH(bp); MOV(bp, sp); reg_sp -= 6; PUSH(si); PUSH(di); reg_di = 0; reg_si = 0; // seg000:55AF reg_bx = MEMB(sc_up); if (MEMB(key_map + reg_bx) != 0) { // seg000:55BC reg_si = 0xffff; } // seg000:55BF reg_bx = MEMB(sc_right); if (MEMB(key_map + reg_bx) != 0) { // seg000:55CC reg_di = 1; } // seg000:55CF reg_bx = MEMB(sc_down); if (MEMB(key_map + reg_bx) != 0) { // seg000:55DC reg_si = 1; } // seg000:55DF reg_bx = MEMB(sc_left); if (MEMB(key_map + reg_bx) != 0) { // seg000:55EC reg_di = 0xffff; } // seg000:55EF reg_bx = MEMB(sc_pgup); if (MEMB(key_map + reg_bx) != 0) { // seg000:55FC reg_si = 0xffff; reg_di = 1; } // seg000:5602 reg_bx = MEMB(sc_home); if (MEMB(key_map + reg_bx) != 0) { // seg000:560F reg_si = 0xffff; reg_di = 0xffff; } // seg000:5615 reg_bx = MEMB(sc_pgdn); if (MEMB(key_map + reg_bx) != 0) { // seg000:5622 reg_si = 1; reg_di = 1; } // seg000:5628 reg_bx = MEMB(sc_end); if (MEMB(key_map + reg_bx) != 0) { // seg000:5635 reg_si = 1; reg_di = 0xffff; } // seg000:563B MOV(ax, si); reg_ax *= 3; reg_ax += reg_di; reg_ax -= 0xfffc; MOV(bx, ax); // seg000:5649 if (reg_bx <= 8) { // seg000:564E switch(reg_bx) { case 0: // seg000:5655 W_MEMW(reg_bp - 6, 7); break; case 1: // seg000:565C W_MEMW(reg_bp - 6, 0); break; case 2: // seg000:5663 W_MEMW(reg_bp - 6, 1); break; case 3: // seg000:566A W_MEMW(reg_bp - 6, 6); break; case 4: // seg000:5671 W_MEMW(reg_bp - 6, 8); break; case 5: // seg000:5678 W_MEMW(reg_bp - 6, 2); break; case 6: // seg000:567F W_MEMW(reg_bp - 6, 5); break; case 7: // seg000:5686 W_MEMW(reg_bp - 6, 4); break; case 8: // seg000:568D W_MEMW(reg_bp - 6, 3); break; } } // seg000:5692 reg_bx = MEMB(sc_ctrl); reg_ax = MEMB(key_map + reg_bx); W_MEMW(reg_bp - 4, reg_ax); // seg000:56A0 reg_bx = MEMB(sc_alt); reg_ax = MEMB(key_map + reg_bx); W_MEMW(reg_bp - 2, reg_ax); // seg000:56AE PUSHI(MEMW(reg_bp + 6)); PUSHI(MEMW(reg_bp + 4)); PUSHI(SegValue(ss)); PUSHI(reg_bp - 6); reg_cx = 6; EMU_CALL(a_N_SCOPY, 56BF, get_keyb_ctrl_state); reg_ax = MEMW(reg_bp + 4); // seg000:56C2 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 56DB void get_mouse_ctrl() { printf("get_mouse_ctrl\n"); reg_eip = 0x56DB; return; } // 5811 void poll_joystick() { RETLOC(58A9); RETLOC(585F); RETLOC(5858); RETLOC(5854); RETLOC(584A); assert(reg_eip == 0x5811); PUSH(bp); MOV(bp, sp); reg_sp -= 0xa; PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 6); reg_si = MEMW(reg_bp + 8); // seg000:581F if (MEMW(reg_bp + 4) == 1) { // seg000:5825 W_MEMW(reg_bp - 8, 1); W_MEMW(reg_bp - 0xa, 2); } else { // seg000:5831 W_MEMW(reg_bp - 8, 4); W_MEMW(reg_bp - 0xa, 8); } // seg000:583B W_MEMW(reg_di, 0); W_MEMW(reg_si, 0); reg_ax = 0x201; PUSH(ax); EMU_CALL(a__inportb, 584A, poll_joystick); reg_sp += 2; // seg000:584C PUSH(ax); reg_ax = 0x201; PUSH(ax); EMU_CALL(a__outportb, 5854, poll_joystick); reg_sp += 4; // seg000:5857 EMU_INSTR(5857, 5858, poll_joystick); do { // seg000:5858 reg_ax = 0x201; PUSH(ax); EMU_CALL(a__inportb, 585F, poll_joystick); reg_sp += 2; reg_ah = 0; W_MEMW(reg_bp - 2, reg_ax); reg_ax = MEMW(reg_bp - 8); // seg000:5869 if (MEMW(reg_bp - 2) & reg_ax) { // seg000:586E reg_ax = 1; } else { // seg000:5873 reg_ax = 0; } // seg000:5875 W_MEMW(reg_bp - 4, reg_ax); reg_ax = MEMW(reg_bp - 0xa); // seg000:587B if (MEMW(reg_bp - 2) & reg_ax) { // seg000:5880 reg_ax = 1; } else { // seg000:5885 reg_ax = 0; } // seg000:5887 W_MEMW(reg_bp - 6, reg_ax); reg_ax = MEMW(reg_bp - 4); W_MEMW(reg_di, MEMW(reg_di) + reg_ax); reg_ax = MEMW(reg_bp - 4); reg_ax += MEMW(reg_bp - 6); // seg000:589A if (reg_ax == 0) break; // seg000:589C if ((short)MEMW(reg_di) >= 0x1f4) break; // seg000:58A2 } while ((short)MEMW(reg_si) < 0x1f4); // seg000:58A8 EMU_INSTR(58A8, 58A9, poll_joystick); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 58AF void get_joystick_ctrl() { RETLOC(5A1D); RETLOC(59C3); RETLOC(58DA); assert(reg_eip == 0x58AF); PUSH(bp); MOV(bp, sp); reg_sp -= 0xe; PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 8); W_MEMW(reg_bp - 2, 0); W_MEMW(reg_bp - 4, 0); W_MEMW(reg_bp - 6, 0); W_MEMW(reg_bp - 8, 0); reg_ax = reg_bp - 4; PUSH(ax); reg_ax = reg_bp - 2; PUSH(ax); PUSH(si); EMU_CALL(a_poll_joystick, 58DA, get_joystick_ctrl); reg_sp += 6; // seg000:58DD if ((short)MEMW(reg_bp - 2) > 0x1f4) { // seg000:58E4 reg_ax = 1; } else { // seg000:58E9 reg_ax = 0; } // seg000:58EB PUSH(ax); // seg000:58EC if ((short)MEMW(reg_bp - 4) > 0x1f4) { // seg000:58F3 reg_ax = 1; } else { // seg000:58F8 reg_ax = 0; } // seg000:58FA POP(dx); if (reg_dx != reg_ax) { // seg000:58FF MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1B2BA + reg_bx); reg_ax++; W_MEMW(reg_bp - 2, reg_ax); // seg000:590B MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1B2C6 + reg_bx); reg_ax++; W_MEMW(reg_bp - 4, reg_ax); } // seg000:5917 MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1B2C0 + reg_bx); // seg000:591F if ((short)reg_ax < (short)MEMW(reg_bp - 2)) { // seg000:5924 W_MEMW(reg_bp - 6, 1); } else { // seg000:592B MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1B2BA + reg_bx); // seg000:5933 if ((short)reg_ax > (short)MEMW(reg_bp - 2)) { // seg000:5938 W_MEMW(reg_bp - 6, 0xffff); } } // seg000:593D MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1B2CC + reg_bx); // seg000:5945 if ((short)reg_ax < (short)MEMW(reg_bp - 4)) { // seg000:594A W_MEMW(reg_bp - 8, 1); } else { // seg000:5951 MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1B2C6 + reg_bx); // seg000:5959 if ((short)reg_ax > (short)MEMW(reg_bp - 4)) { // seg000:595E W_MEMW(reg_bp - 8, 0xffff); } } // seg000:5963 reg_ax = MEMW(reg_bp - 8); reg_ax *= 3; reg_ax += MEMW(reg_bp - 6); reg_ax -= 0xfffc; MOV(bx, ax); // seg000:5973 if (reg_bx <= 8) { // seg000:5978 switch(reg_bx) { case 0: // seg000:597F W_MEMW(reg_bp - 0xe, 7); break; case 1: // seg000:5986 W_MEMW(reg_bp - 0xe, 0); break; case 2: // seg000:598D W_MEMW(reg_bp - 0xe, 1); break; case 3: // seg000:5994 W_MEMW(reg_bp - 0xe, 6); break; case 4: // seg000:599B W_MEMW(reg_bp - 0xe, 8); break; case 5: // seg000:59A2 W_MEMW(reg_bp - 0xe, 2); break; case 6: // seg000:59A9 W_MEMW(reg_bp - 0xe, 5); break; case 7: // seg000:59B0 W_MEMW(reg_bp - 0xe, 4); break; case 8: // seg000:59B7 W_MEMW(reg_bp - 0xe, 3); break; } } // seg000:59BC PUSHI(0x201); EMU_CALL(a__inportb, 59C3, get_joystick_ctrl); reg_sp += 2; // seg000:59C5 reg_ah = 0; MOV(di, ax); // seg000:59C9 if (reg_si == 1) { // seg000:59CE if (reg_ax & 0x10) { // seg000:59D8 reg_ax = 0; } else { // seg000:59D3 reg_ax = 1; } // seg000:59DA W_MEMW(reg_bp - 0xc, reg_ax); // seg000:59DD if (reg_di & 0x20) { // seg000:59E8 // seg000:5A07 reg_ax = 0; } else { // seg000:59E3 reg_ax = 1; } } else { // seg000:59EC if (reg_di & 0x40) { // seg000:59F7 reg_ax = 0; } else { reg_ax = 1; } // seg000:59F9 W_MEMW(reg_bp - 0xc, reg_ax); // seg000:59FC if (reg_di & 0x80) { // seg000:5A07 reg_ax = 0; } else { // seg000:5A02 reg_ax = 1; } } // seg000:5A09 W_MEMW(reg_bp - 0xa, reg_ax); PUSHI(MEMW(reg_bp + 6)); PUSHI(MEMW(reg_bp + 4)); reg_ax = reg_bp - 0xe; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 5A1D, get_joystick_ctrl); // seg000:5A1D reg_ax = MEMW(reg_bp + 4); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 5A39 void handle_ctrl() { RETLOC(5B2E); RETLOC(5AC7); RETLOC(5AB9); RETLOC(5AA0); RETLOC(5A87); RETLOC(5A72); assert(reg_eip == 0x5a39); PUSH(bp); MOV(bp, sp); reg_sp -= 0x20; // seg000:5A3F if (MEMW(word_1C782) == 0 || MEMW(word_1C782) == 2) { // seg000:5A50 reg_bx = MEMW(reg_bp + 8); reg_bx <<= 1; reg_bx = MEMW(word_1B38C + reg_bx); // hmm if (reg_bx <= 3) { // seg000:5A5E switch(reg_bx) { case 0: // seg000:5A65 reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0xe; PUSH(ax); EMU_CALL(a_get_keyb_ctrl_state, 5A72, handle_ctrl); reg_sp += 4; // seg000:5A75 reg_ax = reg_bp - 0xe; break; case 1: // seg000:5A7A reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x14; EMU_CALL(a_get_mouse_ctrl, 5A87, handle_ctrl); reg_sp += 4; // seg000:5A8A reg_ax = reg_bp - 0x14; break; case 2: // seg000:5A8F reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); reg_ax = 1; PUSH(ax); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x1a; PUSH(ax); EMU_CALL(a_get_joystick_ctrl, 5AA0, handle_ctrl); reg_sp += 6; // seg000:5AA3 reg_ax = reg_bp - 0x1a; break; case 3: // seg000:5AA8 reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); reg_ax = 2; PUSH(ax); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x20; PUSH(ax); EMU_CALL(a_get_joystick_ctrl, 5AB9, handle_ctrl); reg_sp += 6; // seg000:5ABC reg_ax = reg_bp - 0x20; break; } // seg000:5ABF PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 5AC7, handle_ctrl); } // seg000:5AC7 if (MEMW(word_1C782) == 2) { // seg000:5ACE reg_ax = MEMW(reg_bp - 6); reg_ax <<= 2; reg_dx = MEMW(reg_bp - 2); reg_dx <<= 1; reg_ax |= reg_dx; reg_ax |= MEMW(reg_bp - 4); W_MEMW(reg_bp - 8, reg_ax); // seg000:5AE2 reg_bx = MEMW(word_1B3B2); reg_al = MEMB(reg_bp - 8); W_MEMB(reg_bx, reg_al); // seg000:5AEB W_MEMW(word_1B3B2, MEMW(word_1B3B2) + 1); } } else { // seg000:5AF1 reg_bx = MEMW(word_1B3B2); reg_ax = MEMB(reg_bx); W_MEMW(reg_bp - 8, reg_ax); W_MEMW(word_1B3B2, MEMW(word_1B3B2) + 1); reg_ax &= 1; W_MEMW(reg_bp - 4, reg_ax); // seg000:5B05 reg_ax = MEMW(reg_bp - 8); reg_ax &= 2; reg_ax = (short)reg_ax >> 1; W_MEMW(reg_bp - 2, reg_ax); // seg000:5B10 reg_ax = MEMW(reg_bp - 8); reg_ax &= 0x3c; reg_ax = (short)reg_ax >> 2; W_MEMW(reg_bp - 6, reg_ax); } // seg000:5B1D PUSHI(MEMW(reg_bp + 6)); PUSHI(MEMW(reg_bp + 4)); reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 5B2E, handle_ctrl); reg_ax = MEMW(reg_bp + 4); // seg000:5B31 MOV(sp, bp); POP(bp); RET; } // 5CB8 void map_file_to_mem() { RETLOC(5D54); RETLOC(5D41); RETLOC(5D21); RETLOC(5D0E); RETLOC(5CF6); RETLOC(5CE6); assert(reg_eip == 0x5cb8); PUSH(bp); MOV(bp, sp); reg_sp -= 0xe; W_MEMD(reg_bp - 6, 0); reg_ax = MEMW(reg_bp + 6); W_MEMW(reg_bp - 8, reg_ax); reg_ax = MEMW(reg_bp + 8); W_MEMW(reg_bp - 0xa, reg_ax); W_MEMW(reg_bp - 0xc, 0); W_MEMW(reg_bp - 0xe, 0); // seg000:5CDE reg_dx = MEMW(reg_bp + 4); reg_ax = 0x3d00; EMU_INSTR(5CE4, 5CE6, map_file_to_mem); // seg000:5CE6 if ((cpu_regs.flags & FLAG_CF) == 0) { // seg000:5CE8 W_MEMW(reg_bp - 2, reg_ax); MOV(bx, ax); reg_cx = 0; reg_dx = 0; reg_ax = 0x4202; EMU_INSTR(5CF4, 5CF6, map_file_to_mem); // seg000:5CF6 if ((cpu_regs.flags & FLAG_CF) == 0) { // seg000:5CF8 W_MEMW(reg_bp - 6, reg_ax); W_MEMW(reg_bp - 4, reg_dx); reg_cx = MEMW(reg_bp - 4); reg_cx++; do { // seg000:5D02 PUSH(cx); reg_cx = MEMW(reg_bp - 0xe); reg_dx = MEMW(reg_bp - 0xc); reg_ax = 0x4200; EMU_INSTR(5D0C, 5D0E, map_file_to_mem); // seg000:5D0E PUSHI(SegValue(ds)); reg_bx = MEMW(reg_bp - 2); reg_cx = 0xffff; reg_dx = MEMW(reg_bp - 8); reg_ax = MEMW(reg_bp - 0xa); SegSet16(ds, reg_ax); reg_ah = 0x3f; EMU_INSTR(5D1F, 5D21, map_file_to_mem); // seg000:5D21 POP(cx); SegSet16(ds, reg_cx); POP(cx); // seg000:5D23 if ((cpu_regs.flags & FLAG_CF) != 0 || reg_ax != 0xffff) break; // goto seg000:5D4D // seg000:5D2A PUSH(cx); PUSHI(SegValue(ds)); reg_bx = MEMW(reg_bp - 2); reg_cx = 1; reg_dx = MEMW(reg_bp - 8); reg_dx += 0xffff; reg_ax = MEMW(reg_bp - 0xa); SegSet16(ds, reg_ax); reg_ah = 0x3f; EMU_INSTR(5D3F, 5D41, map_file_to_mem); // seg000:5D41 POP(cx); SegSet16(ds, reg_cx); POP(cx); W_MEMW(reg_bp - 0xa, MEMW(reg_bp - 0xa) + 0x1000); W_MEMW(reg_bp - 0xe, MEMW(reg_bp - 0xe) + 1); reg_cx--; } while (reg_cx != 0); } } // seg000:5D4D reg_bx = MEMW(reg_bp - 2); reg_ah = 0x3e; EMU_INSTR(5D52, 5D54, map_file_to_mem); // seg000:5D54 reg_dx = MEMW(reg_bp - 6); reg_ax = MEMW(reg_bp - 4); MOV(sp, bp); POP(bp); RET; } // 5D63 void write_file() { RETLOC(5DE0); RETLOC(5DD6); RETLOC(5DA7); RETLOC(5D89); assert(reg_eip == 0x5D63); PUSH(bp); MOV(bp, sp); reg_sp -= 0xa; reg_ax = MEMW(reg_bp + 6); W_MEMW(reg_bp - 4, reg_ax); reg_ax = MEMW(reg_bp + 8); W_MEMW(reg_bp - 6, reg_ax); W_MEMW(reg_bp - 8, 0); W_MEMW(reg_bp - 0xa, 0); reg_dx = MEMW(reg_bp + 4); reg_ax = 0x3c00; reg_cx = 0; EMU_INSTR(5D87, 5D89, write_file); // seg000:5D89 if ((reg_flags & FLAG_CF) == 0) { // seg000:5D8B W_MEMW(reg_bp - 2, reg_ax); // eg000:5D8E if (MEMW(reg_bp + 12) != 0) { do { // seg000:5D94 PUSHI(SegValue(ds)); reg_bx = MEMW(reg_bp - 2); reg_cx = 0x8000; reg_dx = MEMW(reg_bp - 4); reg_ax = MEMW(reg_bp - 6); SegSet16(ds, reg_ax); reg_ah = 0x40; EMU_INSTR(5DA5, 5DA7, write_file); POP(ax); SegSet16(ds, reg_ax); W_MEMW(reg_bp - 6, MEMW(reg_bp - 6) + 0x800); W_MEMD(reg_bp + 10, MEMD(reg_bp + 10) - 0x8000); // seg000:5DB6 } while (MEMD(reg_bp + 10) > 0x8000); } // seg000:5DC3 PUSHI(SegValue(ds)); reg_bx = MEMW(reg_bp - 2); reg_cx = MEMW(reg_bp + 10); reg_dx = MEMW(reg_bp - 4); reg_ax = MEMW(reg_bp - 6); SegSet16(ds, reg_ax); reg_ah = 0x40; EMU_INSTR(5DD4, 5DD6, write_file); POP(ax); SegSet16(ds, reg_ax); } // seg000:5DD9 reg_bx = MEMW(reg_bp - 2); reg_ah = 0x3e; EMU_INSTR(5DDE, 5DE0, write_file); MOV(sp, bp); POP(bp); RET; } // 5DE4 void alloc_and_map_file() { RETLOC(5E2D); RETLOC(5E1F); RETLOC(5E12); RETLOC(5E03); RETLOC(5DF5); assert(reg_eip == 0x5de4); PUSH(bp); MOV(bp, sp); reg_sp -= 8; PUSH(si); PUSHI(0x8000); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a__open, 5DF5, alloc_and_map_file); reg_sp += 4; MOV(si, ax); // seg000:5DFA if (reg_ax == 0xffff) { reg_dx = 0; reg_ax = 0; POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:5DFF PUSH(ax); EMU_CALL(a__filelength, 5E03, alloc_and_map_file); reg_sp += 2; W_MEMW(reg_bp - 4, reg_ax); W_MEMW(reg_bp - 2, reg_dx); PUSH(dx); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_sub_5C58, 5E12, alloc_and_map_file); reg_sp += 4; W_MEMW(reg_bp - 8, reg_ax); W_MEMW(reg_bp - 6, reg_dx); // seg000:5E1B PUSH(si); EMU_CALL(a__close, 5E1F, alloc_and_map_file); reg_sp += 2; // seg000:5E21 PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_map_file_to_mem, 5E2D, alloc_and_map_file); reg_sp += 6; reg_dx = MEMW(reg_bp - 6); reg_ax = MEMW(reg_bp - 8); POP(si); MOV(sp, bp); POP(bp); RET; } // 5F1E void draw_box2() { RETLOC(6036); RETLOC(6019); RETLOC(5FFC); RETLOC(5FDF); RETLOC(5FC3); RETLOC(5FA7); RETLOC(5F89); RETLOC(5F6C); RETLOC(5F4F); assert(reg_eip == 0x5f1e); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_ax = MEMW(reg_bp + 4); W_MEMW(word_1B3A8, reg_ax); reg_ax = MEMW(reg_bp + 6); W_MEMW(word_1B3AE, reg_ax); reg_ax = MEMW(reg_bp + 8); W_MEMW(word_1B3AA, reg_ax); reg_ax = MEMW(reg_bp + 10); W_MEMW(word_1B3B0, reg_ax); PUSHI(1); reg_ax = MEMW(reg_bp + 6); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_draw_char, 5F4F, draw_box2); reg_sp += 6; reg_ax = MEMW(reg_bp + 4); reg_ax++; MOV(si, ax); // seg000:5F70 while ((short)reg_si < (short)MEMW(reg_bp + 8)) { // seg000:5F5A PUSHI(2); reg_ax = MEMW(reg_bp + 6); reg_ax <<= 3; PUSH(ax); PUSH(si); EMU_CALL(a_draw_char, 5F6C, draw_box2); reg_sp += 6; reg_si++; } // seg000:5F75 PUSHI(3); reg_ax = MEMW(reg_bp + 6); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(reg_bp + 8)); EMU_CALL(a_draw_char, 5F89, draw_box2); reg_sp += 6; reg_ax = MEMW(reg_bp + 6); reg_ax++; MOV(di, ax); // seg000:5FE3 while ((short)reg_di < (short)MEMW(reg_bp + 10)) { // seg000:5F94 PUSHI(4); MOV(ax, di); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_draw_char, 5FA7, draw_box2); reg_sp += 6; reg_ax = MEMW(reg_bp + 4); reg_ax++; MOV(si, ax); // seg000:5FC7 while ((short)reg_si < (short)MEMW(reg_bp + 8)) { // seg000:5FB2 PUSHI(0x20); MOV(ax, di); reg_ax <<= 3; PUSH(ax); PUSH(si); EMU_CALL(a_draw_char, 5FC3, draw_box2); reg_sp += 6; reg_si++; } // seg000:5FCC PUSHI(5); MOV(ax, di); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(reg_bp + 8)); EMU_CALL(a_draw_char, 5FDF, draw_box2); reg_sp += 6; reg_di++; } // seg000:5FE8 PUSHI(6); reg_ax = MEMW(reg_bp + 10); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_draw_char, 5FFC, draw_box2); reg_sp += 6; reg_ax = MEMW(reg_bp + 4); reg_ax++; MOV(si, ax); // seg000:601D while ((short)reg_si < (short)MEMW(reg_bp + 8)) { // seg000:6007 PUSHI(7); reg_ax = MEMW(reg_bp + 10); reg_ax <<= 3; PUSH(ax); PUSH(si); EMU_CALL(a_draw_char, 6019, draw_box2); reg_sp += 6; reg_si++; } // seg000:6022 PUSHI(8); reg_ax = MEMW(reg_bp + 10); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(reg_bp + 8)); EMU_CALL(a_draw_char, 6036, draw_box2); reg_sp += 6; // seg000:6039 reg_ax = MEMW(reg_bp + 4); reg_ax++; W_MEMW(word_1B3A4, reg_ax); W_MEMW(word_1B2D2, reg_ax); reg_ax = MEMW(reg_bp + 6); reg_ax++; W_MEMW(word_1B348, reg_ax); POP(di); POP(si); POP(bp); RET; } // 604E void draw_box() { RETLOC(6085); assert(reg_eip == 0x604e); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_ax = MEMW(reg_bp + 4); reg_bx = 2; int tmp1 = (short)reg_ax; tmp1 /= reg_bx; reg_dx = MEMW(word_1551E); reg_dx -= tmp1 & 0xffff; MOV(di, dx); reg_ax = MEMW(reg_bp + 6); tmp1 = (short)reg_ax; tmp1 /= reg_bx; reg_dx = MEMW(word_15520); reg_dx -= tmp1 & 0xffff; MOV(si, dx); MOV(ax, si); reg_ax += MEMW(reg_bp + 6); reg_ax++; PUSH(ax); MOV(ax, di); reg_ax += MEMW(reg_bp + 4); reg_ax++; PUSH(ax); PUSH(dx); PUSH(di); EMU_CALL(a_draw_box2, 6085, draw_box); reg_sp += 8; POP(di); POP(si); POP(bp); RET; } // 6268 void read_char_with_echo() { RETLOC(62CC); RETLOC(62C3); RETLOC(6291); RETLOC(6287); RETLOC(629A); assert(reg_eip == 0x6268); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); do { // seg000:626D reg_si = 9; while (1) { // seg000:6293 PUSHI(1); EMU_CALL(a_translate_key, 629A, read_char_with_echo); reg_sp += 2; reg_ax &= 0xff; MOV(di, ax); // seg000:62A1 if (reg_ax != 0) break; // seg000:62A5 if ((short)reg_si >= 0xd) break; // seg000:6272 MOV(ax, si); reg_si++; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 6287, read_char_with_echo); reg_sp += 6; PUSHI(5); EMU_CALL(a_delay, 6291, read_char_with_echo); reg_sp += 2; } // seg000:62AA } while (reg_di == 0); // seg000:62AE PUSHI(0x20); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 62C3, read_char_with_echo); reg_sp += 6; // seg000:62C6 PUSHI(0); EMU_CALL(a_translate_key, 62CC, read_char_with_echo); reg_sp += 2; POP(di); POP(si); POP(bp); RET; } // 62D2 void draw_string() { RETLOC(6314); assert(reg_eip == 0x62d2); PUSH(bp); MOV(bp, sp); reg_sp -= 2; while (1) { // seg000:6317 reg_bx = MEMW(reg_bp + 4); W_MEMW(reg_bp + 4, MEMW(reg_bp + 4) + 1); reg_al = MEMB(reg_bx); W_MEMB(reg_bp - 1, reg_al); // seg000:6322 if (reg_al == 0) break; // seg000:62D9 if (MEMB(reg_bp - 1) == 0xa) { W_MEMW(word_1B348, MEMW(word_1B348) + 1); reg_ax = MEMW(word_1B3A4); W_MEMW(word_1B2D2, reg_ax); continue; } // seg000:62EB if (MEMB(reg_bp - 1) == 0xd) { // seg000:62F1 reg_ax = MEMW(word_1B3A4); W_MEMW(word_1B2D2, reg_ax); continue; } // seg000:62F9 reg_al = MEMB(reg_bp - 1); reg_ah = 0; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B2D2); W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 1); PUSH(ax); EMU_CALL(a_draw_char, 6314, draw_string); reg_sp += 6; } // seg000:6326 MOV(sp, bp); POP(bp); RET; } // 632A void draw_number() { RETLOC(6345); RETLOC(633B); assert(reg_eip == 0x632a); PUSH(bp); MOV(bp, sp); PUSHI(0xa); PUSHI(unk_1B2E0); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a__itoa, 633B, draw_number); reg_sp += 6; PUSHI(unk_1B2E0); EMU_CALL(a_draw_string, 6345, draw_number); reg_sp += 2; POP(bp); RET; } // 636B void get_file_length() { RETLOC(639C); RETLOC(6390); RETLOC(637C); assert(reg_eip == 0x636b); PUSH(bp); MOV(bp, sp); reg_sp -= 4; PUSH(si); PUSHI(0x8000); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a__open, 637C, get_file_length); reg_sp += 4; MOV(si, ax); // seg000:6381 if (reg_ax == 0xffff) { reg_dx = 0; reg_ax = 0; POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:638C PUSH(si); EMU_CALL(a__filelength, 6390, get_file_length); reg_sp += 2; W_MEMW(reg_bp - 4, reg_ax); W_MEMW(reg_bp - 2, reg_dx); PUSH(si); EMU_CALL(a__close, 639C, get_file_length); reg_sp += 2; reg_dx = MEMW(reg_bp - 2); reg_ax = MEMW(reg_bp - 4); POP(si); MOV(sp, bp); POP(bp); RET; } // 6476 void draw_stringz() { RETLOC(6494); RETLOC(647F); assert(reg_eip == 0x6476); PUSH(bp); MOV(bp, sp); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a__strlen, 647F, draw_stringz); reg_sp += 2; reg_ax >>= 1; reg_dx = MEMW(word_1551E); reg_dx++; reg_dx -= reg_ax; W_MEMW(word_1B2D2, reg_dx); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_draw_string, 6494, draw_stringz); reg_sp += 2; POP(bp); RET; } // 65B7 void get_string_input() { RETLOC(6629); RETLOC(65F1); RETLOC(65CA); RETLOC(65C3); assert(reg_eip == 0x65B7); PUSH(bp); MOV(bp, sp); reg_sp -= 2; PUSH(si); PUSH(di); reg_si = 0; do { // seg000:65C0 EMU_CALL(a_read_char_with_echo, 65C3, get_string_input); reg_ax &= 0xff; PUSH(ax); EMU_CALL(a_sub_CD36, 65CA, get_string_input); reg_sp += 2; W_MEMB(reg_bp - 1, reg_al); //seg000:65CF if (reg_al == 0x7f || reg_al == 8) { // seg000:65D7 if ((short)reg_si > 0) { // seg000:65DB reg_si--; PUSHI(0x20); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 65F1, get_string_input); reg_sp += 6; W_MEMW(word_1B2D2, MEMW(word_1B2D2) - 1); } } // seg000:65F8 if ((char)MEMB(reg_bp - 1) >= ' ' && (char)MEMB(reg_bp - 1) <= 'z' && (short)reg_si < (short)MEMW(reg_bp + 6)) { // seg000:6609 reg_bx = MEMW(reg_bp + 4); reg_al = MEMB(reg_bp - 1); W_MEMB(reg_bx + reg_si, reg_al); reg_si++; PUSHI((char)reg_al); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B2D2); W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 1); PUSH(ax); EMU_CALL(a_draw_char, 6629, get_string_input); reg_sp += 6; } // seg000:662C } while (MEMB(reg_bp - 1) != 0x1b && MEMB(reg_bp - 1) != 0xd); // seg000:663A MOV(di, si); // seg000:6645 while ((short)reg_di < (short)MEMW(reg_bp + 6)) { // seg000:663E reg_bx = MEMW(reg_bp + 4); W_MEMB(reg_bx + reg_di, 0); reg_di++; } // seg000:664A if (MEMB(reg_bp - 1) == 0xd) { // seg000:6650 reg_ax = 1; } else { // seg000:6655 reg_ax = 0; } // seg000:6657 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 665D void init_ctrls() { RETLOC(67A4); RETLOC(679D); RETLOC(678E); RETLOC(677F); RETLOC(6770); RETLOC(6761); RETLOC(6752); RETLOC(6743); RETLOC(6734); RETLOC(6725); RETLOC(6716); RETLOC(668C); RETLOC(667A); RETLOC(666C); assert(reg_eip == 0x665D); PUSH(bp); MOV(bp, sp); PUSH(si); reg_ax = aCtlpanel_; PUSH(ax); reg_ax = unk_1B2E0; PUSH(ax); EMU_CALL(a__strcpy, 666C, init_ctrls); reg_sp += 4; PUSHI(MEMW(pExt)); reg_ax = unk_1B2E0; PUSH(ax); EMU_CALL(a__strcat, 667A, init_ctrls); reg_sp += 4; // seg000:667D reg_ax = 0x180; PUSH(ax); reg_ax = 0x8001; PUSH(ax); reg_ax = unk_1B2E0; PUSH(ax); EMU_CALL(a__open, 668C, init_ctrls); reg_sp += 6; MOV(si, ax); // seg000:6691 if (reg_ax == 0xffff) { // seg000:6699 W_MEMW(want_sound, 1); W_MEMW(ctrl_type, 0); W_MEMW(word_1B390, 2); reg_ax = 0x14; W_MEMW(word_1B2BE, reg_ax); W_MEMW(word_1B2BC, reg_ax); reg_ax = 0x3c; W_MEMW(word_1B2C4, reg_ax); W_MEMW(word_1B2C2, reg_ax); reg_ax = 0x14; W_MEMW(word_1B2CA, reg_ax); W_MEMW(word_1B2C8, reg_ax); reg_ax = 0x3c; W_MEMW(word_1B2D0, reg_ax); W_MEMW(word_1B2CE, reg_ax); W_MEMW(word_1B3BC, 5); W_MEMB(sc_up, 0x48); W_MEMB(sc_pgup, 0x49); W_MEMB(sc_right, 0x4d); W_MEMB(sc_pgdn, 0x51); W_MEMB(sc_down, 0x50); W_MEMB(sc_end, 0x4F); W_MEMB(sc_left, 0x4b); W_MEMB(sc_home, 0x47); W_MEMB(sc_ctrl, 0x1d); W_MEMB(sc_alt, 0x38); } else { // seg000:670A PUSHI(2); reg_ax = want_sound; PUSH(ax); PUSH(si); EMU_CALL(a__read, 6716, init_ctrls); reg_sp += 6; // seg000:6719 PUSHI(6); reg_ax = word_1B38C; PUSH(ax); PUSH(si); EMU_CALL(a__read, 6725, init_ctrls); reg_sp += 6; // seg000:6728 PUSHI(6); reg_ax = word_1B2BA; PUSH(ax); PUSH(si); EMU_CALL(a__read, 6734, init_ctrls); reg_sp += 6; // seg000:6737 PUSHI(6); reg_ax = word_1B2C6; PUSH(ax); PUSH(si); EMU_CALL(a__read, 6743, init_ctrls); reg_sp += 6; // seg000:6746 PUSHI(6); reg_ax = word_1B2C0; PUSH(ax); PUSH(si); EMU_CALL(a__read, 6752, init_ctrls); reg_sp += 6; // seg000:6755 PUSHI(6); reg_ax = word_1B2CC; PUSH(ax); PUSH(si); EMU_CALL(a__read, 6761, init_ctrls); reg_sp += 6; // seg000:6764 PUSHI(2); reg_ax = word_1B3BC; PUSH(ax); PUSH(si); EMU_CALL(a__read, 6770, init_ctrls); reg_sp += 6; // seg000:6773 PUSHI(8); reg_ax = sc_up; PUSH(ax); PUSH(si); EMU_CALL(a__read, 677F, init_ctrls); reg_sp += 6; // seg000:6782 PUSHI(1); reg_ax = sc_ctrl; PUSH(ax); PUSH(si); EMU_CALL(a__read, 678E, init_ctrls); reg_sp += 6; // seg000:6791 PUSHI(1); reg_ax = sc_alt; PUSH(ax); PUSH(si); EMU_CALL(a__read, 679D, init_ctrls); reg_sp += 6; // seg000:67A0 PUSH(si); EMU_CALL(a__close, 67A4, init_ctrls); reg_sp += 2; } // seg000:67A6 POP(si); POP(bp); RET; } // 67A9 void save_ctrls() { RETLOC(687F); RETLOC(6878); RETLOC(6869); RETLOC(685A); RETLOC(684B); RETLOC(683C); RETLOC(682D); RETLOC(681E); RETLOC(680F); RETLOC(6800); RETLOC(67F1); RETLOC(67D8); RETLOC(67C6); RETLOC(67B8); assert(reg_eip == 0x67A9); PUSH(bp); MOV(bp, sp); PUSH(si); PUSHI(aCtlpanel__0); PUSHI(unk_1B2E0); EMU_CALL(a__strcpy, 67B8, save_ctrls); reg_sp += 4; PUSHI(MEMW(pExt)); PUSHI(unk_1B2E0); EMU_CALL(a__strcat, 67C6, save_ctrls); reg_sp += 4; // seg000:67C9 PUSHI(0x180); PUSHI(0x8302); PUSHI(unk_1B2E0); EMU_CALL(a__open, 67D8, save_ctrls); reg_sp += 6; MOV(si, ax); // seg000:67DD if (reg_ax != 0xffff) { // seg000:67E5 PUSHI(2); PUSHI(want_sound); PUSH(si); EMU_CALL(a_sub_CD62, 67F1, save_ctrls); reg_sp += 6; // seg000:67F4 PUSHI(6); PUSHI(word_1B38C); PUSH(si); EMU_CALL(a_sub_CD62, 6800, save_ctrls); reg_sp += 6; // seg000:6803 PUSHI(6); PUSHI(word_1B2BA); PUSH(si); EMU_CALL(a_sub_CD62, 680F, save_ctrls); reg_sp += 6; // seg000:6812 PUSHI(6); PUSHI(word_1B2C6); PUSH(si); EMU_CALL(a_sub_CD62, 681E, save_ctrls); reg_sp += 6; // seg000:6821 PUSHI(6); PUSHI(word_1B2C0); PUSH(si); EMU_CALL(a_sub_CD62, 682D, save_ctrls); reg_sp += 6; // seg000:6830 PUSHI(6); PUSHI(word_1B2CC); PUSH(si); EMU_CALL(a_sub_CD62, 683C, save_ctrls); reg_sp += 6; // seg000:683F PUSHI(2); PUSHI(word_1B3BC); PUSH(si); EMU_CALL(a_sub_CD62, 684B, save_ctrls); reg_sp += 6; // seg000:684E PUSHI(8); PUSHI(sc_up); PUSH(si); EMU_CALL(a_sub_CD62, 685A, save_ctrls); reg_sp += 6; // seg000:685D PUSHI(1); PUSHI(sc_ctrl); PUSH(si); EMU_CALL(a_sub_CD62, 6869, save_ctrls); reg_sp += 6; // seg000:686C PUSHI(1); PUSHI(sc_alt); PUSH(si); EMU_CALL(a_sub_CD62, 6878, save_ctrls); reg_sp += 6; // seg000:687B PUSH(si); EMU_CALL(a__close, 687F, save_ctrls); reg_sp += 2; } // seg000:6881 POP(si); POP(bp); RET; } // 6884 void decomp_file() { RETLOC(6A21); RETLOC(6A15); RETLOC(6A07); RETLOC(69FC); RETLOC(69E5); RETLOC(69C8); RETLOC(69BC); RETLOC(699F); RETLOC(694A); RETLOC(693C); RETLOC(6915); RETLOC(690A); RETLOC(68FE); RETLOC(68F5); RETLOC(68DD); RETLOC(68D2); RETLOC(68CB); RETLOC(68BC); RETLOC(68AB); assert(reg_eip == 0x6884); PUSH(bp); MOV(bp, sp); reg_sp -= 0x10; PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 4); W_MEMW(reg_bp - 4, 0); W_MEMW(reg_bp - 2, 0); W_MEMD(reg_bp - 8, 0); reg_ax = 0x8000; PUSH(ax); PUSH(di); EMU_CALL(a__open, 68AB, decomp_file); reg_sp += 4; MOV(si, ax); PUSHI(4); PUSHI(reg_bp - 4); PUSH(si); EMU_CALL(a__read, 68BC, decomp_file); reg_sp += 6; PUSHI(2); PUSHI(word_1B376); PUSH(si); EMU_CALL(a__read, 68CB, decomp_file); reg_sp += 6; PUSH(si); EMU_CALL(a__close, 68D2, decomp_file); reg_sp += 2; PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_sub_5C58, 68DD, decomp_file); reg_sp += 4; W_MEMW(dword_1B378, reg_ax); W_MEMW(dword_1B378 + 2, reg_dx); W_MEMW(reg_bp - 0xc, reg_ax); W_MEMW(reg_bp - 0xa, reg_dx); PUSHI(0x8000); PUSH(di); EMU_CALL(a__open, 68F5, decomp_file); reg_sp += 4; MOV(si, ax); PUSH(ax); EMU_CALL(a__filelength, 68FE, decomp_file); reg_sp += 2; W_MEMW(reg_bp - 8, reg_ax); W_MEMW(reg_bp - 6, reg_dx); PUSH(si); EMU_CALL(a__close, 690A, decomp_file); reg_sp += 2; // seg000:690C PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); EMU_CALL(a_alloc_mem, 6915, decomp_file); reg_sp += 4; W_MEMW(dword_1B2AA, reg_ax); W_MEMW(dword_1B2AA + 2, reg_dx); W_MEMW(reg_bp - 0x10, reg_ax); W_MEMW(reg_bp - 0xe, reg_dx); // seg000:6925 if (MEMD(dword_1B2AA) == 0) { // seg000:6935 PUSHI(aOutOfMemoryTryUn_0); EMU_CALL(a_chg_vid_and_error, 693C, decomp_file); reg_sp += 2; } // seg000:693E PUSHI(MEMW(dword_1B2AA + 2)); PUSHI(MEMW(dword_1B2AA)); PUSH(di); EMU_CALL(a_map_file_to_mem, 694A, decomp_file); reg_sp += 6; // seg000:694D reg_ax = MEMW(word_1B376); reg_ax += 0xfff8; W_MEMW(word_1B3AC, reg_ax); reg_ax = MEMW(word_1B376); // seg000:6959 if (reg_ax == 0xc) { // seg000:697A W_MEMW(word_1B3A6, 0x139D); } else if (reg_ax == 0xd) { // seg000:6972 W_MEMW(word_1B3A6, 0x2345); } else if (reg_ax == 0xe) { // seg000:696A W_MEMW(word_1B3A6, 0x4679); } // seg000:6980 W_MEMW(word_1C74A, 9); reg_ax = 1; reg_cl = MEMB(word_1C74A); reg_ax <<= reg_cl; reg_ax--; W_MEMW(word_1B398, reg_ax); // seg000:6993 reg_ax = MEMW(word_1B3A6); reg_ax <<= 1; PUSHI(0); PUSH(ax); EMU_CALL(a_alloc_mem, 699F, decomp_file); reg_sp += 4; W_MEMW(dword_1B2B6, reg_ax); W_MEMW(dword_1B2B6 + 2, reg_dx); // seg000:69A9 if (MEMD(dword_1B2B6) == 0) { // seg000:69B5 PUSHI(aOutOfMemoryTryUn_1); EMU_CALL(a_chg_vid_and_error, 69BC, decomp_file); reg_sp += 2; } // seg000:69BE PUSHI(0); PUSHI(MEMW(word_1B3A6)); EMU_CALL(a_alloc_mem, 69C8, decomp_file); reg_sp += 4; W_MEMW(dword_1D726, reg_ax); W_MEMW(dword_1D726 + 2, reg_dx); // seg000:69D2 if (MEMD(dword_1D726) == 0) { // seg000:69DE PUSHI(aOutOfMemoryTryUn_2); EMU_CALL(a_chg_vid_and_error, 69E5, decomp_file); reg_sp += 2; } // seg000:69E7 W_MEMW(word_1B346, 0); W_MEMW(dword_1B342, 0); W_MEMW(dword_1B342 + 2, 0); EMU_CALL(a_sub_6A30, 69FC, decomp_file); // seg000:69FC PUSHI(MEMW(dword_1B2B6 + 2)); PUSHI(MEMW(dword_1B2B6)); EMU_CALL(a_sub_DDFE, 6A07, decomp_file); reg_sp += 4; PUSHI(MEMW(dword_1D726 + 2)); PUSHI(MEMW(dword_1D726)); EMU_CALL(a_sub_DDFE, 6A15, decomp_file); reg_sp += 4; PUSHI(MEMW(reg_bp - 0xe)); PUSHI(MEMW(reg_bp - 0x10)); EMU_CALL(a_sub_DDFE, 6A21, decomp_file); reg_sp += 4; // seg000:6A24 reg_dx = MEMW(reg_bp - 0xa); reg_ax = MEMW(reg_bp - 0xc); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 6C49 void fade_in() { RETLOC(6C8B); RETLOC(6C7D); RETLOC(6C76); RETLOC(6C68); RETLOC(6C61); RETLOC(6C53); assert(reg_eip == 0x6c49); PUSH(bp); MOV(bp, sp); PUSHI(1); EMU_CALL(a_delay, 6C53, fade_in); reg_sp += 2; reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_dx = byte_15558; reg_ax = 0x1002; EMU_INSTR(6C5F, 6C61, fade_in); PUSHI(8); EMU_CALL(a_delay, 6C68, fade_in); reg_sp += 2; reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_dx = byte_15569; reg_ax = 0x1002; EMU_INSTR(6C74, 6C76, fade_in); PUSHI(8); EMU_CALL(a_delay, 6C7D, fade_in); reg_sp += 2; reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_dx = byte_1558B; reg_ax = 0x1002; EMU_INSTR(6C89, 6C8B, fade_in); POP(bp); RET; } // 6C8D void fade_out() { RETLOC(6CE4); RETLOC(6CD6); RETLOC(6CCF); RETLOC(6CC1); RETLOC(6CBA); RETLOC(6CAC); RETLOC(6CA5); RETLOC(6C97); assert(reg_eip == 0x6C8D); PUSH(bp); MOV(bp, sp); PUSHI(1); EMU_CALL(a_delay, 6C97, fade_out); reg_sp += 2; reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_dx = byte_1558B; reg_ax = 0x1002; EMU_INSTR(6CA3, 6CA5, fade_out); PUSHI(8); EMU_CALL(a_delay, 6CAC, fade_out); reg_sp += 2; reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_dx = byte_1557A; reg_ax = 0x1002; EMU_INSTR(6CB8, 6CBA, fade_out); PUSHI(8); EMU_CALL(a_delay, 6CC1, fade_out); reg_sp += 2; reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_dx = byte_15569; reg_ax = 0x1002; EMU_INSTR(6CCD, 6CCF, fade_out); PUSHI(8); EMU_CALL(a_delay, 6CD6, fade_out); reg_sp += 2; reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_dx = byte_15558; reg_ax = 0x1002; EMU_INSTR(6CE2, 6CE4, fade_out); POP(bp); RET; } // 6CE6 void decomp_graphics() { RETLOC(7785); RETLOC(6FF2); RETLOC(6FE9); RETLOC(6FD9); RETLOC(6FCB); RETLOC(6FBD); RETLOC(6FAF); RETLOC(6FA0); RETLOC(6F95); RETLOC(6EF9); RETLOC(6EE0); RETLOC(6EBA); RETLOC(6E98); RETLOC(6E8A); RETLOC(6E7D); RETLOC(6E5E); RETLOC(6E4B); RETLOC(6E31); RETLOC(6E28); RETLOC(6E18); RETLOC(6E0A); RETLOC(6DEA); RETLOC(6D21); RETLOC(6D17); RETLOC(6D09); RETLOC(6CFE); RETLOC(716A); RETLOC(70E9); RETLOC(7302); RETLOC(7503); RETLOC(76FC); assert(reg_eip == 0x6CE6); PUSH(bp); MOV(bp, sp); reg_sp -= 0x68; PUSH(si); PUSH(di); PUSHI(SegValue(ss)); //dest reg_ax = reg_bp - 0x40; PUSH(ax); PUSHI(SegValue(ds)); //source PUSHI(a_gapics_); reg_cx = 0xd; //copy filename to stack EMU_CALL(a_N_SCOPY, 6CFE, decomp_graphics); PUSHI(aEgahead_); //bp-0x40 = egahead.ckx PUSHI(reg_bp - 0x40); EMU_CALL(a__strcpy, 6D09, decomp_graphics); reg_sp += 4; PUSHI(MEMW(pExt)); PUSHI(reg_bp - 0x40); EMU_CALL(a__strcat, 6D17, decomp_graphics); reg_sp += 4; PUSHI(reg_bp - 0x40); EMU_CALL(a_alloc_and_map_file, 6D21, decomp_graphics); //alloc and map egahead.ckx reg_sp += 2; W_MEMW(reg_bp - 0x20, reg_ax); //file in memory at dx:ax W_MEMW(reg_bp - 0x20 + 2, reg_dx); reg_bx = MEMW(reg_bp - 0x20); SegSet16(es, MEMW(reg_bp - 0x20 + 2)); //es:bx = EGAHEAD (eg 2494 in dosbox cs=018e) // EGAHEAD data // seg000:6D2C reg_ax = mem_readw(SegPhys(es) + reg_bx + 0x2e); // compression flag W_MEMW(reg_bp - 0xc, reg_ax); reg_ax = mem_readw(SegPhys(es) + reg_bx + 0x10); // FontNum W_MEMW(EGAHEAD_FontNum, reg_ax); reg_ax = mem_readw(SegPhys(es) + reg_bx + 0x1c); // TileNum W_MEMW(EGAHEAD_TileNum, reg_ax); reg_ax = mem_readw(SegPhys(es) + reg_bx + 0x22); // BmpNum W_MEMW(EGAHEAD_BmpNum, reg_ax); reg_ax = mem_readw(SegPhys(es) + reg_bx + 0x28); // SpriteNum W_MEMW(EGAHEAD_SpriteNum, reg_ax); // seg000:6D4F int tmp1 = mem_readd(SegPhys(es) + reg_bx + 0xc); // SprtDataStart tmp1 /= 0x10; // convert to segment reg_dx = MEMW(reg_bp - 0x20 + 2); reg_dx += tmp1 & 0xffff; reg_ax = MEMW(reg_bp - 0x20); W_MEMW(sprite_data, reg_ax); // save sprite data far pointer W_MEMW(sprite_data + 2, reg_dx); W_MEMW(reg_bp - 4, 0); W_MEMW(reg_bp - 2, 0); W_MEMW(reg_bp - 6, 0); while(1) { // seg000:6DCA reg_bx = MEMW(reg_bp - 0x20); // es:bx = EGALATCH SegSet16(es, MEMW(reg_bp - 0x20 + 2)); reg_ax = mem_readw(SegPhys(es) + reg_bx + 0x28); // SpriteNum reg_ax <<= 2; // seg000:6DD5 if ((short)reg_ax <= (short)MEMW(reg_bp - 6)) { W_MEMW(reg_bp - 6, 0); break; } // seg000:6D81 int tmp1 = (short)MEMW(reg_bp - 6); tmp1 <<= 5; tmp1 = N_PADD(MEMD(sprite_data), tmp1); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_ax = mem_readw(SegPhys(es) + reg_bx); PUSH(ax); // seg000:6DA0 // this is ok // seg000:6DBB POP(ax); reg_ax *= mem_readw(SegPhys(es) + reg_bx + 2); tmp1 = (short)reg_ax; W_MEMD(reg_bp - 4, (int)MEMD(reg_bp - 4) + tmp1); // seg000:6DC7 W_MEMW(reg_bp - 6, MEMW(reg_bp - 6) + 1); } // seg000:6DF9 while ((short)MEMW(reg_bp - 6) < 5) { // seg000:6DE1 PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_sub_5C58, 6DEA, decomp_graphics); reg_sp += 4; reg_bx = MEMW(reg_bp - 6); reg_bx <<= 1; W_MEMW(sprite_src_hi_1 + reg_bx, reg_dx); W_MEMW(reg_bp - 6, MEMW(reg_bp - 6) + 1); } // seg000:6DFF // LOAD EGA LATCH // set bp-40 to egalatch filename+extension PUSHI(aEgalatch_); PUSHI(reg_bp - 0x40); EMU_CALL(a__strcpy, 6E0A, decomp_graphics); reg_sp += 4; PUSHI(MEMW(pExt)); PUSHI(reg_bp - 0x40); EMU_CALL(a__strcat, 6E18, decomp_graphics); reg_sp += 4; // decompress EGALATCH if compressed // seg000:6E1B if (MEMW(reg_bp - 0xc) != 0) { // seg000:6E21 PUSHI(reg_bp - 0x40); //filename EMU_CALL(a_decomp_file, 6E28, decomp_graphics); } else { // seg000:6E2A PUSHI(reg_bp - 0x40); EMU_CALL(a_alloc_and_map_file, 6E31, decomp_graphics); } // seg000:6E31 //dx:ax = far ptr to latch (eg. 513a:0) -- save in bp-0x28 reg_sp += 2; W_MEMW(reg_bp - 0x28, reg_ax); W_MEMW(reg_bp - 0x26, reg_dx); W_MEMD(reg_bp - 0x30, MEMD(dword_1D72E)); //eg 5139:04 (what is??) // seg000:6E46 // set video mode D reg_ax = 0xd; EMU_INSTR(6E49, 6E4B, decomp_graphics); W_MEMW(dstseg, 0xa000); W_MEMW(reg_bp - 6, 0); // seg000:6E6D while ((short)MEMW(reg_bp - 6) < 4) { // seg000:6E58 PUSHI(MEMW(reg_bp - 6)); EMU_CALL(a_vga_regplane_select, 6E5E, decomp_graphics); reg_sp += 2; SegSet16(es, MEMW(dstseg)); mem_writew(SegPhys(es) + 0x2000, 0); //a000:2000 = 0 W_MEMW(reg_bp - 6, MEMW(reg_bp - 6) + 1); } // select CRT controller register, index 13 == offset register // seg000:6E73 reg_al = 0x13; PUSH(ax); reg_ax = 0x3d4; PUSH(ax); EMU_CALL(a__outportb, 6E7D, decomp_graphics); reg_sp += 4; // offset register = 18h = 24 // seg000:6E80 reg_al = 0x18; PUSH(ax); reg_ax = 0x3d5; PUSH(ax); EMU_CALL(a__outportb, 6E8A, decomp_graphics); reg_sp += 4; // select Graphics Controller register, index 5 == write mode = 0 // seg000:6E8D reg_ax = 5; PUSH(ax); reg_ax = 0x3ce; PUSH(ax); EMU_CALL(a__outport, 6E98, decomp_graphics); reg_sp += 4; W_MEMW(reg_bp - 6, 0); // For each egalatch plane: bp-6 = current plane // seg000:6EFF while ((short)MEMW(reg_bp - 6) < 4) { // seg000:6EA2 reg_ax = 0; reg_dx = 0x10; //PUSH(ax); //PUSH(dx); reg_bx = MEMW(reg_bp - 0x20); //es:bx = EGAHEAD SegSet16(es, MEMW(reg_bp - 0x20 + 2)); reg_cx = mem_readw(SegPhys(es) + reg_bx + 2); reg_bx = mem_readw(SegPhys(es) + reg_bx); // //dx:ax *= cx:bx --> es:[bx] * (0 thru 3) //size of plane in bytes // seg000:6EB3 calculating offset int tmp1 = (short)MEMW(reg_bp - 6); reg_ax = tmp1 & 0xffff; reg_dx = tmp1 >> 16; EMU_CALL(a__LXMUL, 6EBA, decomp_graphics); tmp1 = (reg_dx << 16) | reg_ax; tmp1 /= 0x10; //convert to segment // seg000:6EBF reg_dx = MEMW(reg_bp - 0x26); reg_dx += tmp1 & 0xffff; W_MEMW(reg_bp - 0x32, reg_dx); // Set memory write plane enable to current plane (bp-6) reg_ax = 1; reg_cl = MEMB(reg_bp - 6); reg_ax <<= reg_cl; reg_cl = 8; reg_ax <<= reg_cl; reg_dx = 2; reg_dx |= reg_ax; PUSH(dx); reg_ax = 0x3c4; PUSH(ax); EMU_CALL(a__outport, 6EE0, decomp_graphics); reg_sp += 4; // seg000:6EE3 reg_bx = MEMW(reg_bp - 0x20); SegSet16(es, MEMW(reg_bp - 0x20 + 2)); PUSHI(mem_readw(SegPhys(es) + reg_bx)); // size of plane in bytes (e.g. 74E0h) PUSHI(0); // dest off PUSHI(0xa700); // dest seg PUSHI(0); // src off PUSHI(MEMW(reg_bp - 0x32)); // src seg (e.g. 513Ah) EMU_CALL(a__movedata, 6EF9, decomp_graphics); reg_sp += 0x0a; W_MEMW(reg_bp - 6, MEMW(reg_bp - 6) + 1); } // Save various EGAHEAD far pointers // seg000:6F05 reg_bx = MEMW(reg_bp - 0x20); //es:bx = egahead SegSet16(es, MEMW(reg_bp - 0x20 + 2)); tmp1 = mem_readd(SegPhys(es) + reg_bx + 0x12); //FontLoc tmp1 /= 0x10; //convert to segment reg_ax = (tmp1 & 0xffff) + 0xa700; W_MEMW(EGAHEAD_font_off, 0); W_MEMW(EGAHEAD_font_seg, reg_ax); // seg000:6F26 tmp1 = mem_readd(SegPhys(es) + 0x1e); //Tile Loc tmp1 /= 0x10; reg_ax = (tmp1 & 0xffff) + 0xa700; W_MEMW(EGAHEAD_Tileloc_off, 0); W_MEMW(EGAHEAD_Tileloc_seg, reg_ax); // seg000:6F47 //BmpLoc tmp1 = mem_readd(SegPhys(es) + 0x24); tmp1 /= 0x10; reg_ax = (tmp1 & 0xffff) + 0xa700; W_MEMW(EGAHEAD_Bmploc_off, 0); W_MEMW(EGAHEAD_Bmploc_seg, reg_ax); // seg000:6F68 tmp1 = mem_readd(SegPhys(es) + 8); //Bmpdatastart tmp1 /= 0x10; reg_dx = MEMW(reg_bp - 0x20 + 2) + (tmp1 & 0xffff); reg_ax = MEMW(reg_bp - 0x20); W_MEMW(EGAHEAD_Bmpdatastart_off, reg_ax); W_MEMW(EGAHEAD_Bmpdatastart_seg, reg_dx); // seg000:6F8C //latch data? PUSHI(MEMW(reg_bp - 0x2e)); //5139 PUSHI(MEMW(reg_bp - 0x30)); //04 EMU_CALL(a_sub_DDFE, 6F95, decomp_graphics); reg_sp += 4; // seg000:6F98 reg_ax = 0x1001; reg_bh = 3; EMU_INSTR(6F9E, 6FA0, decomp_graphics); //set border colour to bh PUSHI(0xe); PUSHI(0x3c); PUSHI(0xf); EMU_CALL(a_draw_filter, 6FAF, decomp_graphics); reg_sp += 6; PUSHI(5); PUSHI(0x3ce); //set graphics mode register to 0 EMU_CALL(a__outport, 6FBD, decomp_graphics); reg_sp += 4; // seg000:6FC0 PUSHI(aEgasprit_); PUSHI(reg_bp - 0x40); EMU_CALL(a__strcpy, 6FCB, decomp_graphics); reg_sp += 4; PUSHI(MEMW(pExt)); PUSHI(reg_bp - 0x40); EMU_CALL(a__strcat, 6FD9, decomp_graphics); reg_sp += 4; // seg000:6FDC Decompress if compressed if (MEMW(reg_bp - 0xc) != 0) { // seg000:6FE2 PUSHI(reg_bp - 0x40); EMU_CALL(a_decomp_file, 6FE9, decomp_graphics); } else { // seg000:6FEB PUSHI(reg_bp - 0x40); EMU_CALL(a_alloc_and_map_file, 6FF2, decomp_graphics); } // seg000:6FF2 reg_sp += 2; W_MEMW(reg_bp - 0x24, reg_ax); W_MEMW(reg_bp - 0x22, reg_dx); W_MEMD(reg_bp - 0x2c, MEMD(dword_1D72E)); W_MEMW(dword_1D72A, 0); W_MEMW(dword_1D72A + 2, 0); W_MEMW(dword_1B2AE, 0); W_MEMW(dword_1B2AE + 2, 0); W_MEMW(reg_bp - 6, 0); while (1) { // seg000:7770 reg_ax = MEMW(reg_bp - 6); if ((short)reg_ax >= (short)MEMW(EGAHEAD_SpriteNum)) break; // seg000:7021 reg_ax = MEMW(reg_bp - 6); reg_ax <<= 2; tmp1 = (short)reg_ax; tmp1 <<= 5; tmp1 = N_PADD(MEMD(sprite_data), tmp1); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_ax = mem_readw(SegPhys(es) + reg_bx); PUSH(ax); // seg000:7044 // ok // seg000:7063 POP(ax); reg_ax *= mem_readw(SegPhys(es) + reg_bx + 2); W_MEMW(reg_bp - 0xe, reg_ax); // seg000:706B // ok // seg000:708A tmp1 = mem_readd(SegPhys(es) + reg_bx + 4); W_MEMD(dword_1D72A, tmp1); // seg000:7099 // ok reg_ax = reg_bx; // seg000:70B4 reg_bx = MEMW(dword_1B2AE + 2); reg_cx = MEMW(dword_1B2AE); MOV(si, ax); mem_writew(SegPhys(es) + reg_si + 4, reg_cx); mem_writew(SegPhys(es) + reg_si + 6, reg_bx); W_MEMW(reg_bp - 8, 0); // seg000:7170 while ((short)MEMW(reg_bp - 8) < 5) { // seg000:70D0 reg_bx = MEMW(reg_bp - 0x20); SegSet16(es, MEMW(reg_bp - 0x20 + 2)); reg_cx = mem_readw(SegPhys(es) + reg_bx + 6); reg_bx = mem_readw(SegPhys(es) + reg_bx + 4); tmp1 = (short)MEMW(reg_bp - 8); reg_ax = tmp1 & 0xffff; reg_dx = tmp1 >> 16; EMU_CALL(a__LXMUL, 70E9, decomp_graphics); tmp1 = (reg_dx << 16) | reg_ax; tmp1 /= 0x10; reg_ax = tmp1 & 0xffff; reg_dx = MEMW(dword_1D72A + 2); reg_dx += MEMW(reg_bp - 0x22); reg_dx += reg_ax; reg_ax = MEMW(dword_1D72A); reg_bx = MEMW(reg_bp - 8); reg_bx <<= 2; reg_cx = reg_bp - 0x54; reg_bx += reg_cx; W_MEMW(reg_bx, reg_ax); W_MEMW(reg_bx + 2, reg_dx); // seg000:710B reg_bx = MEMW(reg_bp - 8); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; // seg000:7117 reg_si = MEMW(reg_bp - 8); reg_si <<= 1; reg_ax = MEMW(dword_1B2AE + 2); reg_ax += MEMW(sprite_src_hi_1 + reg_si); reg_dx = MEMW(dword_1B2AE); W_MEMW(reg_bx, reg_dx); W_MEMW(reg_bx + 2, reg_ax); // seg000:712C PUSHI(MEMW(reg_bp - 0xe)); reg_bx = MEMW(reg_bp - 8); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; PUSHI(MEMW(reg_bx)); reg_bx = MEMW(reg_bp - 8); reg_bx <<= 2; reg_ax = reg_bp - 0x66; reg_bx += reg_ax; PUSHI(MEMW(reg_bx)); // seg000:714B reg_bx = MEMW(reg_bp - 8); reg_bx <<= 2; reg_ax = reg_bp - 0x54; reg_bx += reg_ax; PUSHI(MEMW(reg_bx)); reg_bx = MEMW(reg_bp - 8); reg_bx <<= 2; reg_ax = reg_bp - 0x52; reg_bx += reg_ax; PUSHI(MEMW(reg_bx)); EMU_CALL(a__movedata, 716A, decomp_graphics); reg_sp += 0xa; // seg000:716D W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) + 1); } // seg000:7179 reg_ax = MEMW(dword_1B2AE); reg_ax += MEMW(reg_bp - 0xe); reg_dx = MEMW(dword_1B2AE + 2); W_MEMW(dword_1B2AE, reg_ax); W_MEMW(dword_1B2AE + 2, reg_dx); reg_ax = MEMW(reg_bp - 6); reg_ax <<= 2; tmp1 = (short)reg_ax; tmp1 <<= 5; tmp1 = N_PADD(MEMD(sprite_data), tmp1); tmp1 = N_PADD(tmp1, 0x20); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_ax = mem_readw(SegPhys(es) + reg_bx); PUSH(ax); // seg000:71B5 // ok // seg000:71DC POP(ax); reg_ax *= mem_readw(SegPhys(es) + reg_bx + 2); W_MEMW(reg_bp - 0xe, reg_ax); // seg000:71E4 // ok reg_ax = reg_bx; // seg000:7207 reg_bx = MEMW(dword_1B2AE + 2); reg_cx = MEMW(dword_1B2AE); MOV(si, ax); mem_writew(SegPhys(es) + reg_si + 4, reg_cx); mem_writew(SegPhys(es) + reg_si + 6, reg_bx); W_MEMW(reg_bp - 0xa, 0); // seg000:7361 while ((short)MEMW(reg_bp - 0xa) < 5) { // seg000:7223 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; reg_si = MEMW(reg_bp - 0xa); reg_si <<= 1; reg_ax = MEMW(dword_1B2AE + 2); reg_ax += MEMW(sprite_src_hi_1 + reg_si); reg_dx = MEMW(dword_1B2AE); W_MEMW(reg_bx, reg_dx); W_MEMW(reg_bx + 2, reg_ax); // seg000:7244 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x16, reg_ax); // seg000:7255 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x66; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x14, reg_ax); // seg000:7266 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x54; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x12, reg_ax); // seg000:7277 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x52; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x10, reg_ax); // seg000:7288 reg_ax = MEMW(reg_bp - 6); reg_ax <<= 2; tmp1 = (short)reg_ax; tmp1 <<= 5; tmp1 = N_PADD(MEMD(sprite_data), tmp1); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 0x18, reg_ax); // seg000:72AD // ok // seg000:72CC reg_ax = mem_readw(SegPhys(es) + reg_bx + 2); W_MEMW(reg_bp - 0x1a, reg_ax); // seg000:72D3 if (MEMW(reg_bp - 0xa) == 4) { // seg000:72D9 reg_ax = 1; } else { // seg000:72DE reg_ax = 0; } // seg000:72E0 reg_ax *= 0xff; W_MEMB(reg_bp - 0x1b, reg_al); PUSH(si); PUSH(di); PUSHI(SegValue(ds)); reg_di = MEMW(reg_bp - 0x16); reg_si = MEMW(reg_bp - 0x12); reg_bx = MEMW(reg_bp - 0x18); reg_dx = MEMW(reg_bp - 0x1A); reg_ax = MEMW(reg_bp - 0x14); SegSet16(es, reg_ax); reg_ax = MEMW(reg_bp - 0x10); SegSet16(ds, reg_ax); EMU_INSTR(7301, 7302, decomp_graphics); do { // seg000:7302 MOV(cx, bx); while (reg_cx != 0) { mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; reg_cx--; } // seg000:7306 reg_al = mem_readb(SegPhys(ss) + reg_bp - 0x1b); mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_di -= reg_bx; reg_di--; // seg000:730D MOV(cx, bx); reg_cx++; reg_al = mem_readb(SegPhys(ss) + reg_bp - 0x1b); int CFtmp = reg_al & 1; reg_al >>= 1; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; do { // seg000:7315 reg_al = mem_readb(SegPhys(es) + reg_di); CFtmp = reg_al & 1; reg_al >>= 1; reg_al |= (reg_flags & FLAG_CF) << 7; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_cx--; } while (reg_cx != 0); // 7320 reg_di -= reg_bx; reg_di--; MOV(cx, bx); reg_cx++; reg_al = mem_readb(SegPhys(ss) + reg_bp - 0x1b); CFtmp = reg_al & 1; reg_al >>= 1; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; do { // seg000:732B reg_al = mem_readb(SegPhys(es) + reg_di); CFtmp = reg_al & 1; reg_al >>= 1; reg_al |= (reg_flags & FLAG_CF) << 7; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_cx--; } while (reg_cx != 0); // seg000:7336 reg_dx--; } while (reg_dx != 0); // seg000:7339 POP(ax); SegSet16(ds, reg_ax); POP(di); POP(si); reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; reg_ax = MEMW(reg_bx + 2); reg_dx = MEMW(reg_bx); reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_cx = reg_bp - 0x54; reg_bx += reg_cx; W_MEMW(reg_bx, reg_dx); W_MEMW(reg_bx + 2, reg_ax); // seg000:735E W_MEMW(reg_bp - 0xa, MEMW(reg_bp - 0xa) + 1); } // seg000:736A reg_ax = MEMW(dword_1B2AE); reg_ax += MEMW(reg_bp - 0xe); reg_dx = MEMW(dword_1B2AE + 2); W_MEMW(dword_1B2AE, reg_ax); W_MEMW(dword_1B2AE + 2, reg_dx); reg_ax = MEMW(reg_bp - 6); reg_ax <<= 2; int tmp1 = (short)reg_ax; tmp1 <<= 5; tmp1 = N_PADD(MEMD(sprite_data), tmp1); tmp1 = N_PADD(tmp1, 0x40); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_ax = mem_readw(SegPhys(es) + reg_bx); PUSH(ax); // seg000:73A5 // ok // seg000:73CD POP(ax); reg_ax *= mem_readw(SegPhys(es) + reg_bx + 2); W_MEMW(reg_bp - 0xe, reg_ax); // seg000:73D5 // ok reg_ax = reg_bx; // seg000:73F8 reg_bx = MEMW(dword_1B2AE + 2); reg_cx = MEMW(dword_1B2AE); reg_si = reg_ax; mem_writew(SegPhys(es) + reg_si + 4, reg_cx); mem_writew(SegPhys(es) + reg_si + 6, reg_bx); W_MEMW(reg_bp - 0xa, 0); // seg000:755A while ((short)MEMW(reg_bp - 0xa) < 5) { // seg000:7414 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; reg_si = MEMW(reg_bp - 0xa); reg_si <<= 1; reg_ax = MEMW(dword_1B2AE + 2); reg_ax += MEMW(sprite_src_hi_1 + reg_si); reg_dx = MEMW(dword_1B2AE); W_MEMW(reg_bx, reg_dx); W_MEMW(reg_bx + 2, reg_ax); // seg000:7435 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x16, reg_ax); // seg000:7446 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x66; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x14, reg_ax); // seg000:7457 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x54; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x12, reg_ax); // seg000:7468 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x52; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x10, reg_ax); // seg000:7479 reg_ax = MEMW(reg_bp - 0x6); reg_ax <<= 2; tmp1 = (short)reg_ax; tmp1 <<= 5; tmp1 = N_PADD(MEMD(sprite_data), tmp1); tmp1 = N_PADD(tmp1, 0x40); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); // seg000:74A0 reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 0x18, reg_ax); // seg000:74A6 // ok // seg000:74CD reg_ax = mem_readw(SegPhys(es) + reg_bx + 2); W_MEMW(reg_bp - 0x1a, reg_ax); // seg000:74D4 if (MEMW(reg_bp - 0xa) == 4) { // seg000:74DA reg_ax = 1; } else { // seg000:74DF reg_ax = 0; } // seg000:74E1 reg_dx = 0xff; reg_ax *= reg_dx; W_MEMB(reg_bp - 0x1b, reg_al); PUSH(si); PUSH(di); PUSHI(SegValue(ds)); reg_di = MEMW(reg_bp - 0x16); reg_si = MEMW(reg_bp - 0x12); reg_bx = MEMW(reg_bp - 0x18); reg_dx = MEMW(reg_bp - 0x1a); reg_ax = MEMW(reg_bp - 0x14); SegSet16(es, reg_ax); reg_ax = MEMW(reg_bp - 0x10); SegSet16(ds, reg_ax); EMU_INSTR(7502, 7503, decomp_graphics); do { // seg000:7503 MOV(cx, bx); while (reg_cx != 0) { mem_writeb(SegPhys(es) + reg_di, mem_readb(SegPhys(ds) + reg_si)); reg_di++; reg_si++; reg_cx--; } reg_di -= reg_bx; MOV(cx, bx); reg_al = mem_readb(SegPhys(ss) + reg_bp - 0x1b); int CFtmp = reg_al & 1; reg_al >>= 1; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; do { // seg000:7510 reg_al = mem_readb(SegPhys(es) + reg_di); CFtmp = reg_al & 1; reg_al >>= 1; reg_al |= (reg_flags & FLAG_CF) << 7; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_cx--; } while (reg_cx != 0); // seg000:751B reg_di -= reg_bx; MOV(cx, bx); reg_al = mem_readb(SegPhys(ss) + reg_bp - 0x1b); CFtmp = reg_al & 1; reg_al >>= 1; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; do { // seg000:7524 reg_al = mem_readb(SegPhys(es) + reg_di); CFtmp = reg_al & 1; reg_al >>= 1; reg_al |= (reg_flags & FLAG_CF) << 7; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_cx--; } while (reg_cx != 0); // seg000:752F reg_dx--; } while (reg_dx != 0); // seg000:7532 POP(ax); SegSet16(ds, reg_ax); POP(di); POP(si); reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; reg_ax = MEMW(reg_bx + 2); reg_dx = MEMW(reg_bx); reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_cx = reg_bp - 0x54; reg_bx += reg_cx; W_MEMW(reg_bx, reg_dx); W_MEMW(reg_bx + 2, reg_ax); // seg000:7557 W_MEMW(reg_bp - 0xa, MEMW(reg_bp - 0xa) + 1); } // seg000:7563 reg_ax = MEMW(dword_1B2AE); reg_ax += MEMW(reg_bp - 0xe); reg_dx = MEMW(dword_1B2AE + 2); W_MEMW(dword_1B2AE, reg_ax); W_MEMW(dword_1B2AE + 2, reg_dx); // seg000:7574 reg_ax = MEMW(reg_bp - 6); reg_ax <<= 2; tmp1 = (short)reg_ax; tmp1 <<= 5; tmp1 = N_PADD(MEMD(sprite_data), tmp1); tmp1 = N_PADD(tmp1, 0x60); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_ax = mem_readw(SegPhys(es) + reg_bx); PUSH(ax); // seg000:759F // ok // seg000:75C6 POP(ax); reg_ax *= mem_readw(SegPhys(es) + reg_bx + 2); W_MEMW(reg_bp - 0xe, reg_ax); // seg000:75CE // ok reg_ax = reg_bx; // seg000:75F1 reg_bx = MEMW(dword_1B2AE + 2); reg_cx = MEMW(dword_1B2AE); reg_si = reg_ax; mem_writew(SegPhys(es) + reg_si + 4, reg_cx); mem_writew(SegPhys(es) + reg_si + 6, reg_bx); W_MEMW(reg_bp - 0xa, 0); // seg000:7753 while ((short)MEMW(reg_bp - 0xa) < 5) { //5 egasprit planes? // seg000:760D reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; reg_si = MEMW(reg_bp - 0xa); reg_si <<= 1; reg_ax = MEMW(dword_1B2AE + 2); reg_ax += MEMW(sprite_src_hi_1 + reg_si); reg_dx = MEMW(dword_1B2AE); W_MEMW(reg_bx, reg_dx); W_MEMW(reg_bx + 2, reg_ax); // seg000:762E // ok // seg000:763A reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x16, reg_ax); // seg000:763F // ok reg_bx += 2; // seg000:764B reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x14, reg_ax); // seg000:7650 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x54; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x12, reg_ax); // seg000:7661 reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x52; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 0x10, reg_ax); // seg000:7672 reg_ax = MEMW(reg_bp - 6); reg_ax <<= 2; tmp1 = (short)reg_ax; tmp1 <<= 5; tmp1 = N_PADD(MEMD(sprite_data), tmp1); tmp1 = N_PADD(tmp1, 0x60); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 0x18, reg_ax); // seg000:769F // ok // seg000:76C6 reg_ax = mem_readw(SegPhys(es) + reg_bx + 2); W_MEMW(reg_bp - 0x1a, reg_ax); // seg000:76CD if ((short)MEMW(reg_bp - 0xa) == 4) { // seg000:76D3 reg_ax = 1; } else { // seg000:76D8 reg_ax = 0; } // seg000:76DA reg_dx = 0xff; reg_ax *= reg_dx; W_MEMB(reg_bp - 0x1b, reg_al); PUSH(si); PUSH(di); PUSHI(SegValue(ds)); reg_di = MEMW(reg_bp - 0x16); reg_si = MEMW(reg_bp - 0x12); reg_bx = MEMW(reg_bp - 0x18); reg_dx = MEMW(reg_bp - 0x1a); reg_ax = MEMW(reg_bp - 0x14); SegSet16(es, reg_ax); reg_ax = MEMW(reg_bp - 0x10); SegSet16(ds, reg_ax); EMU_INSTR(76FB, 76FC, decomp_graphics); do { // seg000:76FC MOV(cx, bx); while (reg_cx != 0) { mem_writeb(SegPhys(es) + reg_di, mem_readb(SegPhys(ds) + reg_si)); reg_di++; reg_si++; reg_cx--; } reg_di -= reg_bx; MOV(cx, bx); reg_al = mem_readb(SegPhys(ss) + reg_bp - 0x1b); int CFtmp = reg_al & 1; reg_al >>= 1; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; do { // seg000:7709 reg_al = mem_readb(SegPhys(es) + reg_di); CFtmp = reg_al & 1; reg_al >>= 1; reg_al |= (reg_flags & FLAG_CF) << 7; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_cx--; } while (reg_cx != 0); // seg000:7714 reg_di -= reg_bx; MOV(cx, bx); reg_al = mem_readb(SegPhys(ss) + reg_bp - 0x1b); CFtmp = reg_al & 1; reg_al >>= 1; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; do { // seg000:771D reg_al = mem_readb(SegPhys(es) + reg_di); CFtmp = reg_al & 1; reg_al >>= 1; reg_al |= (reg_flags & FLAG_CF) << 7; reg_flags &= ~FLAG_CF; reg_flags |= CFtmp; mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_cx--; } while (reg_cx != 0); // seg000:7728 reg_dx--; } while (reg_dx != 0); // seg000:772B POP(ax); SegSet16(ds, reg_ax); POP(di); POP(si); reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_ax = reg_bp - 0x68; reg_bx += reg_ax; reg_ax = MEMW(reg_bx + 2); reg_dx = MEMW(reg_bx); reg_bx = MEMW(reg_bp - 0xa); reg_bx <<= 2; reg_cx = reg_bp - 0x54; reg_bx += reg_cx; W_MEMW(reg_bx, reg_dx); W_MEMW(reg_bx + 2, reg_ax); // seg000:7750 W_MEMW(reg_bp - 0xa, MEMW(reg_bp - 0xa) + 1); } // seg000:775C reg_ax = MEMW(dword_1B2AE); reg_ax += MEMW(reg_bp - 0xe); reg_dx = MEMW(dword_1B2AE + 2); W_MEMW(dword_1B2AE, reg_ax); W_MEMW(dword_1B2AE + 2, reg_dx); // seg000:776D W_MEMW(reg_bp - 6, MEMW(reg_bp - 6) + 1); } // seg000:777C PUSHI(MEMW(reg_bp - 0x2a)); PUSHI(MEMW(reg_bp - 0x2c)); EMU_CALL(a_sub_DDFE, 7785, decomp_graphics); reg_sp += 4; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 7913 void main_loop() { RETLOC(7AB4); RETLOC(7AB1); RETLOC(7AAE); RETLOC(7AA8); RETLOC(7A97); RETLOC(7A51); RETLOC(79F9); RETLOC(79E7); RETLOC(79DD); RETLOC(79CF); RETLOC(79C5); RETLOC(79B7); RETLOC(79AD); RETLOC(799F); RETLOC(7995); RETLOC(7987); RETLOC(797D); RETLOC(796F); RETLOC(7961); RETLOC(7945); RETLOC(793A); RETLOC(792A); RETLOC(7953); assert(reg_eip == 0x7913); PUSH(bp); MOV(bp, sp); reg_sp -= 0x3c; PUSH(si); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0xe; PUSH(ax); PUSHI(SegValue(ss)); reg_ax = aScores_; PUSH(ax); reg_cx = 0xd; EMU_CALL(a_N_SCOPY, 792A, main_loop); // seg000:792A PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x3c; PUSH(ax); PUSHI(SegValue(ds)); reg_ax = aYorpy; PUSH(ax); reg_cx = 0x3d; EMU_CALL(a_N_SCOPY, 793A, main_loop); // seg000:793A PUSHI(MEMW(pExt)); reg_ax = reg_bp - 0xe; PUSH(ax); EMU_CALL(a__strcat, 7945, main_loop); reg_sp += 4; // seg000:7948 PUSHI(MEMW(pExt)); reg_ax = aHelptext_; PUSH(ax); EMU_CALL(a__strcat, 7953, main_loop); reg_sp += 4; // seg000:7956 PUSHI(MEMW(pExt)); reg_ax = aStorytxt_; PUSH(ax); EMU_CALL(a__strcat, 7961, main_loop); reg_sp += 4; // seg000:7964 PUSHI(MEMW(pExt)); reg_ax = aEndtext_; PUSH(ax); EMU_CALL(a__strcat, 796F, main_loop); reg_sp += 4; // seg000:7972 PUSHI(MEMW(pExt)); reg_ax = aPreviews_; PUSH(ax); EMU_CALL(a__strcat, 797D, main_loop); reg_sp += 4; // seg000:7980 reg_ax = aHelptext_; PUSH(ax); EMU_CALL(a_alloc_and_map_file, 7987, main_loop); reg_sp += 2; W_MEMW(help_text, reg_ax); W_MEMW(help_text + 2, reg_dx); PUSH(dx); PUSH(ax); EMU_CALL(a_process_text_file, 7995, main_loop); reg_sp += 4; // seg000:7998 reg_ax = aStorytxt_; PUSH(ax); EMU_CALL(a_alloc_and_map_file, 799F, main_loop); reg_sp += 2; W_MEMW(story_text, reg_ax); W_MEMW(story_text + 2, reg_dx); PUSH(dx); PUSH(ax); EMU_CALL(a_process_text_file, 79AD, main_loop); reg_sp += 4; // seg000:79B0 reg_ax = aEndtext_; PUSH(ax); EMU_CALL(a_alloc_and_map_file, 79B7, main_loop); reg_sp += 2; W_MEMW(end_text, reg_ax); W_MEMW(end_text + 2, reg_dx); PUSH(dx); PUSH(ax); EMU_CALL(a_process_text_file, 79C5, main_loop); reg_sp += 4; // seg000:79C8 reg_ax = aPreviews_; PUSH(ax); EMU_CALL(a_alloc_and_map_file, 79CF, main_loop); reg_sp += 2; W_MEMW(previews_text, reg_ax); W_MEMW(previews_text + 2, reg_dx); PUSH(dx); PUSH(ax); EMU_CALL(a_process_text_file, 79DD, main_loop); reg_sp += 4; // seg000:79E0 reg_ax = a_sub_7ABB; PUSH(ax); EMU_CALL(a__harderr, 79E7, main_loop); reg_sp += 2; W_MEMW(on_world_map, 0); PUSHI(0); reg_ax = reg_bp - 0xe; PUSH(ax); EMU_CALL(a_sub_C552, 79F9, main_loop); reg_sp += 4; // seg000:79FC if (reg_ax != 0) { // seg000:7A03 reg_si = 0; // seg000:7A7D while ((short)reg_si < 7) { // seg000:7A08 MOV(bx, si); reg_bx <<= 2; W_MEMD(dword_1DB4E + reg_bx, 0x64); MOV(bx, si); reg_bx <<= 1; W_MEMW(word_1DBB0 + reg_bx, 0); MOV(bx, si); reg_bx <<= 1; W_MEMW(word_1DBA2 + reg_bx, 0); // seg000:7A2E MOV(ax, si); int tmp1 = (short)reg_ax; reg_dx = tmp1 % 3; MOV(ax, dx); reg_ax *= 0xf; reg_dx = reg_bp - 0x3c; reg_ax += reg_dx; PUSH(ax); // seg000:7A43 MOV(ax, si); reg_ax *= 0xd; reg_ax += unk_1DBBE; PUSH(ax); EMU_CALL(a__strcpy, 7A51, main_loop); reg_sp += 4; // seg000:7A54 MOV(bx, si); reg_bx <<= 1; W_MEMW(word_1DB6A + reg_bx, 0); // seg000:7A5E MOV (bx, si); reg_bx <<= 1; W_MEMW(word_1DB78 + reg_bx, 0); // seg000:7A68 MOV (bx, si); reg_bx <<= 1; W_MEMW(word_1DB94 + reg_bx, 0); // seg000:7A72 MOV (bx, si); reg_bx <<= 1; W_MEMW(word_1DB86 + reg_bx, 0); // seg000:7A7C reg_si++; } // seg000:7A84 reg_ax = 0; reg_dx = 0xcc; PUSH(ax); PUSH(dx); PUSHI(SegValue(ds)); reg_ax = dword_1DB4E; PUSH(ax); reg_ax = reg_bp - 0xe; PUSH(ax); EMU_CALL(a_write_file, 7A97, main_loop); reg_sp += 0xa; } else { // seg000:7A9C PUSHI(SegValue(ds)); reg_ax = dword_1DB4E; PUSH(ax); reg_ax = reg_bp - 0xe; PUSH(ax); EMU_CALL(a_map_file_to_mem, 7AA8, main_loop); reg_sp += 6; } // seg000:7AAB EMU_CALL(a_fade_out, 7AAE, main_loop); while(1) { // seg000:7AAE EMU_CALL(a_do_intro_and_menu, 7AB1, main_loop); EMU_CALL(a_draw_worldmap, 7AB4, main_loop); } // seg000:7AB6 POP(si); MOV(sp, bp); POP(bp); RET; } // 7C04 void draw_worldmap() { RETLOC(7CC7); RETLOC(7C32); RETLOC(7C1E); RETLOC(7C17); RETLOC(7C14); RETLOC(8058); RETLOC(8055); RETLOC(8052); RETLOC(8052); RETLOC(7D13); RETLOC(7D0E); RETLOC(7E9C); RETLOC(7E93); RETLOC(7E90); RETLOC(7E8D); RETLOC(7F21); RETLOC(7F13); RETLOC(7EF3); RETLOC(7EE0); RETLOC(7ED2); RETLOC(7EBF); RETLOC(7EB1); RETLOC(7EA5); RETLOC(7F33); RETLOC(7F30); RETLOC(7FAB); RETLOC(7FA1); RETLOC(7F65); RETLOC(7F62); RETLOC(7F5C); RETLOC(7F59); RETLOC(7F4B); RETLOC(7F3C); RETLOC(803F); RETLOC(8020); RETLOC(7FE6); RETLOC(7FDA); assert(reg_eip == 0x7c04); PUSH(bp); MOV(bp, sp); reg_sp -= 0x1e; PUSH(si); PUSH(di); W_MEMW(reg_bp - 6, 0); EMU_CALL(a_clear_keys, 7C14, draw_worldmap); EMU_CALL(a_clear_overlay, 7C17, draw_worldmap); PUSHI(80); EMU_CALL(a_load_level_data, 7C1E, draw_worldmap); reg_sp += 2; // seg000:7C20 if (MEMW(word_1DADE) == 0) { // seg000:7C27 PUSHI(dword_1DB22); PUSHI(dword_1DB1E); EMU_CALL(a_sub_8F90, 7C32, draw_worldmap); reg_sp += 4; int tmp1 = MEMD(dword_1DB1E); tmp1 += 0xffff7000; W_MEMD(dword_1DB26, tmp1); tmp1 = MEMD(dword_1DB22); tmp1 += 0xffffd000; W_MEMD(dword_1DB2A, tmp1); W_MEMD(value, 0); } // seg000:7C6B int tmp1 = MEMD(dword_1DB26); W_MEMD(dword_1D752, tmp1); tmp1 = MEMD(dword_1DB2A); W_MEMD(dword_1D756, tmp1); tmp1 = MEMD(dword_1DB1E); W_MEMD(dword_1D74A, tmp1); tmp1 = MEMD(dword_1DB22); W_MEMD(dword_1D74E, tmp1); W_MEMW(word_1D738, 0x8000); // seg000:7CA9 tmp1 = MEMD(value); tmp1 /= 0x4e20; reg_ax = tmp1 & 0xffff; reg_dx = tmp1 >> 16; PUSH(ax); PUSH(dx); reg_dx = 0; reg_ax = 0x4e20; POP(cx); POP(bx); EMU_CALL(a__LXMUL, 7CC7, draw_worldmap); W_MEMW(dword_19F12, reg_ax); W_MEMW(dword_19F12 + 2, reg_dx); W_MEMW(quit_to_title, 0); W_MEMW(word_186A2, 0); W_MEMW(word_19CB2, 3); // seg000:7CE0 do { W_MEMW(reg_bp - 2, 0x6eda); //pointer to keen sprite data - initialize keen data reg_bx = MEMW(reg_bp - 2); W_MEMW(reg_bx + 0x1c, 0); W_MEMW(reg_bx + 0x1e, 0); W_MEMW(reg_bx + 0x20, 0); W_MEMW(reg_bx + 0x22, 0); W_MEMW(reg_bx + 0x28, 0x24); W_MEMW(cur_level, 0); PUSHI(80); EMU_CALL(a_load_level_data, 7D0E, draw_worldmap); reg_sp += 2; EMU_CALL(a_mark_cities_done, 7D13, draw_worldmap); W_MEMW(reg_bp - 4, 0); // seg000:7E48 while ((short)MEMW(reg_bp - 4) < 0x10) { // seg000:7D1B reg_ax = MEMW(reg_bp - 4); reg_ax *= 6; MOV(bx, ax); reg_di = MEMW(word_1D75E + reg_bx); reg_ax = MEMW(reg_bp - 4); reg_ax *= 6; MOV(bx, ax); reg_si = MEMW(word_1D760 + reg_bx); reg_bx = MEMW(reg_bp - 4); reg_bx <<= 1; // seg000:7D3C if (MEMW(word_1DAF6 + reg_bx) != 0) { // seg000:7D46 reg_ax = MEMW(reg_bp - 4); reg_ax *= 6; MOV(bx, ax); reg_ax = MEMW(word_1D762 + reg_bx); // seg000:7D54 if (reg_ax != 0) { // seg000:7D58 if (reg_ax == 1) { // seg000:7D8D MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0); MOV(ax, si); reg_ax *= MEMW(map_width_intiles); MOV(dx, di); reg_dx += reg_ax; reg_dx++; reg_dx <<= 1; reg_bx = MEMW(tile_data_sprites); reg_bx += reg_dx; mem_writew(SegPhys(es) + reg_bx, 0); // seg000:7DBA MOV(ax, si); reg_ax++; reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0); // seg000:7DD0 MOV(ax, si); reg_ax++; reg_ax *= MEMW(map_width_intiles); MOV(dx, di); reg_dx += reg_ax; reg_dx++; reg_dx <<= 1; reg_bx = MEMW(tile_data_sprites); reg_bx += reg_dx; mem_writew(SegPhys(es) + reg_bx, 0); // seg000:7DE9 MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x4e); // seg000:7DFE MOV(ax, si); reg_ax *= MEMW(map_width_intiles); MOV(dx, di); reg_dx += reg_ax; reg_dx++; reg_dx <<= 1; reg_bx = MEMW(tile_data_1); reg_bx += reg_dx; mem_writew(SegPhys(es) + reg_bx, 0x4f); // seg000:7E16 MOV(ax, si); reg_ax++; reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x50); // seg000:7E2C MOV(ax, si); reg_ax++; reg_ax *= MEMW(map_width_intiles); MOV(dx, di); reg_dx += reg_ax; reg_dx++; reg_dx <<= 1; reg_bx = MEMW(tile_data_1); reg_bx += reg_dx; mem_writew(SegPhys(es) + reg_bx, 0x51); } } else { // seg000:7D60 MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0); // seg000:7D75 MOV(ax, si); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x4d); } } // seg000:7E45 W_MEMW(reg_bp - 4, MEMW(reg_bp - 4) + 1); } // seg000:7E51 reg_bx = MEMW(reg_bp - 2); tmp1 = MEMD(dword_1D74A); W_MEMD(reg_bx + 4, tmp1); tmp1 = MEMD(dword_1D74E); W_MEMD(reg_bx + 8, tmp1); tmp1 = MEMD(dword_1D752); W_MEMD(scroll_x_lo, tmp1); tmp1 = MEMD(dword_1D756); W_MEMD(scroll_y_lo, tmp1); EMU_CALL(a_sync_drawing, 7E8D, draw_worldmap); EMU_CALL(a_draw_screen, 7E90, draw_worldmap); EMU_CALL(a_draw_screen, 7E93, draw_worldmap); // seg000:7E93 if (MEMW(reg_bp - 6) == 0) { //just died // seg000:7E99 EMU_CALL(a_show_keens_left, 7E9C, draw_worldmap); } // seg000:7E9C if ((short)MEMW(reg_bp - 6) < 2) { //did not exit level by teleport // seg000:7EA2 EMU_CALL(a_fade_in, 7EA5, draw_worldmap); } // seg000:7EA5 if (MEMW(reg_bp - 6) == 0) { //just died // seg000:7EAE EMU_CALL(a_clear_keys, 7EB1, draw_worldmap); W_MEMW(reg_bp - 4, 0); // seg000:7EFC while ((short)MEMW(reg_bp - 4) < 0x3c) { // seg000:7EB8 PUSHI(1); EMU_CALL(a_delay, 7EBF, draw_worldmap); reg_sp += 2; reg_ax = reg_bp - 0xc; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x12; PUSH(ax); EMU_CALL(a_handle_ctrl, 7ED2, draw_worldmap); reg_sp += 6; // seg000:7ED5 reg_ax = reg_bp - 0x12; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 7EE0, draw_worldmap); // seg000:7EE0 if (MEMW(reg_bp - 0xa) != 0) break; // seg000:7EE6 if (MEMW(reg_bp - 8) != 0) break; // seg000:7EEC PUSHI(1); EMU_CALL(a_translate_key, 7EF3, draw_worldmap); reg_sp += 2; // seg000:7EF5 if (reg_ax != 0) break; W_MEMW(reg_bp - 4, MEMW(reg_bp - 4) + 1); } do { // seg000:7F02 reg_ax = reg_bp - 0xc; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x18; PUSH(ax); EMU_CALL(a_handle_ctrl, 7F13, draw_worldmap); reg_sp += 6; // seg000:7F16 reg_ax = reg_bp - 0x18; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 7F21, draw_worldmap); // seg000:7F21 } while (MEMW(reg_bp - 0xa) != 0 || MEMW(reg_bp - 8) != 0); } // seg000:7F2D EMU_CALL(a_clear_keys, 7F30, draw_worldmap); EMU_CALL(a_clear_overlay, 7F33, draw_worldmap); W_MEMW(on_world_map, 1); // seg000:7F39 do { EMU_CALL(a_sync_drawing, 7F3C, draw_worldmap); PUSHI(MEMW(reg_bp - 2)); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x1e; PUSH(ax); EMU_CALL(a_handle_ctrl, 7F4B, draw_worldmap); reg_sp += 6; // seg000:7F4E reg_ax = reg_bp - 0x1e; reg_dx = SegValue(ss); reg_cx = 6; EMU_CALL(a_N_SPUSH, 7F59, draw_worldmap); EMU_CALL(a_move_worldmap, 7F5C, draw_worldmap); reg_sp += 8; EMU_CALL(a_draw_screen, 7F62, draw_worldmap); EMU_CALL(a_handle_cheat_keys, 7F65, draw_worldmap); // seg000:7F65 reg_bx = MEMW(reg_bp - 2); int tmp1 = MEMD(reg_bx + 4); W_MEMD(dword_1D74A, tmp1); tmp1 = MEMD(reg_bx + 8); W_MEMD(dword_1D74E, tmp1); tmp1 = MEMD(scroll_x_lo); W_MEMD(dword_1D752, tmp1); tmp1 = MEMD(scroll_y_lo); W_MEMD(dword_1D756, tmp1); EMU_CALL(a_handle_global_keys, 7FA1, draw_worldmap); // seg000:7FA1 if (MEMB(byte_180B5) != 0) { // seg000:7FA8 EMU_CALL(a_show_pause_menu, 7FAB, draw_worldmap); } // seg000:7FAB if (MEMW(quit_to_title) != 0) { // seg000:7FB2 goto loc_8055; } // seg000:7FB5 reg_si++; // seg000:7FB6 } while (MEMW(cur_level) == 0); //0 = worldmap // seg000:7FC0 W_MEMW(on_world_map, 0); reg_bx = MEMW(cur_level); reg_bx <<= 1; // seg000:7FCC if (MEMW(got_blue_keycard + reg_bx) != 0) continue; // seg000:7FD3 PUSHI(3); EMU_CALL(a_set_cur_sound, 7FDA, draw_worldmap); reg_sp += 2; // seg000:7FDC reg_ax = MEMW(cur_level); reg_ax &= 0xff; PUSH(ax); EMU_CALL(a_draw_level, 7FE6, draw_worldmap); reg_sp += 2; W_MEMW(reg_bp - 6, reg_ax); // ax = bp-6 = level_finished // seg000:7FEB if (MEMW(quit_to_title) != 0) { W_MEMW(quit_to_title, 0); goto loc_8055; } // seg000:7FFA if (MEMW(reg_bp - 6) != 0) { // seg000:8000 reg_ax = MEMW(reg_bp - 6); if (reg_ax == 1) { // seg000:800F Level is done reg_bx = MEMW(cur_level); reg_bx <<= 1; W_MEMW(got_blue_keycard + reg_bx, 1); } else if (reg_ax == 2) { // seg000:801D EMU_CALL(a_handle_secret_city, 8020, draw_worldmap); } // seg000:8020 if (MEMW(got_part_1) == 0) continue; // seg000:8027 if (MEMW(got_part_2) == 0) continue; // seg000:802E if (MEMW(got_part_3) == 0) continue; // seg000:8035 if (MEMW(got_part_4) == 0) continue; // seg000:803C EMU_CALL(a_draw_win, 803F, draw_worldmap); goto loc_8055; } // seg000:8041 W_MEMW(num_keens_left, MEMW(num_keens_left) - 1); // seg000:8045 } while ((short)MEMW(num_keens_left) > -1); // seg000:804F reg_eip = 0x804f; EMU_CALL(a_finish_cur_sound, 8052, draw_worldmap); EMU_CALL(a_fade_in, 8055, draw_worldmap); loc_8055: // seg000:8055 EMU_CALL(a_game_over, 8058, draw_worldmap); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 8150 void draw_stringz2() { RETLOC(8179); RETLOC(8170); RETLOC(8180); assert(reg_eip == 0x8150); PUSH(bp); MOV(bp, sp); reg_sp -= 2; PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 4); W_MEMB(reg_bp - 2 + 1, 0); reg_si = 0; while (1) { // seg000:817C PUSH(di); EMU_CALL(a__strlen, 8180, draw_stringz2); reg_sp += 2; // seg000:8182 if ((short)reg_ax <= (short)reg_si) break; // seg000:8162 MOV(bx, si); reg_al = MEMB(reg_bx + reg_di); W_MEMB(reg_bp - 2, reg_al); reg_ax = reg_bp - 2; PUSH(ax); EMU_CALL(a_draw_string, 8170, draw_stringz2); reg_sp += 2; PUSHI(6); EMU_CALL(a_delay, 8179, draw_stringz2); reg_sp += 2; reg_si++; } // seg000:8186 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 818C void draw_win() { RETLOC(82EF); RETLOC(82E8); RETLOC(82E2); RETLOC(82CF); RETLOC(8288); RETLOC(8285); RETLOC(8282); RETLOC(827F); RETLOC(827C); RETLOC(8267); RETLOC(8262); RETLOC(8259); RETLOC(8250); RETLOC(8247); RETLOC(823E); RETLOC(8235); RETLOC(822E); RETLOC(8228); RETLOC(8213); RETLOC(820C); RETLOC(8206); RETLOC(81F0); RETLOC(81ED); RETLOC(81D0); RETLOC(81C9); RETLOC(81C6); RETLOC(81B5); RETLOC(81A4); RETLOC(8522); RETLOC(851D); RETLOC(84F7); RETLOC(84F1); RETLOC(84AE); RETLOC(84A1); RETLOC(849B); RETLOC(8473); RETLOC(8460); RETLOC(8453); RETLOC(844D); RETLOC(8431); RETLOC(8424); RETLOC(841E); RETLOC(83F6); RETLOC(83E3); RETLOC(83DC); RETLOC(83CD); RETLOC(83C7); RETLOC(83B4); RETLOC(838E); RETLOC(8388); RETLOC(8375); RETLOC(8340); RETLOC(833A); RETLOC(8327); RETLOC(8911); RETLOC(88FD); RETLOC(88F6); RETLOC(88F3); RETLOC(88D9); RETLOC(88D0); RETLOC(88C6); RETLOC(88B1); RETLOC(88AA); RETLOC(88A4); RETLOC(8891); RETLOC(886F); RETLOC(8869); RETLOC(8826); RETLOC(881F); RETLOC(8818); RETLOC(8815); RETLOC(880F); RETLOC(87FC); RETLOC(87F9); RETLOC(87DA); RETLOC(87D3); RETLOC(87CE); RETLOC(87C5); RETLOC(87BC); RETLOC(87B3); RETLOC(87AA); RETLOC(87A1); RETLOC(8798); RETLOC(878E); RETLOC(8778); RETLOC(8768); RETLOC(875F); RETLOC(8755); RETLOC(8745); RETLOC(873E); RETLOC(8739); RETLOC(8730); RETLOC(8726); RETLOC(8711); RETLOC(8708); RETLOC(86FE); RETLOC(86EB); RETLOC(86E6); RETLOC(86DD); RETLOC(86D4); RETLOC(86CB); RETLOC(86C1); RETLOC(86AE); RETLOC(86A9); RETLOC(86A0); RETLOC(8697); RETLOC(868D); RETLOC(867A); RETLOC(8675); RETLOC(866C); RETLOC(8663); RETLOC(865A); RETLOC(8651); RETLOC(8647); RETLOC(8632); RETLOC(8628); RETLOC(8618); RETLOC(8611); RETLOC(860C); RETLOC(8603); RETLOC(85FA); RETLOC(85F1); RETLOC(85E7); RETLOC(85D2); RETLOC(85C9); RETLOC(85BF); RETLOC(85AF); RETLOC(85A6); RETLOC(859C); RETLOC(858C); RETLOC(8585); RETLOC(8580); RETLOC(8577); RETLOC(856E); RETLOC(8565); RETLOC(855E); RETLOC(8558); RETLOC(8543); assert(reg_eip == 0x818c); PUSH(bp); MOV(bp, sp); reg_sp -= 0x198; PUSH(si); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x4c; PUSH(ax); PUSHI(SegValue(ds)); PUSHI(unk_1597E); reg_cx = 0x3c; EMU_CALL(a_N_SCOPY, 81A4, draw_win); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0xf8; PUSH(ax); PUSHI(SegValue(ds)); PUSHI(unk_159BA); reg_cx = 0xac; EMU_CALL(a_N_SCOPY, 81B5, draw_win); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x198; PUSH(ax); PUSHI(SegValue(ds)); PUSHI(unk_15A66); reg_cx = 0xa0; EMU_CALL(a_N_SCOPY, 81C6, draw_win); EMU_CALL(a_clear_keys, 81C9, draw_win); PUSHI(80); EMU_CALL(a_load_level_data, 81D0, draw_win); reg_sp += 2; // seg000:81D2 W_MEMD(scroll_x_lo, 0x3000); W_MEMD(scroll_y_lo, 0x23000); EMU_CALL(a_clear_overlay, 81ED, draw_win); EMU_CALL(a_sync_drawing, 81F0, draw_win); PUSHI(0x28); PUSHI(2); PUSHI(0x7000); PUSHI(0); PUSHI(0xD000); EMU_CALL(a_draw_sprite_at, 8206, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 820C, draw_win); PUSHI(0x12c); EMU_CALL(a_delay, 8213, draw_win); reg_sp += 2; // seg000:8215 PUSHI(0x14); PUSHI(0x2a); PUSHI(0x0f); PUSHI(5); EMU_CALL(a_draw_box2, 8228, draw_win); reg_sp += 8; EMU_CALL(a_fade_in, 822E, draw_win); PUSHI(aCommanderKeenRetur); EMU_CALL(a_draw_stringz2, 8235, draw_win); reg_sp += 2; PUSHI(aWithBaconMegarocke); EMU_CALL(a_draw_stringz2, 823E, draw_win); reg_sp += 2; PUSHI(aReplacesTheMissing); EMU_CALL(a_draw_stringz2, 8247, draw_win); reg_sp += 2; PUSHI(aGetHomeBeforeHisPa); EMU_CALL(a_draw_stringz2, 8250, draw_win); reg_sp += 2; PUSHI(81); EMU_CALL(a_load_level_data, 8259, draw_win); reg_sp += 2; PUSHI(0xf0); EMU_CALL(a_delay, 8262, draw_win); reg_sp += 2; EMU_CALL(a_fade_out, 8267, draw_win); // seg000:8267 W_MEMD(scroll_y_lo, 0); W_MEMD(scroll_x_lo, 0); EMU_CALL(a_clear_overlay, 827C, draw_win); EMU_CALL(a_sync_drawing, 827F, draw_win); EMU_CALL(a_draw_screen, 8282, draw_win); EMU_CALL(a_draw_screen, 8285, draw_win); EMU_CALL(a_fade_in, 8288, draw_win); // seg000:8288 reg_si = 0; W_MEMW(reg_bp - 4, 0x6400); W_MEMW(reg_bp - 2, 0); W_MEMW(reg_bp - 8, 0x5000); W_MEMW(reg_bp - 6, 0); do { // seg000:829E MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0x4c; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); reg_ax <<= 8; int tmp1 = (short)reg_ax; W_MEMD(reg_bp - 4, MEMD(reg_bp - 4) + tmp1); // seg000:82B6 MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0x4a; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); reg_ax <<= 8; tmp1 = (short)reg_ax; W_MEMD(reg_bp - 8, MEMD(reg_bp - 8) + tmp1); // seg000:82CC EMU_CALL(a_sync_drawing, 82CF, draw_win); PUSHI(0x73); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 82E2, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 82E8, draw_win); PUSHI(4); EMU_CALL(a_delay, 82EF, draw_win); reg_sp += 2; // seg000:82F1 MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0x4c; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); MOV(bx, si); reg_si++; reg_bx <<= 2; reg_dx = reg_bp - 0x4a; reg_bx += reg_dx; reg_ax += MEMW(reg_bx); // seg000:830C } while (reg_ax != 0); // seg000:8310 reg_si = 0; do { // seg000:8312 W_MEMD(reg_bp - 4, MEMD(reg_bp - 4) + 0x300); W_MEMD(reg_bp - 8, MEMD(reg_bp - 8) + 0x100); EMU_CALL(a_sync_drawing, 8327, draw_win); PUSHI(0x73); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 833A, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 8340, draw_win); // seg000:8340 MOV(ax, si); reg_si++; // seg000:8343 } while ((short)reg_ax < 0x14); // seg000:8348 reg_si = 0; do { // seg000:834A W_MEMD(scroll_x_lo, MEMD(scroll_x_lo) + 0x300); W_MEMD(scroll_y_lo, MEMD(scroll_y_lo) + 0x100); W_MEMD(reg_bp - 4, MEMD(reg_bp - 4) + 0x300); W_MEMD(reg_bp - 8, MEMD(reg_bp - 8) + 0x100); EMU_CALL(a_sync_drawing, 8375, draw_win); PUSHI(0x73); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 8388, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 838E, draw_win); // seg000:838E MOV(ax, si); reg_si++; } while ((short)reg_ax < 0xc8); // seg000:8396 reg_si = 0; do { // seg000:8398 W_MEMD(reg_bp - 8, MEMD(reg_bp - 8) + 0x100); // seg000:83A1 if ((short)reg_si < 0x14) { // seg000:83A6 W_MEMD(scroll_y_lo, MEMD(scroll_y_lo) + 0x300); } // seg000:83B1 EMU_CALL(a_sync_drawing, 83B4, draw_win); PUSHI(0x73); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 83C7, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 83CD, draw_win); // seg000:83CD MOV(ax, si); reg_si++; // seg000:83D0 } while ((short)reg_ax < 0x3c); // seg000:83D5 PUSHI(0x14); EMU_CALL(a_delay, 83DC, draw_win); reg_sp += 2; reg_si = 0; do { // seg000:83E0 EMU_CALL(a_sync_drawing, 83E3, draw_win); PUSHI(0x73); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 83F6, draw_win); reg_sp += 0xa; // seg000:83F9 PUSHI(0x76); int tmp1 = MEMD(reg_bp - 8); tmp1 += 0xfffff200; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp - 4); tmp1 += 0x600; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a_draw_sprite_at, 841E, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 8424, draw_win); // seg000:8424 MOV(ax, si); reg_si++; } while ((short)reg_ax < 0x1e); // seg000:842C reg_si = 0; do { // seg000:842E EMU_CALL(a_sync_drawing, 8431, draw_win); W_MEMD(reg_bp - 4, MEMD(reg_bp - 4) - 0x200); PUSHI(0x74); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 844D, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 8453, draw_win); // seg000:8453 MOV(ax, si); reg_si++; } while ((short)reg_ax < 0x32); // seg000:845B reg_si = 0; do { // seg000:845D EMU_CALL(a_sync_drawing, 8460, draw_win); PUSHI(0x74); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 8473, draw_win); reg_sp += 0xa; PUSHI(0x75); int tmp1 = MEMD(reg_bp - 8); tmp1 += 0xfffff200; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp - 4); tmp1 += 0x600; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a_draw_sprite_at, 849B, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 84A1, draw_win); // seg000:84A1 MOV(ax, si); reg_si++; } while ((short)reg_ax < 0x1e); // seg000:84A9 reg_si = 0; do { // seg000:84AB EMU_CALL(a_sync_drawing, 84AE, draw_win); MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0x198; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); reg_ax <<= 8; int tmp1 = (short)reg_ax; W_MEMD(reg_bp - 4, MEMD(reg_bp - 4) + tmp1); // seg000:84C7 MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0x196; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); reg_ax <<= 8; tmp1 = (short)reg_ax; W_MEMD(reg_bp - 8, MEMD(reg_bp - 8) + tmp1); // seg000:84DE PUSHI(0x73); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 84F1, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 84F7, draw_win); // seg000:84F7 MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0x198; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); MOV(bx, si); reg_si++; reg_bx <<= 2; reg_dx = reg_bp - 0x196; reg_bx += reg_dx; reg_ax += MEMW(reg_bx); } while (reg_ax != 0); // seg000:8516 PUSHI(0x3c); EMU_CALL(a_delay, 851D, draw_win); reg_sp += 2; EMU_CALL(a_fade_out, 8522, draw_win); // seg000:8522 int tmp1 = MEMD(scroll_x_lo); W_MEMD(reg_bp - 0xc, tmp1); tmp1 = MEMD(scroll_y_lo); W_MEMD(reg_bp - 0x10, tmp1); PUSHI(aFinale_ck1); EMU_CALL(a_show_image_file, 8543, draw_win); reg_sp += 2; PUSHI(0x13); PUSHI(0x1b); PUSHI(0xf); PUSHI(4); EMU_CALL(a_draw_box2, 8558, draw_win); reg_sp += 8; EMU_CALL(a_fade_in, 855E, draw_win); PUSHI(aKeenMakesItHomeAnd); EMU_CALL(a_draw_stringz2, 8565, draw_win); reg_sp += 2; PUSHI(aRushesToBeatHis); EMU_CALL(a_draw_stringz2, 856E, draw_win); reg_sp += 2; PUSHI(aParentsUpstairs_); EMU_CALL(a_draw_stringz2, 8577, draw_win); reg_sp += 2; PUSHI(0x78); EMU_CALL(a_delay, 8580, draw_win); reg_sp += 2; EMU_CALL(a_sub_8132, 8585, draw_win); PUSHI(0x3c); EMU_CALL(a_delay, 858C, draw_win); reg_sp += 2; PUSHI(0xc); PUSHI(0); PUSHI(0xe); EMU_CALL(a_draw_filter, 859C, draw_win); reg_sp += 6; PUSHI(0x19); EMU_CALL(a_set_cur_sound, 85A6, draw_win); reg_sp += 2; PUSHI(0x78); EMU_CALL(a_delay, 85AF, draw_win); reg_sp += 2; PUSHI(0xd); PUSHI(0); PUSHI(0xe); EMU_CALL(a_draw_filter, 85BF, draw_win); reg_sp += 6; PUSHI(0x19); EMU_CALL(a_set_cur_sound, 85C9, draw_win); reg_sp += 2; PUSHI(0x12c); EMU_CALL(a_delay, 85D2, draw_win); reg_sp += 2; PUSHI(0x13); PUSHI(0x1B); PUSHI(0x0f); PUSHI(4); EMU_CALL(a_draw_box2, 85E7, draw_win); reg_sp += 8; // seg000:85EA PUSHI(aShhhHoney___letS); EMU_CALL(a_draw_stringz2, 85F1, draw_win); reg_sp += 2; PUSHI(aSeeIfLittleBilly); EMU_CALL(a_draw_stringz2, 85FA, draw_win); reg_sp += 2; PUSHI(aIsAsleep_); EMU_CALL(a_draw_stringz2, 8603, draw_win); reg_sp += 2; PUSHI(0xb4); EMU_CALL(a_delay, 860C, draw_win); reg_sp += 2; EMU_CALL(a_sub_8132, 8611, draw_win); PUSHI(0x3c); EMU_CALL(a_delay, 8618, draw_win); reg_sp += 2; PUSHI(0xc); PUSHI(0); PUSHI(0xe); EMU_CALL(a_draw_filter, 8628, draw_win); reg_sp += 6; PUSHI(0x19); EMU_CALL(a_set_cur_sound, 8632, draw_win); reg_sp += 2; PUSHI(0x14); PUSHI(0x1b); PUSHI(0xf); PUSHI(4); EMU_CALL(a_draw_box2, 8647, draw_win); reg_sp += 8; PUSHI(aBilly____AreYouA); EMU_CALL(a_draw_stringz2, 8651, draw_win); reg_sp += 2; PUSHI(aWhatIsThisOneEyed); EMU_CALL(a_draw_string, 865A, draw_win); reg_sp += 2; PUSHI(aGreenThingInYour); EMU_CALL(a_draw_string, 8663, draw_win); reg_sp += 2; PUSHI(aRoom___); EMU_CALL(a_draw_string, 866C, draw_win); reg_sp += 2; PUSHI(0xf0); EMU_CALL(a_delay, 8675, draw_win); reg_sp += 2; EMU_CALL(a_sub_8132, 867A, draw_win); PUSHI(0x12); PUSHI(0x1b); PUSHI(0xf); PUSHI(4); EMU_CALL(a_draw_box2, 868D, draw_win); reg_sp += 8; // seg000:8690 PUSHI(aAwMomCanTI); EMU_CALL(a_draw_stringz2, 8697, draw_win); reg_sp += 2; PUSHI(aKeepHim_); EMU_CALL(a_draw_stringz2, 86A0, draw_win); reg_sp += 2; PUSHI(0xb4); EMU_CALL(a_delay, 86A9, draw_win); reg_sp += 2; EMU_CALL(a_sub_8132, 86AE, draw_win); PUSHI(0x13); PUSHI(0x1d); PUSHI(0xf); PUSHI(4); EMU_CALL(a_draw_box2, 86C1, draw_win); reg_sp += 8; // seg000:86C4 PUSHI(aWellWeLlTalkAbout); EMU_CALL(a_draw_stringz2, 86CB, draw_win); reg_sp += 2; PUSHI(aThatInTheMorning); EMU_CALL(a_draw_stringz2, 86D4, draw_win); reg_sp += 2; PUSHI(aSon_YouGetSomeRest); EMU_CALL(a_draw_stringz2, 86DD, draw_win); reg_sp += 2; PUSHI(0xb4); EMU_CALL(a_delay, 86E6, draw_win); reg_sp += 2; EMU_CALL(a_sub_8132, 86EB, draw_win); PUSHI(0x11); PUSHI(0x1b); PUSHI(0xf); PUSHI(4); EMU_CALL(a_draw_box2, 86FE, draw_win); reg_sp += 8; // seg000:8701 PUSHI(aOkMom_Goodnight_); EMU_CALL(a_draw_stringz2, 8708, draw_win); reg_sp += 2; PUSHI(0xb4); EMU_CALL(a_delay, 8711, draw_win); reg_sp += 2; PUSHI(0x11); PUSHI(0x1b); PUSHI(0xf); PUSHI(4); EMU_CALL(a_draw_box2, 8726, draw_win); reg_sp += 8; // seg000:8729 PUSHI(aGoodnightDear_); EMU_CALL(a_draw_stringz2, 8730, draw_win); reg_sp += 2; PUSHI(0xb4); EMU_CALL(a_delay, 8739, draw_win); reg_sp += 2; EMU_CALL(a_sub_8132, 873E, draw_win); PUSHI(0x3c); EMU_CALL(a_delay, 8745, draw_win); reg_sp += 2; PUSHI(0xd); PUSHI(0); PUSHI(0xe); EMU_CALL(a_draw_filter, 8755, draw_win); reg_sp += 6; PUSHI(0x19); EMU_CALL(a_set_cur_sound, 875F, draw_win); reg_sp += 2; PUSHI(0x12c); EMU_CALL(a_delay, 8768, draw_win); reg_sp += 2; PUSHI(0xc); PUSHI(0); PUSHI(0xe); EMU_CALL(a_draw_filter, 8778, draw_win); reg_sp += 6; PUSHI(0x15); PUSHI(0x1d); PUSHI(0xf); PUSHI(4); EMU_CALL(a_draw_box2, 878E, draw_win); reg_sp += 8; PUSHI(0x19); EMU_CALL(a_set_cur_sound, 8798, draw_win); reg_sp += 2; // seg000:879A PUSHI(aButThereIsNoSleep); EMU_CALL(a_draw_stringz2, 87A1, draw_win); reg_sp += 2; PUSHI(aForCommanderKeenTh); EMU_CALL(a_draw_stringz2, 87AA, draw_win); reg_sp += 2; PUSHI(aVorticonMothership); EMU_CALL(a_draw_stringz2, 87B3, draw_win); reg_sp += 2; PUSHI(aLoomsAboveReadyTo); EMU_CALL(a_draw_stringz2, 87BC, draw_win); reg_sp += 2; PUSHI(aDestroyEarth); EMU_CALL(a_draw_stringz2, 87C5, draw_win); reg_sp += 2; PUSHI(0x12c); EMU_CALL(a_delay, 87CE, draw_win); reg_sp += 2; EMU_CALL(a_fade_out, 87D3, draw_win); PUSHI(81); EMU_CALL(a_load_level_data, 87DA, draw_win); reg_sp += 2; // seg000:87DC tmp1 = MEMD(reg_bp - 0xc); W_MEMD(scroll_x_lo, tmp1); tmp1 = MEMD(reg_bp - 0x10); W_MEMD(scroll_y_lo, tmp1); EMU_CALL(a_clear_overlay, 87F9, draw_win); EMU_CALL(a_sync_drawing, 87FC, draw_win); PUSHI(0x74); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 880F, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 8815, draw_win); EMU_CALL(a_fade_in, 8818, draw_win); PUSHI(0x1e); EMU_CALL(a_delay, 881F, draw_win); reg_sp += 2; reg_si = 0; do { // seg000:8823 EMU_CALL(a_sync_drawing, 8826, draw_win); MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0xf8; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); reg_ax <<= 8; tmp1 = (short)reg_ax; W_MEMD(reg_bp - 4, MEMD(reg_bp - 4) + tmp1); MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0xf6; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); reg_ax <<= 8; tmp1 = (short)reg_ax; W_MEMD(reg_bp - 8, MEMD(reg_bp - 8) + tmp1); PUSHI(0x74); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 8869, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 886F, draw_win); // seg000:886F MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0xf8; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); MOV(bx, si); reg_si++; reg_bx <<= 2; reg_dx = reg_bp - 0xf6; reg_bx += reg_dx; reg_ax += MEMW(reg_bx); } while (reg_ax != 0); // seg000:888E EMU_CALL(a_sync_drawing, 8891, draw_win); PUSHI(0x73); PUSHI(MEMW(reg_bp - 6)); PUSHI(MEMW(reg_bp - 8)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_draw_sprite_at, 88A4, draw_win); reg_sp += 0xa; EMU_CALL(a_draw_screen, 88AA, draw_win); PUSHI(0x3c); EMU_CALL(a_delay, 88B1, draw_win); reg_sp += 2; PUSHI(5); PUSHI(0x20); PUSHI(3); PUSHI(0xc); EMU_CALL(a_draw_box2, 88C6, draw_win); reg_sp += 8; // seg000:88C9 PUSHI(aToBeContinued____); EMU_CALL(a_draw_stringz2, 88D0, draw_win); reg_sp += 2; PUSHI(0x190); EMU_CALL(a_delay, 88D9, draw_win); reg_sp += 2; // seg000:88DB tmp1 = MEMD(scroll_x_lo); tmp1 &= 0xfffff000; W_MEMD(scroll_x_lo, tmp1); EMU_CALL(a_draw_screen, 88F3, draw_win); EMU_CALL(a_draw_screen, 88F6, draw_win); PUSHI(0x29); EMU_CALL(a_set_cur_sound, 88FD, draw_win); reg_sp += 2; PUSHI(0x16); PUSHI(0); PUSHI(MEMW(end_text + 2)); PUSHI(MEMW(end_text)); EMU_CALL(a_do_text_viewer, 8911, draw_win); reg_sp += 8; POP(si); MOV(sp, bp); POP(bp); RET; } // 9AB4 void save_game() { RETLOC(9C49); RETLOC(9C44); RETLOC(9C3B); RETLOC(9C32); RETLOC(9C28); RETLOC(9C1A); RETLOC(9BA4); RETLOC(9B9D); RETLOC(9B98); RETLOC(9B8B); RETLOC(9B86); RETLOC(9B7C); RETLOC(9B6A); RETLOC(9B40); RETLOC(9B3B); RETLOC(9B32); RETLOC(9B29); RETLOC(9B1F); RETLOC(9B11); RETLOC(9B0E); RETLOC(9B09); RETLOC(9B00); RETLOC(9AF7); RETLOC(9AED); RETLOC(9AD8); RETLOC(9ACD); assert(reg_eip == 0x9ab4); PUSH(bp); MOV(bp, sp); reg_sp -= 0x10; PUSH(si); reg_si = 0; PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x10; PUSH(ax); PUSHI(SegValue(ds)); PUSHI(aSaved__); reg_cx = 0xd; EMU_CALL(a_N_SCOPY, 9ACD, save_game); PUSHI(MEMW(pExt)); reg_ax = reg_bp - 0x10; PUSH(ax); EMU_CALL(a__strcat, 9AD8, save_game); reg_sp += 4; // seg000:9ADB if (MEMW(on_world_map) == 0) { // seg000:9AE2 PUSHI(3); PUSHI(0x16); EMU_CALL(a_draw_box_opening2, 9AED, save_game); reg_sp += 4; PUSHI(aYouCanSaveTheGame); EMU_CALL(a_draw_string, 9AF7, save_game); reg_sp += 2; PUSHI(aOnlyOnTheWorldMap); EMU_CALL(a_draw_string, 9B00, save_game); reg_sp += 2; PUSHI(aPressAKey); EMU_CALL(a_draw_string, 9B09, save_game); reg_sp += 2; EMU_CALL(a_clear_keys, 9B0E, save_game); EMU_CALL(a_wait_for_key, 9B11, save_game); } else { do { // seg000:9B14 PUSHI(3); PUSHI(0x14); EMU_CALL(a_draw_box_opening2, 9B1F, save_game); reg_sp += 4; PUSHI(aWhichGamePosition); EMU_CALL(a_draw_string, 9B29, save_game); reg_sp += 2; PUSHI(aDoYouWantToSave_); EMU_CALL(a_draw_string, 9B32, save_game); reg_sp += 2; PUSHI(a19OrEsc); EMU_CALL(a_draw_string, 9B3B, save_game); reg_sp += 2; while(1) { // seg000:9B3D EMU_CALL(a_read_char_with_echo, 9B40, save_game); reg_al &= 0xff; W_MEMB(reg_bp - 1, reg_al); // seg000:9B45 if (reg_al == 0x1b) break; // seg000:9B49 if ((char)reg_al >= '1' && (char)reg_al <= '9') break; } // seg000:9B51 if (MEMB(reg_bp - 1) == 0x1b) { // seg000:9C49 POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:9B5A reg_al = MEMB(reg_bp - 1); W_MEMB(reg_bp - 0xb, reg_al); PUSHI(0); reg_ax = reg_bp - 0x10; PUSH(ax); EMU_CALL(a_sub_C552, 9B6A, save_game); reg_sp += 4; // seg000:9B6D if (reg_ax == 0) { // seg000:9B71 PUSHI(3); PUSHI(0x14); EMU_CALL(a_draw_box_opening2, 9B7C, save_game); reg_sp += 4; PUSHI(aThatGamePosition); EMU_CALL(a_draw_string, 9B86, save_game); reg_sp += 2; PUSHI(aAlreadyExists); EMU_CALL(a_draw_string, 9B8B, save_game); reg_sp += 2; PUSHI(aOverwriteIt_); EMU_CALL(a_draw_string, 9B98, save_game); reg_sp += 2; // seg000:9B9A while (1) { EMU_CALL(a_read_char_with_echo, 9B9D, save_game); reg_ax &= 0xff; PUSH(ax); EMU_CALL(a_sub_CD36, 9BA4, save_game); reg_sp += 2; W_MEMB(reg_bp - 1, reg_al); // seg000:9BA9 if (reg_al == 0x1b) break; // seg000:9BAD if (reg_al == 'Y') break; // seg000:9BB1 if (reg_al == 'N') break; } // seg000:9BB5 if (MEMB(reg_bp - 1) == 0x1b) { // seg000:9C49 POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:9BBE if (MEMB(reg_bp - 1) == 'Y') { // seg000:9BC4 reg_si++; } } else { // seg000:9BC7 reg_si++; } // seg000:9BC8 } while (reg_si == 0); // seg000:9BCF int tmp1 = MEMD(dword_1D752); W_MEMD(dword_1DB26, tmp1); tmp1 = MEMD(dword_1D756); W_MEMD(dword_1DB2A, tmp1); tmp1 = MEMD(dword_1D74A); W_MEMD(dword_1DB1E, tmp1); tmp1 = MEMD(dword_1D74E); W_MEMD(dword_1DB22, tmp1); // seg000:9C07 PUSHI(0); PUSHI(0x5c); PUSHI(SegValue(ds)); PUSHI(got_part_1); PUSHI(reg_bp - 0x10); EMU_CALL(a_write_file, 9C1A, save_game); reg_sp += 0x0a; // seg000:9C1D PUSHI(3); PUSHI(0x1d); EMU_CALL(a_draw_box_opening2, 9C28, save_game); reg_sp += 4; // seg000:9C2B PUSHI(aYouCanContinueThis); EMU_CALL(a_draw_string, 9C32, save_game); reg_sp += 2; // seg000:9C34 PUSHI(aFromTheMainMenuNex); EMU_CALL(a_draw_string, 9C3B, save_game); reg_sp += 2; // seg000:9C3D PUSHI(aYouPlay_PressAKey); EMU_CALL(a_draw_string, 9C44, save_game); reg_sp += 2; EMU_CALL(a_read_char_with_echo, 9C49, save_game); } // seg000:9C49 POP(si); MOV(sp, bp); POP(bp); RET; } // AA95 void move_worldmap() { RETLOC(AC6B); RETLOC(AC2C); RETLOC(AAA4); RETLOC(ADF9); RETLOC(ADE1); assert(reg_eip == 0xaa95); PUSH(bp); MOV(bp, sp); reg_sp -= 0x14; PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 10); PUSH(si); EMU_CALL(a_detect_worldmap_col, AAA4, move_worldmap); reg_sp += 2; // seg000:AAA6 if (MEMW(reg_bp + 6) != 0 || MEMW(reg_bp + 8) != 0) { // seg000:AAB5 int tmp1 = MEMD(reg_si + 0xc); tmp1 /= 0x1000; W_MEMW(reg_bp - 4, tmp1 & 0xffff); tmp1 = MEMD(reg_si + 0x14); tmp1 /= 0x1000; W_MEMW(reg_bp - 8, tmp1 & 0xffff); tmp1 = MEMD(reg_si + 0x10); tmp1 /= 0x1000; W_MEMW(reg_bp - 6, tmp1 & 0xffff); tmp1 = MEMD(reg_si + 0x18); tmp1 /= 0x1000; W_MEMW(reg_bp - 0xa, tmp1 & 0xffff); reg_ax = MEMW(reg_bp - 4); W_MEMW(reg_bp - 2, reg_ax); // seg000:AB59 while ((short)MEMW(reg_bp - 2) <= (short)MEMW(reg_bp - 8)) { // seg000:AB09 reg_di = MEMW(reg_bp - 6); // seg000:AB51 while ((short)reg_di <= (short)MEMW(reg_bp - 0xa)) { // seg000:AB0E MOV(ax, di); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; if (mem_readw(SegPhys(es) + reg_bx) != 0) { // seg000:AB25 reg_ax = MEMW(reg_bp - 2); W_MEMW(reg_bp - 0xc, reg_ax); W_MEMW(reg_bp - 0xe, reg_di); MOV(ax, di); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(cur_level, reg_ax); // seg000:AB45 if (reg_ax == 0xff) { // seg000:AB4A W_MEMW(cur_level, 0); } } // seg000:AB50 reg_di++; } // seg000:AB56 W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) + 1); } } // seg000:AB61 W_MEMW(reg_si + 0x1e, 0); W_MEMW(reg_si + 0x1c, 0); reg_bx = MEMW(reg_bp + 4); if (reg_bx <= 7) { // seg000:AB71 switch(reg_bx) { case 0: // seg000:AB89 W_MEMW(reg_si + 0x1e, 0xfc00); W_MEMW(reg_si + 0x28, 0x2c); break; case 1: // seg000:AB95 W_MEMW(reg_si + 0x1e, 0xfc00); W_MEMW(reg_si + 0x1c, 0x400); W_MEMW(reg_si + 0x28, 0x2c); break; case 2: // seg000:ABA6 W_MEMW(reg_si + 0x1c, 0x400); W_MEMW(reg_si + 0x28, 0x20); break; case 3: // seg000:ABB2 W_MEMW(reg_si + 0x1e, 0x400); W_MEMW(reg_si + 0x1c, 0x400); W_MEMW(reg_si + 0x28, 0x24); break; case 4: // seg000:ABC3 W_MEMW(reg_si + 0x1e, 0x400); W_MEMW(reg_si + 0x28, 0x24); break; case 5: // seg000:ABCF W_MEMW(reg_si + 0x1e, 0x400); W_MEMW(reg_si + 0x1c, 0xfc00); W_MEMW(reg_si + 0x28, 0x24); break; case 6: // seg000:ABE0 W_MEMW(reg_si + 0x1c, 0xfc00); W_MEMW(reg_si + 0x28, 0x28); break; case 7: // seg000:AB78 W_MEMW(reg_si + 0x1e, 0xfc00); W_MEMW(reg_si + 0x1c, 0xfc00); W_MEMW(reg_si + 0x28, 0x2c); break; } } // seg000:ABEA W_MEMW(reg_bp - 0x10, 0); reg_ax = MEMW(reg_si + 0x1c); if (reg_ax != MEMW(reg_si + 0x1e)) { // seg000:ABF7 reg_ax = MEMW(tick_count); reg_ax >>= 4; reg_ax &= 3; W_MEMW(reg_bp - 0x12, reg_ax); W_MEMW(reg_bp - 0x10, MEMW(reg_bp - 0x10) + 1); } else { // seg000:AC09 W_MEMW(reg_bp - 0x12, 0); } // seg000:AC0E W_MEMW(word_1D738, 0x8000); // seg000:AC14 if (MEMB(byte_1808B) != 0 && MEMB(byte_180A6) != 0) { // seg000:AC22 W_MEMW(word_1D738, 0); } // seg000:AC28 PUSH(si); EMU_CALL(a_check_world_map_col, AC2C, move_worldmap); reg_sp += 2; W_MEMW(reg_bp - 0x14, reg_ax); // seg000:AC31 int tmp1 = (short)MEMW(reg_si + 0x1c); W_MEMD(reg_si + 4, MEMD(reg_si + 4) + tmp1); // seg000:AC3B tmp1 = (short)MEMW(reg_si + 0x1e); W_MEMD(reg_si + 8, MEMD(reg_si + 8) + tmp1); // seg000:AC45 if (MEMW(reg_bp - 0x10) != 0) { // seg000:AC4B reg_ax = MEMW(tick_count); reg_ax >>= 3; // seg000:AC54 if ((reg_ax & 3) == 0) { // seg000:AC59 if (MEMW(reg_bp - 0x14) != 0) { // seg000:AC5F reg_ax = 2; } else { // seg000:AC64 reg_ax = 1; } // seg000:AC67 PUSH(ax); EMU_CALL(a_set_cur_sound, AC6B, move_worldmap); reg_sp += 2; } } // seg000:AC6D if ((short)MEMW(reg_si + 0x1c) > 0 && (int)MEMD(reg_si + 4) - (int)MEMD(scroll_x_lo) > 0xb000) { // seg000:AC8D tmp1 = (short)MEMW(reg_si + 0x1c); W_MEMD(scroll_x_lo, MEMD(scroll_x_lo) + tmp1); // seg000:AC99 if ((int)MEMD(scroll_x_lo) > (int)MEMD(dword_1B00E)) { // seg000:ACAE W_MEMD(scroll_x_lo, MEMD(dword_1B00E)); } } else if ((short)MEMW(reg_si + 0x1c) < 0) { // seg000:ACC4 tmp1 = MEMD(reg_si + 4); tmp1 -= MEMD(scroll_x_lo); // seg000:ACD2 if (tmp1 < 0x9000) { // seg000:ACDE tmp1 = (short)MEMW(reg_si + 0x1c); W_MEMD(scroll_x_lo, MEMD(scroll_x_lo) + tmp1); // seg000:ACEA if ((int)MEMD(scroll_x_lo) < (int)MEMD(dword_1869A)) { // seg000:ACFF W_MEMD(scroll_x_lo, MEMD(dword_1869A)); } } } // seg000:AD0D if ((short)MEMW(reg_si + 0x1e) > 0 && (int)MEMD(reg_si + 8) - (int)MEMD(scroll_y_lo) > 0x7000) { // seg000:AD2D W_MEMD(scroll_y_lo, MEMD(scroll_y_lo) + (short)MEMW(reg_si + 0x1e)); // seg000:AD39 if ((int)MEMD(scroll_y_lo) > (int)MEMD(dword_1B012)) { // seg000:AD4E W_MEMD(scroll_y_lo, MEMD(dword_1B012)); } } else if ((short)MEMW(reg_si + 0x1e) < 0) { // seg000:AD64 tmp1 = MEMD(reg_si + 8); tmp1 -= MEMD(scroll_y_lo); if (tmp1 < 0x3000) { // seg000:AD7E W_MEMD(scroll_y_lo, MEMD(scroll_y_lo) + (short)MEMW(reg_si + 0x1e)); // seg000:AD8A if ((int)MEMD(scroll_y_lo) < (int)MEMD(dword_1869E)) { // seg000:AD9F W_MEMD(scroll_y_lo, MEMD(dword_1869E)); } } } // seg000:ADAD tmp1 = MEMD(scroll_x_lo); tmp1 >>= 0xc; W_MEMW(word_186A6, tmp1 & 0xffff); // seg000:ADBC tmp1 = MEMD(scroll_y_lo); tmp1 >>= 0xc; W_MEMW(word_18B62, tmp1 & 0xffff); // seg000:ADCB reg_ax = MEMW(reg_si + 0x28); reg_ax += MEMW(reg_bp - 0x12); PUSH(ax); PUSHI(MEMW(reg_si + 0xa)); PUSHI(MEMW(reg_si + 8)); PUSHI(MEMW(reg_si + 6)); PUSHI(MEMW(reg_si + 4)); EMU_CALL(a_draw_sprite_at, ADE1, move_worldmap); reg_sp += 0xa; // seg000:ADE4 if (MEMW(cur_level) != 0) { // seg000:ADEB PUSHI(MEMW(reg_bp - 0xe)); PUSHI(MEMW(reg_bp - 0xc)); PUSH(si); PUSHI(MEMW(cur_level)); EMU_CALL(a_draw_game, ADF9, move_worldmap); reg_sp += 8; // seg000:ADFC if (reg_ax != 0) { // seg000:AE00 W_MEMW(cur_level, 0); } } // seg000:AE06 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // AE1C void draw_game() { RETLOC(AF13); RETLOC(AF10); RETLOC(AF0B); RETLOC(AF01); RETLOC(AEDC); RETLOC(AEB7); RETLOC(AF92); RETLOC(AE6E); RETLOC(AE57); RETLOC(AE4E); RETLOC(AE45); RETLOC(AE3B); RETLOC(AFB8); RETLOC(AF7E); RETLOC(AF7B); RETLOC(AF72); RETLOC(B163); RETLOC(B160); RETLOC(B15D); RETLOC(B157); RETLOC(B145); RETLOC(B137); RETLOC(B126); RETLOC(B0EA); RETLOC(B0B0); RETLOC(B0AD); assert(reg_eip == 0xae1c); PUSH(bp); MOV(bp, sp); reg_sp -= 0x18; PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 6); // seg000:AE27 if (MEMW(reg_bp + 4) == 0x14) { // seg000:AE30 PUSHI(8); PUSHI(0x14); EMU_CALL(a_draw_box_opening2, AE3B, draw_game); reg_sp += 4; PUSHI(aYourShipIsMissingT); EMU_CALL(a_draw_string, AE45, draw_game); reg_sp += 2; PUSHI(aGoGetThem); EMU_CALL(a_draw_string, AE4E, draw_game); reg_sp += 2; PUSHI(aPressA); EMU_CALL(a_draw_string, AE57, draw_game); reg_sp += 2; reg_ax = MEMW(ctrl_type); // seg000:AE5C if (reg_ax == 0) { // seg000:AE62 reg_ax = aKey; } else { // seg000:AE67 reg_ax = aButton; } // seg000:AE6A PUSH(ax); EMU_CALL(a_draw_string, AE6E, draw_game); reg_sp += 2; // seg000:AE70 if (MEMW(got_part_1) == 0) { // seg000:AE77 PUSHI(0x141); reg_ax = MEMW(word_1B348); reg_ax += 0xfffc; reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B3A4); reg_ax += 3; PUSH(ax); EMU_CALL(a_do_overdraw, AF92, draw_game); reg_sp += 6; } // seg000:AE95 if (MEMW(got_part_2) == 0) { // seg000:AE9C PUSHI(0x142); reg_ax = MEMW(word_1B348); reg_ax += 0xfffc; reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B3A4); reg_ax += 7; PUSH(ax); EMU_CALL(a_do_overdraw, AEB7, draw_game); reg_sp += 6; } // seg000:AEBA if (MEMW(got_part_3) == 0) { // seg000:AEC1 PUSHI(0x143); reg_ax = MEMW(word_1B348); reg_ax += 0xfffc; reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B3A4); reg_ax += 0xb; PUSH(ax); EMU_CALL(a_do_overdraw, AEDC, draw_game); reg_sp += 6; } // seg000:AEDF if (MEMW(got_part_4) == 0) { // seg000:AEC1 PUSHI(0x144); reg_ax = MEMW(word_1B348); reg_ax += 0xfffc; reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B3A4); reg_ax += 0xf; PUSH(ax); EMU_CALL(a_do_overdraw, AF01, draw_game); reg_sp += 6; } // seg000:AF04 PUSHI(0xf); EMU_CALL(a_delay, AF0B, draw_game); reg_sp += 2; EMU_CALL(a_wait_for_key, AF10, draw_game); EMU_CALL(a_clear_overlay, AF13, draw_game); reg_ax = 1; } else { // seg000:AF19 reg_di = 0; // seg000:B175 while ((short)reg_di < 3) { // seg000:AF1E reg_ax = MEMW(reg_bp + 4); reg_ax &= 0x20; // seg000:AF24 if (reg_ax == 0x20) { // seg000:AF2C reg_ax = MEMW(reg_bp + 4); reg_ax &= 3; reg_ax--; W_MEMW(reg_bp - 8, reg_ax); reg_ax = MEMW(reg_bp + 4); reg_ax = ((short)reg_ax) >> 2; reg_ax &= 3; reg_ax--; W_MEMW(reg_bp - 0xa, reg_ax); // seg000:AF44 reg_ax = MEMW(reg_bp + 8); W_MEMW(reg_bp - 0x10, reg_ax); reg_ax = MEMW(reg_bp + 10); W_MEMW(reg_bp - 0x12, reg_ax); W_MEMW(reg_bp - 0xe, 0x152); reg_ax = MEMW(reg_bp - 0xa); reg_dx = 0xa; reg_ax *= reg_dx; MOV(bx, ax); // seg000:AF5F if (MEMW(word_158E6 + reg_bx) != 0) { // seg000:AF66 W_MEMW(reg_bp - 0xe, 0x156); } // seg000:AF6B PUSHI(0x12); EMU_CALL(a_set_cur_sound, AF72, draw_game); reg_sp += 2; reg_di = 0; // seg000:AFB9 while ((short)reg_di < 0x10) { // seg000:AF78 EMU_CALL(a_sync_drawing, AF7B, draw_game); EMU_CALL(a_clear_overlay, AF7E, draw_game); MOV(ax, di); reg_dx = reg_ax % 2; // seg000:AF86 if (reg_dx == 0) { // seg000:AF8A W_MEMW(reg_bp - 0xc, MEMW(reg_bp - 0xc) + 1); reg_ax = MEMW(reg_bp - 0xc); // seg000:AF90 if ((short)reg_ax > 3) { // seg000:AF95 W_MEMW(reg_bp - 0xc, 0); } } // seg000:AF9A reg_ax = MEMW(reg_bp - 0x12); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 0x10); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = MEMW(reg_bp - 0xc); reg_ax += MEMW(reg_bp - 0xe); mem_writew(SegPhys(es) + reg_bx, reg_ax); EMU_CALL(a_draw_screen, AFB8, draw_game); reg_di++; } // seg000:AFBE W_MEMW(reg_bp - 0xe, 0x145); reg_ax = MEMW(reg_bp - 0xa); reg_ax *= 10; MOV(bx, ax); // seg000:AFCD if (MEMW(word_158E6 + reg_bx) != 0) { // seg000:AFD4 W_MEMW(reg_bp - 0xe, 0x63); } // seg000:AFD9 reg_ax = MEMW(reg_bp - 0x12); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 0x10); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = MEMW(reg_bp - 0xe); mem_writew(SegPhys(es) + reg_bx, reg_ax); reg_ax = MEMW(reg_bp - 8); reg_ax *= 10; MOV(bx,ax); int tmp1 = MEMD(dword_158DE + reg_bx); W_MEMD(dword_1D74A, tmp1); W_MEMD(dword_1DB44, tmp1); W_MEMD(reg_si + 4, tmp1); // seg000:B017 reg_ax = MEMW(reg_bp - 8); reg_ax *= 10; MOV(bx,ax); tmp1 = MEMD(dword_158E2 + reg_bx); W_MEMD(dword_1D74E, tmp1); W_MEMD(dword_1DB48, tmp1); W_MEMD(reg_si + 8, tmp1); tmp1 = MEMD(reg_si + 4); tmp1 += 0xffff7000; W_MEMD(scroll_x_lo, tmp1); tmp1 = MEMD(reg_si + 8); tmp1 += 0xffffd000; W_MEMD(scroll_y_lo, tmp1); // seg000:B065 tmp1 = MEMD(reg_si + 4); tmp1 /= 0x1000; W_MEMW(reg_bp - 0x10, tmp1 & 0xffff); // seg000:B078 tmp1 = MEMD(reg_si + 8); tmp1 /= 0x1000; W_MEMW(reg_bp - 0x12, tmp1 & 0xffff); // seg000:B08B W_MEMW(reg_bp - 0xe, 0x152); reg_ax = MEMW(reg_bp - 8); reg_ax *= 10; MOV(bx, ax); // seg000:B09A if (MEMW(word_158E6 + reg_bx) != 0) { // seg000:B0A1 W_MEMW(reg_bp - 0xe, 0x156); } // seg000:B0A6 reg_di = 0; // seg000:B0EB while ((short)reg_di < 0x10) { // seg000:B0AA EMU_CALL(a_sync_drawing, B0AD, draw_game); EMU_CALL(a_clear_overlay, B0B0, draw_game); MOV(ax, di); reg_dx = reg_ax % 2; // seg000:B0B8 if (reg_dx == 0) { // seg000:B0BC W_MEMW(reg_bp - 0xc, MEMW(reg_bp - 0xc) + 1); reg_ax = MEMW(reg_bp - 0xc); // seg000:B0C2 if ((short)reg_ax > 3) { // seg000:B0C7 W_MEMW(reg_bp - 0xc, 0); } } // seg000:B0CC reg_ax = MEMW(reg_bp - 0x12); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 0x10); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = MEMW(reg_bp - 0xc); reg_ax += MEMW(reg_bp - 0xe); mem_writew(SegPhys(es) + reg_bx, reg_ax); EMU_CALL(a_draw_screen, B0EA, draw_game); reg_di++; } // seg000:B0F0 W_MEMW(reg_bp - 0xe, 0x145); reg_ax = MEMW(reg_bp - 8); reg_ax *= 10; MOV(bx, ax); // seg000:B0FF if (MEMW(word_158E6 + reg_bx) != 0) { // seg000:B106 W_MEMW(reg_bp - 0xe, 0x63); } // seg000:B10B reg_ax = MEMW(reg_bp - 0x12); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 0x10); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = MEMW(reg_bp - 0xe); mem_writew(SegPhys(es) + reg_bx, reg_ax); do { // seg000:B123 EMU_CALL(a_sync_drawing, B126, draw_game); reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x18; PUSH(ax); EMU_CALL(a_handle_ctrl, B137, draw_game); reg_sp += 6; // seg000:B13A reg_ax = reg_bp - 0x18; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, B145, draw_game); PUSHI(MEMW(reg_si + 0x28)); PUSHI(MEMW(reg_si + 0x0a)); PUSHI(MEMW(reg_si + 0x8)); PUSHI(MEMW(reg_si + 0x6)); PUSHI(MEMW(reg_si + 0x4)); EMU_CALL(a_draw_sprite_at, B157, draw_game); reg_sp += 10; EMU_CALL(a_draw_screen, B15D, draw_game); EMU_CALL(a_handle_cheat_keys, B160, draw_game); EMU_CALL(a_handle_global_keys, B163, draw_game); // seg000:B163 } while (MEMW(reg_bp - 4) != 0 || MEMW(reg_bp - 2) != 0); // seg000:B16F reg_ax = 1; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:B174 reg_di++; } // seg000:B17D reg_ax = 0; } // seg000:B17F POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // B185 void wait_for_key() { RETLOC(B23D); RETLOC(B232); RETLOC(B224); RETLOC(B1EE); RETLOC(B1DB); RETLOC(B1CD); RETLOC(B1BA); RETLOC(B1AC); assert(reg_eip == 0xb185); PUSH(bp); MOV(bp, sp); reg_sp -= 0x14; PUSH(si); PUSH(di); // seg000:B18D W_MEMW(reg_bp - 8, 0); reg_di = 0; do { // seg000:B194 reg_ax = MEMW(reg_bp - 8); reg_ax += 9; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(word_1B2D2); EMU_CALL(a_draw_char, B1AC, wait_for_key); reg_sp += 6; reg_si = 0; // seg000:B1F8 while ((short)reg_si < 6) { // seg000:B1B3 PUSHI(1); EMU_CALL(a_delay, B1BA, wait_for_key); reg_sp += 2; reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x14; PUSH(ax); EMU_CALL(a_handle_ctrl, B1CD, wait_for_key); reg_sp += 6; // seg000:B1D0 reg_ax = reg_bp - 0x14; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, B1DB, wait_for_key); // seg000:B1DB if (MEMW(reg_bp - 4) == 0 && MEMW(reg_bp - 2) == 0) { // seg000:B1E7 PUSHI(1); EMU_CALL(a_translate_key, B1EE, wait_for_key); reg_sp += 2; // seg000:B1F0 if (reg_ax == 0) { // seg000:B1F7 reg_si++; continue; } } // seg000:B1F4 reg_di++; break; } // seg000:B1FD W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) + 1); reg_ax = MEMW(reg_bp - 8); if (reg_ax > 4) { // seg000:B208 W_MEMW(reg_bp - 8, 0); } // seg000:B20D } while (reg_di == 0); do { // seg000:B213 reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0xe; PUSH(ax); EMU_CALL(a_handle_ctrl, B224, wait_for_key); reg_sp += 6; // seg000:B227 reg_ax = reg_bp - 0xe; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, B232, wait_for_key); reg_ax = MEMW(reg_bp - 4); // seg000:B235 } while (reg_ax != MEMW(reg_bp - 2)); // seg000:B23A EMU_CALL(a_clear_keys, B23D, wait_for_key); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // B8E0 void draw_char() { RETLOC(B931); RETLOC(B8FE); RETLOC(B8F7); assert(reg_eip == 0xB8E0); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); SegSet16(es, MEMW(dstseg)); reg_di = MEMW(reg_bp + 4); reg_bx = MEMW(reg_bp + 6); reg_bx <<= 1; reg_di += MEMW(word_1685C + reg_bx); EMU_INSTR(B8F5, B8F7, draw_char); reg_dx = 0x3ce; reg_ax = 0x105; EMU_INSTR(B8FD, B8FE, draw_char); reg_si = MEMW(reg_bp + 8); reg_si <<= 3; MOV(bx, si); MOV(cx, di); reg_ax = MEMW(EGAHEAD_font_seg); SegSet16(ds, reg_ax); mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; reg_di += 0x2f; // seg000:B914 mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; reg_di += 0x2f; // seg000:B918 mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; reg_di += 0x2f; // seg000:B91C mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; reg_di += 0x2f; // seg000:B920 mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; reg_di += 0x2f; // seg000:B924 mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; reg_di += 0x2f; // seg000:B928 mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; reg_di += 0x2f; // seg000:B92C mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; reg_di += 0x2f; EMU_INSTR(B930, B931, draw_char); reg_ax = SegValue(ss); SegSet16(ds, reg_ax); POP(di); POP(si); POP(bp); RET; } // BD95 void setup_int9() { RETLOC(BDAE); RETLOC(BD9A); reg_ax = 0x3509; EMU_INSTR(BD98, BD9A, setup_int9); W_MEMW(orig_int9_off, reg_bx); reg_ax = SegValue(es); W_MEMW(orig_int9_seg, reg_ax); PUSHI(SegValue(ds)); PUSHI(SegValue(cs)); POP(ax); SegSet16(ds, reg_ax); reg_dx = a_int9_handler; reg_ax = 0x2509; EMU_INSTR(BDAC, BDAE, setup_int9); POP(ax); SegSet16(ds, reg_ax); RET; } // BDB0 void restore_int9() { RETLOC(BDBE); assert(reg_eip == 0xBDB0); PUSHI(SegValue(ds)); reg_dx = MEMW(orig_int9_off); SegSet16(ds, MEMW(orig_int9_seg)); reg_ax = 0x2509; EMU_INSTR(BDBC, BDBE, restore_int9); reg_ax = 0x40; SegSet16(ds, reg_ax); reg_ax = MEMW(0x17); reg_ax &= 0xfcf0; W_MEMW(0x17, reg_ax); POP(ax); SegSet16(ds, reg_ax); RET; } // BE1A void int9_handler() { RETLOC(BE61); RETLOC(BE52); RETLOC(BE26); PUSH(ax); PUSH(bx); PUSHI(SegValue(ds)); reg_ax = dseg; SegSet16(ds, reg_ax); reg_ah = 0; EMU_INSTR(BE24, BE26, int9_handler); // seg000:BE26 if ((char)reg_al < 0) { // seg000:BE2A reg_al &= 0x7f; reg_bx = reg_ax; W_MEMB(key_map + reg_bx, reg_ah); } else { // seg000:BE35 W_MEMB(key_scan, reg_al); W_MEMB(key_scan, MEMB(key_scan) | 0x80); MOV(bx, ax); reg_al = 1; W_MEMB(key_map + reg_bx, reg_al); } // seg000:BE45 if (MEMW(pass_keys_to_bios) & 1) { // seg000:BE4D EMU_INSTR(BE4D, BE52, int9_handler); reg_ax = 0x40; SegSet16(ds, reg_ax); reg_ax = MEMW(0x1a); W_MEMW(0x1c, reg_ax); } // seg000:BE5D reg_al = 0x20; EMU_INSTR(BE5F, BE61, int9_handler); POP(ax); SegSet16(ds, reg_ax); POP(bx); POP(ax); reg_eip = 0xbe64; return; } // BEB7 void restore_int8() { RETLOC(BEF2); RETLOC(BEED); RETLOC(BEE3); RETLOC(BECC); RETLOC(BEC5); RETLOC(BEC1); assert(reg_eip == 0xBEB7); if (MEMW(sound_disabled) & 0xffff) { RET; } // seg000:BEC0 EMU_INSTR(BEC0, BEC1, restore_int8); reg_al = 0x36; EMU_INSTR(BEC3, BEC5, restore_int8); reg_al = 0; EMU_INSTR(BEC7, BECC, restore_int8); reg_ax = MEMW(int8_set); // seg000:BECF if (reg_ax != 0) { // seg000:BED4 PUSHI(SegValue(ds)); reg_dx = MEMW(orig_int8_off); reg_ax = MEMW(orig_int8_seg); SegSet16(ds, reg_ax); reg_ax = 0x2508; EMU_INSTR(BEE1, BEE3, restore_int8); POP(ax); SegSet16(ds, reg_ax); W_MEMW(int8_set, 0); EMU_INSTR(BEEA, BEED, restore_int8); reg_al &= 0xfd; EMU_INSTR(BEEF, BEF2, restore_int8); } // seg000:BEF2 RET; } // BF97 void int8_handler() { RETLOC(BFEF); RETLOC(BFEB); RETLOC(C00C); RETLOC(C008); RETLOC(C002); RETLOC(BFFE); RETLOC(BFE6); RETLOC(BFC5); RETLOC(BFAB); PUSH(ax); PUSH(bx); PUSH(cx); PUSH(si); PUSHI(SegValue(ds)); PUSHI(SegValue(es)); reg_ax = dseg; SegSet16(ds, reg_ax); reg_ax = MEMW(sound_data_hi); SegSet16(es, reg_ax); reg_al = 0x20; EMU_INSTR(BFA9, BFAB, int8_handler); W_MEMD(tick_count, MEMD(tick_count) + 1); W_MEMB(int8_divider, MEMB(int8_divider) - 1); // seg000:BFB9 if (MEMB(int8_divider) == 0) { // seg000:BFBB reg_al = 8; W_MEMB(int8_divider, reg_al); EMU_INSTR(BFC0, BFC5, int8_handler); } // seg000:BFC5 reg_si = MEMW(cur_sound_pos); if (reg_si != 0) { // seg000:BFCE reg_bx = mem_readw(SegPhys(es) + reg_si); W_MEMW(cur_sound_pos, MEMW(cur_sound_pos) + 2); // seg000:BFDE if (reg_bx == 0xFFFF) { // seg000:BFE3 EMU_CALL(a_stop_cur_sound, BFE6, int8_handler); // C00C POP(ax); SegSet16(es, reg_ax); POP(ax); SegSet16(ds, reg_ax); POP(si); POP(cx); POP(bx); POP(ax); reg_eip = 0xc012; return; } // seg000:BFD9 if (reg_bx != 0) { // seg000:BFF2 if (MEMW(want_sound) & 0xff) { // seg000:BFFA reg_al = 0xB6; EMU_INSTR(BFFC, BFFE, int8_handler); MOV(al, bl); EMU_INSTR(C000, C002, int8_handler); MOV(al, bh); EMU_INSTR(C004, C008, int8_handler); reg_al |= 3; EMU_INSTR(C00A, C00C, int8_handler); POP(ax); SegSet16(es, reg_ax); POP(ax); SegSet16(ds, reg_ax); POP(si); POP(cx); POP(bx); POP(ax); reg_eip = 0xc012; return; } } } // seg000:BFE9 EMU_INSTR(BFE9, BFEB, int8_handler); reg_al &= 0xFC; EMU_INSTR(BFED, BFEF, int8_handler); POP(ax); SegSet16(es, reg_ax); POP(ax); SegSet16(ds, reg_ax); POP(si); POP(cx); POP(bx); POP(ax); reg_eip = 0xc012; } // C0AC void init_rnd() { RETLOC(C0C2); assert(reg_eip == 0xC0AC); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_ax = MEMW(reg_bp + 4); // seg000:C0B4 if (reg_ax == 0) { // seg000:C0B8 reg_dx = 0; } else { // seg000:C0BE reg_ah = 0x2c; EMU_INSTR(C0C0, C0C2, init_rnd); reg_dx &= 0xff; } // seg000:C0C6 W_MEMW(rnd, reg_dx); POP(di); POP(si); POP(bp); RET; } // C0E2 void delay() { RETLOC(C0F5); RETLOC(C0ED); assert(reg_eip == 0xC0E2); PUSH(bp); MOV(bp, sp); PUSH(si); reg_cx = MEMW(reg_bp + 4); do { do { // seg000:C0E9 reg_dx = 0x3da; EMU_INSTR(C0EC, C0ED, delay); } while (reg_al & 8); do { // seg000:C0F1 reg_dx = 0x3da; EMU_INSTR(C0F4, C0F5, delay); } while ((reg_al & 8) == 0); // seg000:C0F9 reg_bx = 100; do { reg_bx--; } while (reg_bx); // seg000:C0FF reg_cx--; } while (reg_cx != 0); POP(si); POP(bp); RET; } // C169 void detect_video() { RETLOC(C1A3); RETLOC(C19C); assert(reg_eip == 0xC169); PUSH(bp); MOV(bp, sp); PUSHI(SegValue(ds)); PUSH(si); PUSH(di); SegSet16(ds, SegValue(cs)); reg_di = word_C139; W_MEMW(reg_di, 0); W_MEMW(reg_di + 2, 0); W_MEMB(byte_C163, 1); W_MEMB(byte_C160, 1); W_MEMB(byte_C166, 1); reg_cx = 4; reg_si = unk_C15D; do { // seg000:C192 reg_al = MEMB(reg_si); reg_si++; char al_tmp = reg_al; reg_ax = MEMW(reg_si); reg_si += 2; if (al_tmp != 0) { // seg000:C198 PUSH(si); PUSH(cx); EMU_CALL(reg_ax, C19C, detect_video); POP(cx); POP(si); } // seg000:C19E reg_cx--; } while (reg_cx != 0); // seg000:C1A0 EMU_CALL(a_check_vid_mode, C1A3, detect_video); // seg000:C1A3 reg_al = MEMB(word_C139); reg_ah = 0; POP(di); POP(si); SegSet16(ds, mem_readw(SegPhys(ss) + reg_sp)); reg_sp += 2; MOV(sp, bp); POP(bp); RET; } // C297 void check_vid_mode() { RETLOC(C2AC); if (MEMW(reg_di + 2) == 0) RET; if ((char)MEMB(reg_di) < 4) RET; if ((char)MEMB(reg_di + 2) < 4) RET; reg_ah = 0xf; EMU_INSTR(C2AA, C2AC, check_vid_mode); reg_al &= 7; // seg000:C2AE if (reg_al != 7) { // seg000:C2B2 if (MEMB(reg_di + 1) != 1) RET; } else { // seg000:C2BA if (MEMB(reg_di + 1) == 1) RET; } // seg000:C2C0 reg_ax = MEMW(reg_di); short tmp = MEMW(reg_di + 2); W_MEMW(reg_di + 2, reg_ax); W_MEMW(reg_di, tmp); RET; } // C5FA void extend_bss() { RETLOC(C64E); assert(reg_eip == 0xC5FA); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_ax = MEMW(reg_bp + 6); reg_ax++; MOV(si, ax); reg_si -= MEMW(segx); MOV(ax, si); reg_ax += 0x3f; reg_cl = 6; reg_ax >>= reg_cl; MOV(si, ax); // seg000:C614 if (reg_ax != MEMW(last_seg)) { // seg000:C62C reg_cl = 6; reg_si <<= reg_cl; reg_di = MEMW(end_bss_seg); MOV(ax, si); reg_ax += MEMW(segx); // seg000:C63A if (reg_ax > reg_di) { // seg000:C63E MOV(ax, di); reg_ax -= MEMW(segx); MOV(si, ax); } // seg000:C646 PUSH(si); PUSHI(MEMW(segx)); EMU_CALL(a__setblock, C64E, extend_bss); POP(cx); POP(cx); MOV(di, ax); // seg000:C652 if (reg_ax == 0xffff) { // seg000:C657 MOV(ax, si); reg_cl = 6; reg_ax >>= reg_cl; W_MEMW(last_seg, reg_ax); } else { // seg000:C662 reg_ax = MEMW(segx); reg_ax += reg_di; W_MEMW(end_bss_off, 0); W_MEMW(end_bss_seg, reg_ax); reg_ax = 0; POP(di); POP(si); POP(bp); reg_eip = 0xc675; return; } } // seg000:C61A int tmp1 = MEMD(reg_bp + 4); W_MEMD(last_extend_lo, tmp1); reg_ax = 1; // seg000:C672 POP(di); POP(si); POP(bp); reg_eip = 0xc675; return; } // C678 void check_extend_bss() { RETLOC(C6AA); assert(reg_eip == 0xC678); PUSH(bp); MOV(bp, sp); int start_bss = MEMD(start_bss_off); int end_bss = MEMD(end_bss_off); int tmp1 = MEMD(reg_bp + 4); if (TOPHYS(tmp1) < TOPHYS(start_bss) || TOPHYS(tmp1) > TOPHYS(end_bss)) { // seg000:C6AE reg_ax = 0xffff; POP(bp); RET; } // seg000:C6A1 PUSHI(MEMW(reg_bp + 6)); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_extend_bss, C6AA, check_extend_bss); // seg000:C6AA if (reg_ax == 0) { reg_ax = 0xffff; POP(bp); RET; } // seg000:C6B3 reg_ax = 0; POP(bp); RET; } // C6B7 void check_extend_bss2() { RETLOC(C714); assert(reg_eip == 0xC6B7); PUSH(bp); MOV(bp, sp); reg_sp -= 8; // C6BD int tmp1 = MEMD(last_extend_lo); tmp1 = N_PADD(tmp1, (int)MEMD(reg_bp + 4)); W_MEMD(reg_bp - 4, tmp1); // seg000:C6D3 unsigned int start_bss = TOPHYS(MEMD(start_bss_off)); unsigned int end_bss = TOPHYS(MEMD(end_bss_off)); if (TOPHYS(tmp1) < start_bss || TOPHYS(tmp1) > end_bss) { // seg000:C6F6 reg_dx = 0xffff; reg_ax = 0xffff; MOV(sp, bp); POP(bp); RET; } // seg000:C6FE tmp1 = MEMD(last_extend_lo); W_MEMD(reg_bp - 8, tmp1); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_extend_bss, C714, check_extend_bss2); // seg000:C714 if (reg_ax == 0) { // seg000:C6F6 reg_dx = 0xffff; reg_ax = 0xffff; MOV(sp, bp); POP(bp); RET; } // seg000:C71A reg_dx = MEMW(reg_bp - 6); reg_ax = MEMW(reg_bp - 8); MOV(sp, bp); POP(bp); RET; } // BB2D void draw_sprite() { RETLOC(BC37); RETLOC(BC2E); RETLOC(BC27); RETLOC(BC0B); RETLOC(BC04); RETLOC(BBFD); RETLOC(BBE1); RETLOC(BBDA); RETLOC(BBD3); RETLOC(BBB7); RETLOC(BBB0); RETLOC(BBA9); RETLOC(BB8D); RETLOC(BB86); RETLOC(BB7F); RETLOC(BB78); assert(reg_eip == 0xBB2D); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_ax = MEMW(reg_bp + 4); reg_bx = MEMW(reg_bp + 6); reg_bx <<= 1; reg_ax += MEMW(word_1685C + reg_bx); W_MEMW(sprite_dst_lo, reg_ax); reg_bx = MEMW(reg_bp + 8); reg_bx <<= 5; // seg000:BB4E SegSet16(es, MEMW(sprite_data + 2)); reg_ax = mem_readw(SegPhys(es) + reg_bx + 2); W_MEMW(sprite_pixel_count, reg_ax); reg_ax = mem_readw(SegPhys(es) + reg_bx + 4); W_MEMW(sprite_mask_src_lo, reg_ax); reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; reg_ax = MEMW(blit_funcs + reg_bx); W_MEMW(draw_sprite_func, reg_ax); reg_ax = 3; W_MEMW(word_18074, reg_ax); // seg000:BB72 SegSet16(es, MEMW(dstseg)); EMU_INSTR(BB76, BB78, draw_sprite); reg_dx = 0x3ce; reg_ax = 5; EMU_INSTR(BB7E, BB7F, draw_sprite); reg_dx = 0x3ce; reg_ax = 4; EMU_INSTR(BB85, BB86, draw_sprite); reg_dx = 0x3c4; reg_ax = 0x102; EMU_INSTR(BB8C, BB8D, draw_sprite); reg_di = MEMW(sprite_dst_lo); reg_cx = MEMW(sprite_pixel_count); reg_si = MEMW(sprite_mask_src_lo); reg_bp = MEMW(word_1806E); reg_ax = MEMW(sprite_mask_hi); SegSet16(ds, MEMW(sprite_src_hi_1)); EMU_INSTR(BBA4, BBA9, draw_sprite); reg_dx = 0x3ce; reg_ax = 0x104; EMU_INSTR(BBAF, BBB0, draw_sprite); reg_dx = 0x3c4; reg_ax = 0x202; EMU_INSTR(BBB6, BBB7, draw_sprite); reg_di = MEMW(sprite_dst_lo); reg_cx = MEMW(sprite_pixel_count); reg_si = MEMW(sprite_mask_src_lo); reg_bp = MEMW(word_1806E); reg_ax = MEMW(sprite_mask_hi); SegSet16(ds, MEMW(sprite_src_hi_2)); EMU_INSTR(BBCE, BBD3, draw_sprite); reg_dx = 0x3ce; reg_ax = 0x204; EMU_INSTR(BBD9, BBDA, draw_sprite); reg_dx = 0x3c4; reg_ax = 0x402; EMU_INSTR(BBE0, BBE1, draw_sprite); reg_di = MEMW(sprite_dst_lo); reg_cx = MEMW(sprite_pixel_count); reg_si = MEMW(sprite_mask_src_lo); reg_bp = MEMW(word_1806E); reg_ax = MEMW(sprite_mask_hi); SegSet16(ds, MEMW(sprite_src_hi_3)); EMU_INSTR(BBF8, BBFD, draw_sprite); reg_dx = 0x3ce; reg_ax = 0x304; EMU_INSTR(BC03, BC04, draw_sprite); reg_dx = 0x3c4; reg_ax = 0x802; EMU_INSTR(BC0A, BC0B, draw_sprite); reg_di = MEMW(sprite_dst_lo); reg_cx = MEMW(sprite_pixel_count); reg_si = MEMW(sprite_mask_src_lo); reg_bp = MEMW(word_1806E); reg_ax = MEMW(sprite_mask_hi); SegSet16(ds, MEMW(sprite_src_hi_4)); EMU_INSTR(BC22, BC27, draw_sprite); reg_ax = 0x105; reg_dx = 0x3ce; EMU_INSTR(BC2D, BC2E, draw_sprite); reg_dx = 0x3c4; reg_al = 2; reg_ah = 0xf; EMU_INSTR(BC35, BC37, draw_sprite); POP(di); POP(si); POP(bp); RET; } // 239 void sync_drawing() { RETLOC(262); assert(reg_eip == 0x239); PUSH(bp); MOV(bp, sp); W_MEMW(overdraw_draw_guard, 0); W_MEMW(filter_draw_guard, 0); W_MEMW(sprite_draw_guard, 0); W_MEMW(sprite_scratch_data, word_1909E); // disabled: no sprites W_MEMW(sprite_scratch_na, word_19C5A); // disabled: no change W_MEMW(sprite_scratch_overdraw, word_19CB4); // disabled: overdraw doesn't work W_MEMW(sprite_scratch_back, word_186B0); // disabled: trails // seg000:025F do { EMU_INSTR(25F, 262, sync_drawing); reg_ax -= MEMW(tick_count_2); W_MEMW(sprite_sync, reg_ax); } while (reg_ax < 6); // seg000:026E if (reg_ax > 0xf) { // seg000:0273 W_MEMW(sprite_sync, 0xf); } // seg000:0279 int tmp1 = MEMD(tick_count); W_MEMW(tick_count_2, tmp1); POP(bp); RET; } // 3296 void sprite_active_screen() { assert(reg_eip == 0x3296); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); int tmp1 = MEMD(sprite_copy.pos_x_lo) >> 0xc; reg_di = tmp1 & 0xffff; // seg000:32A9 tmp1 = MEMD(sprite_copy.pos_y_lo) >> 0xc; reg_si = tmp1 & 0xffff; // seg000:32B7 if ((int)MEMD(sprite_copy.pos_y_lo) < 0) { // seg000:32C7 W_MEMW(sprite_copy.pos_y_lo, 0); } // seg000:32D3 if ((int)MEMD(sprite_copy.pos_x_lo) <= (int)MEMD(background_width)) { // seg000:32E8 if ((int)MEMD(sprite_copy.pos_x_lo) >= 0) { // seg000:32F8 if ((int)MEMD(sprite_copy.pos_y_lo) <= (int)MEMD(background_height)) { // seg000:3318 reg_ax = MEMW(word_186A6); reg_ax += 0xfff8; if ((short)reg_ax <= (short)reg_di) { // seg000:3322 reg_ax = MEMW(word_18B62); reg_ax += 0xfff8; if ((short)reg_ax <= (short)reg_si) { // seg000:332C reg_ax = MEMW(word_186A6); reg_ax += 0x1c; if ((short)reg_ax >= (short)reg_di) { // seg000:3336 reg_ax = MEMW(word_18B62); reg_ax += 0x12; if ((short)reg_ax >= (short)reg_si) { // seg000:335A reg_ax = 0; // sprite is active POP(di); POP(si); POP(bp); RET; } } } } // seg000:3340 if ((short)MEMW(sprite_copy.type) < 9) { // seg000:3347 W_MEMW(sprite_copy.active, 0); } else { // seg000:334F W_MEMW(sprite_copy.type, 0); } // seg000:3355 reg_ax = 1; POP(di); POP(si); POP(bp); RET; } } } // seg000:330D W_MEMW(sprite_copy.type, 0); reg_ax = 1; POP(di); POP(si); POP(bp); RET; } // 2A3B void sub_2A3B() { RETLOC(2A86); assert(reg_eip == 0x2A3B); PUSH(bp); MOV(bp, sp); PUSH(si); // seg000:2A3F reg_ax = 0; reg_dx = 4; PUSH(ax); PUSH(dx); // seg000:2A46 int tmp1 = MEMD(sprite_copy.pos_x_lo) >> 9; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); tmp1 %= 4; reg_sp += 8; // seg000:2A57 reg_dx = MEMW(sprite_copy.cur_frame); reg_dx <<= 2; reg_dx += tmp1 & 0xffff; //seg000:2A61 MOV(si, dx); reg_ax = word_1B356; PUSHI(SegValue(ds)); PUSH(ax); MOV(ax, si); tmp1 = (short)reg_ax; tmp1 = tmp1 << 5; PUSHI(tmp1 & 0xffff); PUSHI(tmp1 >> 16); // seg000:2A72 int tmp2 = MEMD(sprite_data); POP(cx); POP(bx); tmp1 = N_PADD(tmp2, tmp1); PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); reg_cx = 20; EMU_CALL(a_N_SCOPY, 2A86, sub_2A3B); // seg000:2A86 reg_ax = MEMW(word_1B35E); tmp1 = (short)reg_ax; tmp2 = MEMD(sprite_copy.pos_x_lo); tmp2 += tmp1; W_MEMD(sprite_copy.box_left_x, tmp2); // seg000:2A9E reg_ax = MEMW(word_1B362); tmp1 = (short)reg_ax; tmp2 = MEMD(sprite_copy.pos_x_lo); tmp2 += tmp1; W_MEMD(sprite_copy.box_right_x, tmp2); // seg000:2AB6 reg_ax = MEMW(word_1B360); tmp1 = (short)reg_ax; tmp2 = MEMD(sprite_copy.pos_y_lo); tmp2 += tmp1; W_MEMD(sprite_copy.box_top_y, tmp2); // seg000:2ACE reg_ax = MEMW(word_1B364); tmp1 = (short)reg_ax; tmp2 = MEMD(sprite_copy.pos_y_lo); tmp2 += tmp1; W_MEMD(sprite_copy.box_bottom_y, tmp2); // seg000:2AE6 POP(si); POP(bp); RET; } // 2C5 void draw_sprite_at() { RETLOC(380); assert(reg_eip == 0x2C5); PUSH(bp); MOV(bp, sp); reg_sp -= 0x12; PUSH(si); PUSH(di); // seg000:02CD int tmp1 = MEMD(reg_bp + 4); tmp1 /= 0x100; PUSHI(tmp1 & 0xffff); // seg000:02DE tmp1 = MEMD(scroll_x_lo); tmp1 /= 0x100; reg_ax = tmp1 & 0xfff0; POP(dx); reg_dx -= reg_ax; W_MEMW(reg_bp - 0xa, reg_dx); // seg000:02F9 tmp1 = MEMD(reg_bp + 8); tmp1 /= 0x100; PUSHI(tmp1 & 0xffff); // seg000:030A tmp1 = MEMD(scroll_y_lo); tmp1 /= 0x100; reg_ax = tmp1 & 0xfff0; POP(dx); reg_dx -= reg_ax; W_MEMW(reg_bp - 0xc, reg_dx); // seg000:0325 if ((short)MEMW(reg_bp - 0xa) < -32 || (short)reg_dx < -32 || (short)MEMW(reg_bp - 0xa) > 0x150 || (short)reg_dx > 0xc7) { // seg000:033D reg_ax = 0; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:0342 reg_ax = MEMW(reg_bp + 0xc); reg_ax <<= 2; PUSH(ax); reg_ax = MEMW(reg_bp - 0xa); reg_ax &= 7; reg_bx = 2; tmp1 = (short)reg_ax; tmp1 /= reg_bx; POP(dx); reg_dx += tmp1 & 0xffff; W_MEMW(reg_bp - 0xe, reg_dx); // seg000:035C reg_ax = word_1B356; PUSHI(SegValue(ds)); PUSH(ax); reg_ax = MEMW(reg_bp - 0xe); tmp1 = (short)reg_ax; tmp1 = tmp1 << 5; // seg000:036C int tmp2 = MEMD(sprite_data); tmp1 = N_PADD(tmp2, tmp1); PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); reg_cx = 0x20; EMU_CALL(a_N_SCOPY, 380, draw_sprite_at); // seg000:0380 reg_ax = MEMW(reg_bp - 0xa); reg_ax += 0x20; reg_bx = 8; tmp1 = (short)reg_ax; tmp1 /= reg_bx; reg_ax = tmp1 & 0xffff; reg_ax += 0xfffc; W_MEMW(reg_bp - 0xa, reg_ax); reg_bx = 2; tmp1 = (short)reg_ax; tmp1 /= reg_bx; reg_ax = tmp1 & 0xffff; W_MEMW(reg_bp - 2, reg_ax); // seg000:039B if ((short)reg_ax < 0) { // seg000:039F W_MEMW(reg_bp - 2, 0); } else if ((short)MEMW(reg_bp - 2) > 0x15) { // seg000:03AC reg_ax = 0; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:03B1 reg_ax = MEMW(reg_bp - 0xa); reg_ax += MEMW(word_1B356); reg_ax--; reg_bx = 2; tmp1 = (short)reg_ax; tmp1 /= reg_bx; reg_ax = tmp1 & 0xffff; W_MEMW(reg_bp - 4, reg_ax); // seg000:03C2 if ((short)reg_ax > 0x15) { // seg000:03C7 W_MEMW(reg_bp - 4, 0x15); } else { // seg000:03CE if ((short)MEMW(reg_bp - 4) < 0) { // seg000:03D4 reg_ax = 0; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } } // seg000:03D9 reg_ax = MEMW(reg_bp - 0xc); reg_bx = 0x10; tmp1 = (short)reg_ax; tmp1 /= reg_bx; reg_ax = tmp1 & 0xffff; W_MEMW(reg_bp - 6, reg_ax); // seg000:03E5 if ((short)reg_ax < 0) { // seg000:03E9 W_MEMW(reg_bp - 6, 0); } else { // seg000:03F0 if ((short)MEMW(reg_bp - 6) > 0xe) { // seg000:03F6 reg_ax = 0; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } } // seg000:03FB reg_ax = MEMW(reg_bp - 0xc); reg_ax += MEMW(word_1B358); reg_ax--; reg_bx = 0x10; tmp1 = (short)reg_ax; tmp1 /= reg_bx; reg_ax = tmp1 & 0xffff; W_MEMW(reg_bp - 8, reg_ax); // seg000:040C if ((short)reg_ax > 0xd) { // seg000:0411 W_MEMW(reg_bp - 8, 0xd); } else { // seg000:0418 if ((short)MEMW(reg_bp - 8) < 0) { // seg000:041E reg_ax = 0; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } } // seg000:0423 W_MEMW(reg_bp - 0xa, MEMW(reg_bp - 0xa) + 4); W_MEMW(reg_bp - 0xc, MEMW(reg_bp - 0xc) + 0x20); reg_di = MEMW(reg_bp - 6); // seg000:04D2 while ((short)reg_di <= (short)MEMW(reg_bp - 8)) { // seg000:0431 reg_si = MEMW(reg_bp - 2); // seg000:04C9 while((short)reg_si <= (short)MEMW(reg_bp - 4)) { // seg000:0437 MOV(ax, di); reg_ax += MEMW(word_18B62); reg_ax *= MEMW(map_width_intiles); MOV(dx, si); reg_dx += MEMW(word_186A6); reg_dx += reg_ax; reg_dx <<= 1; // seg000:044B reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 0x10, reg_ax); // seg000:0457 reg_bx = MEMW(reg_bp - 0x10); reg_bx <<= 1; reg_ax = MEMW(tile_kind_tbl + reg_bx); W_MEMW(reg_bp - 0x12, reg_ax); // seg000:0463 if ((short)reg_ax >= 0) { // seg000:0467 MOV(ax, di); reg_dx = 0x15; reg_ax *= reg_dx; reg_ax += reg_si; reg_bx = MEMW(sprite_scratch_back); W_MEMW(reg_bx, reg_ax); W_MEMW(sprite_scratch_back, MEMW(sprite_scratch_back) + 2); } else { // seg000:047D MOV(ax, si); reg_ax <<= 1; reg_ax += 4; reg_bx = MEMW(sprite_scratch_overdraw); W_MEMW(reg_bx, reg_ax); MOV(ax, di); reg_ax <<= 4; reg_ax += 0x20; W_MEMW(reg_bx + 2, reg_ax); reg_ax = MEMW(reg_bp - 0x10); W_MEMW(reg_bx + 4, reg_ax); // seg000:049C if (MEMW(reg_bp - 0x12) == 0xFFFE) { // seg000:04A2 reg_ax = MEMW(reg_bx + 4); reg_ax |= 0x8000; W_MEMW(reg_bx + 4, reg_ax); MOV(ax, di); reg_dx = 0x15; reg_ax *= reg_dx; MOV(ax, si); reg_bx = MEMW(sprite_scratch_back); W_MEMW(reg_bx, reg_ax); W_MEMW(sprite_scratch_back, MEMW(sprite_scratch_back) + 2); } // seg000:04BF W_MEMW(overdraw_draw_guard, MEMW(overdraw_draw_guard) + 1); W_MEMW(sprite_scratch_overdraw, MEMW(sprite_scratch_overdraw) + 6); } // seg000:04C8 reg_si++; } // seg000:04D1 reg_di++; } // seg000:04DA reg_bx = MEMW(sprite_scratch_data); reg_ax = MEMW(reg_bp - 0xa); W_MEMW(reg_bx, reg_ax); reg_ax = MEMW(reg_bp - 0xc); W_MEMW(reg_bx + 2, reg_ax); reg_ax = MEMW(reg_bp - 0xe); W_MEMW(reg_bx + 4, reg_ax); W_MEMW(sprite_draw_guard, MEMW(sprite_draw_guard) + 1); W_MEMW(sprite_scratch_data, MEMW(sprite_scratch_data) + 6); reg_ax = 1; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // B939 void do_overdraw() { RETLOC(BAAE); RETLOC(BAA5); RETLOC(BA7D); RETLOC(BA76); RETLOC(B964); RETLOC(B96B); RETLOC(B973); RETLOC(B9E2); RETLOC(B9E9); RETLOC(B9F0); RETLOC(BA18); RETLOC(BA1F); RETLOC(BA47); RETLOC(BA4E); assert(reg_eip == 0xB939); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); SegSet16(es, MEMW(dstseg)); reg_di = MEMW(reg_bp + 4); reg_bx = MEMW(reg_bp + 6); reg_bx <<= 1; reg_di += MEMW(word_1685C + reg_bx); reg_si = MEMW(reg_bp + 8); // seg000:B951 if ((short)reg_si >= 0) { // seg000:B955 reg_si <<= 1; reg_si += MEMW(word_1660E); reg_si = MEMW(reg_si); reg_ax = MEMW(EGAHEAD_Tileloc_seg); SegSet16(ds, reg_ax); EMU_INSTR(B962, B964, do_overdraw); reg_dx = 0x3c4; reg_ax = 0x0f02; EMU_INSTR(B96A, B96B, do_overdraw); reg_ax = 0x0105; reg_dx = 0x3ce; EMU_INSTR(B971, B973, do_overdraw); mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B975 reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B97A reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B97F reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B984 reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B989 reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B98E reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B993 reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B998 reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B99D reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B9A2 reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B9A7 reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B9AC reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B9B1 reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B9B6 reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B9BB reg_di += 0x2e; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_di++; reg_si++; // seg000:B9C0 SegSet16(ds, SegValue(ss)); POP(di); POP(si); POP(bp); RET; } // seg000:B9C8 reg_si &= 0x7fff; reg_si <<= 5; reg_ax = MEMW(EGAHEAD_Tileloc_seg); SegSet16(ds, reg_ax); reg_dx = 0x3ce; reg_ax = 5; EMU_INSTR(B9E1, B9E2, do_overdraw); reg_dx = 0x3ce; reg_ax = 4; EMU_INSTR(B9E8, B9E9, do_overdraw); reg_dx = 0x3c4; reg_ax = 0x102; EMU_INSTR(B9Ef, B9F0, do_overdraw); PUSH(si); PUSH(di); reg_cx = 0x10; do { // seg000:B9F5 reg_ax = mem_readw(SegPhys(es) + reg_di); reg_bx = MEMW(reg_si + 0x20); reg_dx = MEMW(reg_si); reg_ax &= reg_bx; reg_bx ^= 0xffff; reg_dx &= reg_bx; reg_ax |= reg_dx; mem_writew(SegPhys(es) + reg_di, MEMW(reg_si)); reg_di += 2; reg_si += 2; reg_si += 2; reg_di += 0x2e; reg_cx--; } while (reg_cx != 0); // seg000:BA0F POP(di); POP(si); reg_dx = 0x3ce; reg_ax = 0x104; EMU_INSTR(BA17, BA18, do_overdraw); reg_dx = 0x3c4; reg_ax = 0x202; EMU_INSTR(BA1E, BA1F, do_overdraw); PUSH(si); PUSH(di); reg_cx = 0x10; do { // seg000:BA24 reg_ax = mem_readw(SegPhys(es) + reg_di); reg_bx = MEMW(reg_si + 0x20); reg_dx = MEMW(reg_si); reg_ax &= reg_bx; reg_bx ^= 0xffff; reg_dx &= reg_bx; reg_ax |= reg_dx; mem_writew(SegPhys(es) + reg_di, MEMW(reg_si)); reg_di += 2; reg_si += 2; reg_si += 2; reg_di += 0x2e; reg_cx--; } while (reg_cx != 0); // seg000:BA3E POP(di); POP(si); reg_dx = 0x3ce; reg_ax = 0x204; EMU_INSTR(BA46, BA47, do_overdraw); reg_dx = 0x3c4; reg_ax = 0x402; EMU_INSTR(BA4D, BA4E, do_overdraw); PUSH(si); PUSH(di); reg_cx = 0x10; do { // seg000:BA53 reg_ax = mem_readw(SegPhys(es) + reg_di); reg_bx = MEMW(reg_si + 0x20); reg_dx = MEMW(reg_si); reg_ax &= reg_bx; reg_bx ^= 0xffff; reg_dx &= reg_bx; reg_ax |= reg_dx; mem_writew(SegPhys(es) + reg_di, MEMW(reg_si)); reg_di += 2; reg_si += 2; reg_si += 2; reg_di += 0x2e; reg_cx--; } while (reg_cx != 0); // seg000:BA6D POP(di); POP(si); reg_dx = 0x3ce; reg_ax = 0x304; EMU_INSTR(BA75, BA76, do_overdraw); reg_dx = 0x3c4; reg_ax = 0x802; EMU_INSTR(BA7C, BA7D, do_overdraw); PUSH(si); PUSH(di); reg_cx = 0x10; do { // seg000:BA82 reg_ax = mem_readw(SegPhys(es) + reg_di); reg_bx = MEMW(reg_si + 0x20); reg_dx = MEMW(reg_si); reg_ax &= reg_bx; reg_bx ^= 0xffff; reg_dx &= reg_bx; reg_ax |= reg_dx; mem_writew(SegPhys(es) + reg_di, MEMW(reg_si)); reg_di += 2; reg_si += 2; reg_si += 2; reg_di += 0x2e; reg_cx--; } while (reg_cx != 0); // seg000:BA9C POP(di); POP(si); reg_ax = 0x105; reg_dx = 0x3ce; EMU_INSTR(BAA4, BAA5, do_overdraw); reg_dx = 0x3c4; reg_al = 2; reg_ah = 0xf; EMU_INSTR(BAAC, BAAE, do_overdraw); // seg000:BAAE SegSet16(ds, SegValue(ss)); POP(di); POP(si); POP(bp); RET; } // 6BD4 void sub_6BD4() { PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); // seg000:6C0E while ((short)MEMW(word_1B346) <= 0x18) { // seg000:6BDB reg_bx = MEMW(dword_1B2AA); SegSet16(es, MEMW(dword_1B2AA + 2)); reg_ax = mem_readb(SegPhys(es) + reg_bx); reg_ax &= 0xff; MOV(si, ax); reg_cx = 0; reg_bx = 1; W_MEMD(dword_1B2AA, N_PADD(MEMD(dword_1B2AA), 1)); // seg000:6BF5 MOV(ax, si); int tmp1 = (short)reg_ax; reg_cl = 0x18 - MEMB(word_1B346); tmp1 = tmp1 << reg_cl; W_MEMD(dword_1B342, MEMD(dword_1B342) | tmp1); // seg000:6C09 W_MEMW(word_1B346, MEMW(word_1B346) + 8); } // seg000:6C15 reg_cl = 0x20; reg_cl -= MEMB(word_1C74A); unsigned int tmpu = MEMD(dword_1B342); tmpu >>= reg_cl; reg_di = tmpu & 0xffff; // seg000:6C27 reg_cl = MEMB(word_1C74A); tmpu = MEMD(dword_1B342); tmpu = tmpu << reg_cl; W_MEMD(dword_1B342, tmpu); // seg000:6C3C reg_ax = MEMW(word_1C74A); W_MEMW(word_1B346, MEMW(word_1B346) - reg_ax); MOV(ax, di); // seg000:6C45 POP(di); POP(si); POP(bp); RET; } // 6B62 void sub_6B62() { RETLOC(6BBD); RETLOC(6BB7); assert(reg_eip == 0x6B62); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_di = 0; // seg000:6BC2 while (MEMW(reg_bp + 6) > 0xff) { // seg000:6B6E int tmp1 = N_PADD(MEMD(dword_1D726), MEMW(reg_bp + 6)); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_al = mem_readb(SegPhys(es) + reg_bx); W_MEMB(reg_si, reg_al); reg_si++; // seg000:6B8A tmp1 = MEMW(reg_bp + 6); // ax:bx tmp1 <<= 1; int tmp2 = MEMD(dword_1B2B6); tmp1 = N_PADD(tmp2, tmp1); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); // seg000:6BA2 reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp + 6, reg_ax); MOV(ax, di); reg_di++; // seg000:6BAB if ((short)reg_ax >= 0xfa0) { // seg000:6BB0 PUSHI(aErrorDuringCodeExp); EMU_CALL(a__printf, 6BB7, sub_6B62); reg_sp += 2; // seg000:6BB9 PUSHI(1); EMU_CALL(a__exit, 6BBD, sub_6B62); } } // seg000:6BC9 reg_al = MEMB(reg_bp + 6); W_MEMB(reg_si, reg_al); MOV(ax, si); POP(di); POP(si); POP(bp); RET; } // BDCE void translate_key() { PUSH(bp); MOV(bp, sp); reg_bh = 0; reg_ax = MEMW(reg_bp + 4); if (reg_ax == 0) { // there's a loop here which is waiting for key_scan to change // seg000:BDDA reg_eip = 0xBDDA; return; } // seg000:BDF8 reg_bl = MEMB(key_scan); if ((reg_bl & 0x80) == 0) { reg_ax = 0; POP(bp); RET; } // seg000:BE06 reg_bl &= 0x7f; reg_ah = reg_bl; reg_al = MEMB(trans_map + reg_bx); W_MEMB(key_code, reg_al); // seg000:BE12 if (reg_al == 0) { // seg000:BE16 reg_ah = 0; } // seg000:BE18 POP(bp); RET; } // 6A30 void sub_6A30() { RETLOC(6AC0); RETLOC(6B51); assert(reg_eip == 0x6A30); PUSH(bp); MOV(bp, sp); reg_sp -= 8; PUSH(si); PUSH(di); reg_di = 0x102; W_MEMW(reg_bp - 8, 1); W_MEMD(dword_1B2AA, N_PADD(MEMD(dword_1B2AA), word_13056)); while(1) { // seg000:6B4E EMU_CALL(a_sub_6BD4, 6B51, sub_6A30); W_MEMW(reg_bp - 2, reg_ax); // seg000:6B54 if (reg_ax == 0x101) break; // seg000:6A50 if (MEMW(reg_bp - 8) != 0) { // seg000:6A56 W_MEMW(reg_bp - 8, 0); reg_ax = MEMW(reg_bp - 2); W_MEMW(reg_bp - 4, reg_ax); W_MEMW(reg_bp - 6, reg_ax); reg_bx = MEMW(dword_1B378); SegSet16(es, MEMW(dword_1B378 + 2)); reg_al = MEMB(reg_bp - 4); mem_writew(SegPhys(es) + reg_bx, reg_al); W_MEMD(dword_1B378, N_PADD(MEMD(dword_1B378), 1)); continue; } // seg000:6A7E if (MEMW(reg_bp - 2) == 0x100) { // seg000:6A85 W_MEMW(reg_bp - 8, 1); W_MEMW(word_1C74A, 9); reg_di = 0x102; reg_ax = 1; reg_cl = MEMB(word_1C74A); reg_ax <<= reg_cl; reg_ax--; W_MEMW(word_1B398, reg_ax); continue; } // seg000:6AA3 if (MEMW(reg_bp - 2) >= reg_di) { // seg000:6AA8 reg_al = MEMB(reg_bp - 6); W_MEMB(byte_1C784, reg_al); PUSHI(MEMW(reg_bp - 4)); reg_ax = unk_1C785; } else { // seg000:6AB6 PUSHI(MEMW(reg_bp - 2)); reg_ax = byte_1C784; } // seg000:6ABC PUSH(ax); EMU_CALL(a_sub_6B62, 6AC0, sub_6A30); reg_sp += 4; // seg000:6AC3 MOV(si, ax); reg_al = MEMB(reg_si); reg_ah = 0; W_MEMW(reg_bp - 6, reg_ax); // seg000:6AE5 while (reg_si >= byte_1C784) { // seg000:6ACE reg_al = MEMB(reg_si); reg_bx = MEMW(dword_1B378); SegSet16(es, MEMW(dword_1B378 + 2)); mem_writeb(SegPhys(es) + reg_bx, reg_al); reg_si--; W_MEMD(dword_1B378, N_PADD(MEMD(dword_1B378), 1)); } // seg000:6AEB if (reg_di <= MEMW(word_1B398)) { // seg000:6AF1 MOV(bx, di); int tmp1 = reg_di; tmp1 <<= 1; tmp1 = N_PADD(MEMD(dword_1B2B6), tmp1); reg_ax = MEMW(reg_bp - 4); SegSet16(es, tmp1 >> 16); reg_bx = tmp1 & 0xffff; mem_writew(SegPhys(es) + reg_bx, reg_ax); // seg000:6B10 MOV(bx, di); tmp1 = reg_di; tmp1 = N_PADD(MEMD(dword_1D726), tmp1); reg_al = MEMB(reg_bp - 6); SegSet16(es, tmp1 >> 16); reg_bx = tmp1 & 0xffff; mem_writew(SegPhys(es) + reg_bx, reg_ax); // seg000:6B27 reg_di++; if (reg_di == MEMW(word_1B398)) { // seg000:6B2E reg_ax = MEMW(word_1C74A); if ((short)reg_ax < (short)MEMW(word_1B376)) { // seg000:6B37 W_MEMW(word_1C74A, MEMW(word_1C74A) + 1); reg_cx = MEMW(word_1C74A); reg_ax = 1; reg_ax <<= reg_cl; reg_ax--; W_MEMW(word_1B398, reg_ax); } } } // seg000:6B48 reg_ax = MEMW(reg_bp - 2); W_MEMW(reg_bp - 4, reg_ax); } // seg000:6B5C POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // DEE4 void alloc_mem() { // printf("alloc_mem\n"); reg_eip = 0xDEE4; return; } // 5C58 void sub_5C58() { RETLOC(5C97); RETLOC(5C71); assert(reg_eip == 0x5C58); PUSH(bp); MOV(bp, sp); reg_sp -= 4; PUSH(si); PUSH(di); int tmp1 = MEMD(reg_bp + 4); tmp1 += 0xf; PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a_alloc_mem, 5C71, sub_5C58); reg_sp += 4; W_MEMW(reg_bp - 4, reg_ax); W_MEMW(reg_bp - 2, reg_dx); W_MEMW(dword_1D72E, reg_ax); W_MEMW(dword_1D72E + 2, reg_dx); // seg000:5C81 tmp1 = MEMD(reg_bp - 4); if (tmp1 == 0) { // seg000:5C90 PUSHI(aOutOfMemoryTryUnlo); EMU_CALL(a_chg_vid_and_error, 5C97, sub_5C58); reg_sp += 2; } // seg000:5C99 reg_si = MEMW(reg_bp - 4); if (reg_si != 0) { // seg000:5CA0 reg_di = MEMW(reg_bp - 2); reg_di++; reg_si = 0; W_MEMW(reg_bp - 4, reg_si); W_MEMW(reg_bp - 2, reg_di); } // seg000:5CAC reg_dx = MEMW(reg_bp - 2); reg_ax = MEMW(reg_bp - 4); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // c104 // GFx mode register = 0 (write/read mode = hostO/E = shift reg = shift 256 = 0) // read map select = plane i // write mode enable = plane i void vga_regplane_select() { RETLOC(C126); RETLOC(C118); RETLOC(C10F); RETLOC(C108); assert(reg_eip == 0xc104); PUSH(bp); MOV(bp, sp); EMU_INSTR(C107, C108, vga_regplane_select); //cli (clear interrupt) reg_dx = 0x3ce; //set Graphics Register = 05 --> Write Mode = 0 reg_ax = 5; EMU_INSTR(C10E, C10F, vga_regplane_select); //out dx, ax reg_dx = 0x3ce; //set Graphics Register = 04 --> Read Map Select reg_al = 4; reg_ah = MEMB(reg_bp + 4); //plane i EMU_INSTR(C117, C118, vga_regplane_select); //out dx, ax reg_dx = 0x3c4; //set Sequencer Register = 02 --> Map Mask Register reg_al = 2; reg_ah = 1; reg_cl = MEMB(reg_bp + 4); reg_ah <<= reg_cl; //write mode enable = plane i EMU_INSTR(C124, C126, vga_regplane_select); //sti (set interrupt) POP(bp); RET; } // BAB6 void draw_filter() { RETLOC(BAFF); RETLOC(BAFA); RETLOC(BAF4); RETLOC(BAF0); RETLOC(BAEA); assert(reg_eip == 0xBAB6); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 8); reg_si <<= 4; SegSet16(es, MEMW(EGAHEAD_Bmpdatastart_seg)); reg_ax = mem_readw(SegPhys(es) + reg_si); mem_writew(SegPhys(cs) + word_B8DA, reg_ax); reg_ax = mem_readw(SegPhys(es) + reg_si + 2); mem_writew(SegPhys(cs) + word_B8DE, reg_ax); reg_si = mem_readw(SegPhys(es) + reg_si + 4); reg_ax = MEMW(reg_bp + 4); mem_writew(SegPhys(cs) + word_B8DC, reg_ax); SegSet16(es, MEMW(dstseg)); EMU_INSTR(BAE8, BAEA, draw_filter); reg_dx = 0x3c4; reg_al = 2; EMU_INSTR(BAEF, BAF0, draw_filter); reg_al = 0xf; reg_dx++; EMU_INSTR(BAF3, BAF4, draw_filter); reg_dx = 0x3ce; reg_al = 5; EMU_INSTR(BAF9, BAFA, draw_filter); reg_al = 1; reg_dx++; EMU_INSTR(BAFD, BAFF, draw_filter); reg_bx = MEMW(reg_bp + 6); reg_bx <<= 1; reg_cx = MEMW(EGAHEAD_Bmploc_seg); SegSet16(ds, reg_cx); do { // seg000:BB0A reg_di = mem_readw(SegPhys(ss) + word_1685C + reg_bx); reg_bx += 2; reg_di += mem_readw(SegPhys(cs) + word_B8DC); reg_cx = mem_readw(SegPhys(cs) + word_B8DA); while (reg_cx != 0) { mem_writeb(SegPhys(es) + reg_di, mem_readb(SegPhys(ds) + reg_si)); reg_si++; reg_di++; reg_cx--; } mem_writew(SegPhys(cs) + word_B8DE, mem_readw(SegPhys(cs) + word_B8DE) - 1); } while (mem_readw(SegPhys(cs) + word_B8DE) != 0); // seg000:BB25 reg_ax = SegValue(ss); SegSet16(ds, reg_ax); POP(di); POP(si); POP(bp); RET; } // C013 void sub_C013() { RETLOC(C057); RETLOC(C046); assert(reg_eip == 0xC013); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_di = unk_182AF; reg_si = unk_182D1; reg_cx = 0x11; while (reg_cx != 0) { mem_writew(SegPhys(es) + reg_di, mem_readw(SegPhys(ds) + reg_si)); reg_di += 2; reg_si += 2; reg_cx--; } // seg000:C028 W_MEMW(word_182AD, 0); W_MEMW(word_182A9, 0x22); W_MEMW(word_182AB, 0xa); reg_ax = MEMW(reg_bp + 4); // seg000:C03D if (reg_ax != 0) { reg_ah = 0x2c; EMU_INSTR(C044, C046, sub_C013); W_MEMW(word_182CF, reg_dx); reg_dx ^= reg_cx; W_MEMW(word_182B7, reg_dx); } // seg000:C050 PUSHI(0xffff); EMU_CALL(a_calc_jump_height, C057, sub_C013); POP(ax); POP(di); POP(si); POP(bp); RET; } // B364 void process_text_file() { RETLOC(B477); RETLOC(B381); assert(reg_eip == 0xB364); PUSH(bp); MOV(bp, sp); reg_sp -= 2; PUSH(si); PUSH(di); // seg000:B36B if (MEMD(reg_bp + 4) == 0) { // seg000:B37A PUSHI(aMissingATextFile); EMU_CALL(a_chg_vid_and_error, B381, process_text_file); reg_sp += 2; } // seg000:B383 reg_di = 0; while(1) { // seg000:B388 int tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_di); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); // seg000:B399 if (mem_readb(SegPhys(es) + reg_bx) == 0x1a) break; // seg000:B387 reg_di++; } // seg000:B39F reg_si = 0; while (1) { // seg000:B4BF int tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); if (mem_readb(SegPhys(es) + reg_bx) == 0x1a) break; // seg000:B3A4 tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_al = mem_readb(SegPhys(es) + reg_bx); W_MEMB(reg_bp - 1, reg_al); // seg000:B3BB if (reg_al == 0x1f) { // seg000:B3BF int tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); mem_writeb(SegPhys(es) + reg_bx, 0xd); } else { // seg000:B3D7 if (MEMB(reg_bp - 1) == 0xd) { // seg000:B3E0 tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si + 2); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); if (mem_readb(SegPhys(es) + reg_bx) != 0xd) { // seg000:B402 tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); mem_writeb(SegPhys(es) + reg_bx, 0x20); tmp1 = MEMD(reg_bp + 4); PUSHI(reg_di - reg_si); tmp1 = N_PADD(tmp1, reg_si + 1); PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si + 1); PUSHI(tmp1 >> 16); tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si + 2); PUSHI(tmp1 & 0xffff); tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si + 2); PUSHI(tmp1 >> 16); EMU_CALL(a__movedata, B477, process_text_file); reg_sp += 0xa; reg_di--; // duplicate of b4be reg_si++; continue; } } // seg000:B47D if (MEMB(reg_bp - 1) == 0xd) { // seg000:B483 int tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si + 2); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); if (mem_readb(SegPhys(es) + reg_bx) == 0xd) { while (1) { // seg000:B4A6 int tmp1 = MEMD(reg_bp + 4); tmp1 = N_PADD(tmp1, reg_si); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); if (mem_readb(SegPhys(es) + reg_bx) != 0xd) break; // seg000:B4A4 reg_si += 2; } // seg000:B4BD reg_si--; } } } // seg000:B4BE reg_si++; } // seg000:B4D9 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 8FF0 void do_intro_and_menu() { RETLOC(9280); RETLOC(927D); RETLOC(926E); RETLOC(926A); RETLOC(9236); RETLOC(922F); RETLOC(922C); RETLOC(9229); RETLOC(9204); RETLOC(9201); RETLOC(91FB); RETLOC(91E1); RETLOC(91DA); RETLOC(91CC); RETLOC(91B9); RETLOC(91AF); RETLOC(9192); RETLOC(9164); RETLOC(9152); RETLOC(914F); RETLOC(914C); RETLOC(9147); RETLOC(9142); RETLOC(913D); RETLOC(9128); RETLOC(9125); RETLOC(9122); RETLOC(911F); RETLOC(9111); RETLOC(9100); RETLOC(90FD); RETLOC(90FA); RETLOC(90F7); RETLOC(90F4); RETLOC(90CE); RETLOC(90CB); RETLOC(90C2); RETLOC(90BF); RETLOC(90BC); RETLOC(90B9); RETLOC(909C); RETLOC(908C); RETLOC(9085); assert(reg_eip == 0x8FF0); PUSH(bp); MOV(bp, sp); reg_sp -= 0x16; PUSH(si); PUSH(di); W_MEMW(word_1DADE, 0); W_MEMW(num_keens_left, 4); W_MEMW(ray_gun_charge, 0); W_MEMW(got_pogo, 0); W_MEMW(got_part_1, 0); W_MEMW(got_part_2, 0); W_MEMW(got_part_3, 0); W_MEMW(got_part_4, 0); W_MEMW(reg_bp - 8, 0); // seg000:903D while ((short)MEMW(reg_bp - 8) < 8) { // seg000:902F reg_bx = MEMW(reg_bp - 8); reg_bx <<= 1; W_MEMW(word_1DB2E + reg_bx, 0); W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) + 1); } // seg000:9043 W_MEMW(got_yellow_keycard, 0); W_MEMW(got_red_keycard, 0); W_MEMW(got_green_keycard, 0); W_MEMW(got_blue_keycard, 0); W_MEMW(reg_bp - 8, 0); // seg000:9070 while ((short)MEMW(reg_bp - 8) < 0x10) { // seg000:9062 reg_bx = MEMW(reg_bp - 8); reg_bx <<= 1; W_MEMW(word_1DAF6 + reg_bx, 0); W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) + 1); } do { // seg000:9076 W_MEMW(word_186A2, 0); W_MEMW(word_19CB2, 3); EMU_CALL(a_clear_overlay, 9085, do_intro_and_menu); PUSHI(90); EMU_CALL(a_load_level_data, 908C, do_intro_and_menu); reg_sp += 2; // seg000:908E if (MEMW(word_158FC) != 0) { // seg000:9095 PUSHI(90); EMU_CALL(a_load_level_data, 909C, do_intro_and_menu); reg_sp += 2; W_MEMD(scroll_x_lo, 0x68000); W_MEMD(scroll_y_lo, 0x2000); EMU_CALL(a_clear_overlay, 90B9, do_intro_and_menu); EMU_CALL(a_sync_drawing, 90BC, do_intro_and_menu); EMU_CALL(a_draw_screen, 90BF, do_intro_and_menu); EMU_CALL(a_fade_in, 90C2, do_intro_and_menu); reg_di = 0x960; reg_si = 4; EMU_CALL(a_scroll_up_logo, 90CB, do_intro_and_menu); EMU_CALL(a_fade_out, 90CE, do_intro_and_menu); W_MEMW(word_158FC, 0); } // seg000:90D4 reg_di = 0x960; reg_si = 0; W_MEMD(scroll_x_lo, 0x2000); W_MEMD(scroll_y_lo, 0x2000); EMU_CALL(a_clear_overlay, 90F4, do_intro_and_menu); EMU_CALL(a_sync_drawing, 90F7, do_intro_and_menu); EMU_CALL(a_do_draw_mural, 90FA, do_intro_and_menu); EMU_CALL(a_fade_in, 90FD, do_intro_and_menu); EMU_CALL(a_clear_keys, 9100, do_intro_and_menu); while(1) { // seg000:9100 reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x10; PUSH(ax); EMU_CALL(a_handle_ctrl, 9111, do_intro_and_menu); reg_sp += 6; reg_ax = reg_bp - 0x10; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 911F, do_intro_and_menu); EMU_CALL(a_sync_drawing, 9122, do_intro_and_menu); EMU_CALL(a_draw_screen, 9125, do_intro_and_menu); EMU_CALL(a_handle_global_keys, 9128, do_intro_and_menu); // seg000:9128 if (reg_ax != 0) { // seg000:912C MOV(bx, si); if (reg_bx <= 3) { // seg000:9133 switch(reg_bx) { case 0: // seg000:913A EMU_CALL(a_do_draw_mural, 913D, do_intro_and_menu); break; case 1: // seg000:913F EMU_CALL(a_do_about_us, 9142, do_intro_and_menu); break; case 2: // seg000:9144 EMU_CALL(a_do_scores, 9147, do_intro_and_menu); break; case 3: // seg000:9149 EMU_CALL(a_show_ordering_info, 914C, do_intro_and_menu); EMU_CALL(a_draw_screen, 914F, do_intro_and_menu); EMU_CALL(a_show_ordering_info, 9152, do_intro_and_menu); break; } } } // seg000:9152 MOV(ax, di); reg_ax -= MEMW(sprite_sync); MOV(di, ax); // seg000:915A if ((short)reg_ax <= 0) { // seg000:9161 EMU_CALL(a_fade_out, 9164, do_intro_and_menu); MOV(ax, si); // seg000:9166 if (reg_ax == 0) { // seg000:9177 W_MEMD(scroll_x_lo, 0x3f000); W_MEMD(scroll_y_lo, 0x1c00); EMU_CALL(a_do_about_us, 9192, do_intro_and_menu); } else if (reg_ax == 1) { // seg000:9194 W_MEMD(scroll_x_lo, 0x54000); W_MEMD(scroll_y_lo, 0x2000); EMU_CALL(a_do_scores, 91AF, do_intro_and_menu); } else if (reg_ax == 2) { // seg000:91B1 reg_si++; PUSHI(1); EMU_CALL(a_do_ordering_info, 91B9, do_intro_and_menu); reg_sp += 2; reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x16; PUSH(ax); EMU_CALL(a_handle_ctrl, 91CC, do_intro_and_menu); reg_sp += 6; reg_ax = reg_bp - 0x16; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 91DA, do_intro_and_menu); PUSHI(1); EMU_CALL(a_translate_key, 91E1, do_intro_and_menu); reg_sp += 2; // seg000:91E3 if (reg_ax != 0 || MEMW(reg_bp - 4) != 0 || MEMW(reg_bp - 2) != 0) { // seg000:91F3 reg_di = 0x960; goto loc_922F; } // seg000:91F8 EMU_CALL(a_fade_out, 91FB, do_intro_and_menu); } // seg000:91FB reg_di = 0x960; EMU_CALL(a_sync_drawing, 9201, do_intro_and_menu); EMU_CALL(a_draw_screen, 9204, do_intro_and_menu); // seg000:9204 reg_si++; MOV(ax, si); // seg000:9207 if (reg_ax == 4) { // seg000:920C reg_si = 0; W_MEMD(scroll_x_lo, 0x2000); W_MEMW(scroll_y_lo, 0x2000); EMU_CALL(a_clear_overlay, 9229, do_intro_and_menu); EMU_CALL(a_do_draw_mural, 922C, do_intro_and_menu); } // seg000:922C EMU_CALL(a_fade_in, 922F, do_intro_and_menu); } loc_922F: // seg000:922F PUSHI(1); EMU_CALL(a_translate_key, 9236, do_intro_and_menu); reg_sp += 2; // seg000:9238 if (reg_ax != 0) break; // seg000:923C if (MEMW(reg_bp - 4) != 0) break; // seg000:9242 if (MEMW(reg_bp - 2) != 0) break; // seg000:9248 if (MEMW(word_1D748) != 0) break; } // seg000:9252 W_MEMW(word_1D748, 0); // seg000:9258 if (MEMD(scroll_x_lo) != 0x2000) { // seg000:9267 EMU_CALL(a_fade_out, 926A, do_intro_and_menu); } // seg000:926A PUSH(si); EMU_CALL(a_draw_title, 926E, do_intro_and_menu); reg_sp += 2; W_MEMW(reg_bp - 0xa, reg_ax); // seg000:9273 } while (reg_ax == 0); // seg000:927A EMU_CALL(a_clear_keys, 927D, do_intro_and_menu); EMU_CALL(a_fade_out, 9280, do_intro_and_menu); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // A262 void scroll_up_logo() { RETLOC(A311); RETLOC(A2FE); RETLOC(A2F0); RETLOC(A2AA); RETLOC(A2A3); RETLOC(A297); RETLOC(A294); assert(reg_eip == 0xA262); PUSH(bp); MOV(bp, sp); reg_sp -= 0x10; PUSH(si); PUSH(di); W_MEMD(scroll_x_lo, 0x68000); W_MEMW(scroll_y_lo, 0x2000); W_MEMW(reg_bp - 8, 0x12c); reg_di = 0xc8; reg_si = 0; W_MEMW(reg_bp - 0xa, 0); EMU_CALL(a_clear_overlay, A294, scroll_up_logo); EMU_CALL(a_clear_keys, A297, scroll_up_logo); W_MEMW(word_1D748, 0); while(1) { // seg000:A322 reg_ax = MEMW(reg_bp - 8); W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) - 1); if (reg_ax == 0) break; // seg000:A2A0 EMU_CALL(a_sync_drawing, A2A3, scroll_up_logo); W_MEMW(word_1D740, reg_di); EMU_CALL(a_draw_screen, A2AA, scroll_up_logo); MOV(ax, si); if (reg_ax == 0) { // seg000:A2B7 W_MEMW(reg_bp - 0xa, MEMW(reg_bp - 0xa) + 1); reg_ax = MEMW(reg_bp - 0xa); // seg000:A2BD if ((short)reg_ax > 0x1e) { // eg000:A2C2 W_MEMW(reg_bp - 0xa, 0); reg_si++; W_MEMW(draw_func, a_sub_A1D4); } } else if (reg_ax == 1) { // seg000:A2B0 if (reg_ax == 1) { // seg000:A2D0 if ((short)reg_di > 0x37) { // seg000:A2D5 reg_di--; } else { // seg000:A2D8 reg_si++; W_MEMW(draw_func, a_show_logo_text); } } } // seg000:A2DF reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x10; PUSH(ax); EMU_CALL(a_handle_ctrl, A2F0, scroll_up_logo); reg_sp += 6; reg_ax = reg_bp - 0x10; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, A2FE, scroll_up_logo); // seg000:A2FE if (MEMW(reg_bp - 4) == 0 && MEMW(reg_bp - 2) == 0) { // seg000:A30A PUSHI(1); EMU_CALL(a_translate_key, A311, scroll_up_logo); reg_sp += 2; if (reg_ax == 0) continue; } // seg000:A317 W_MEMW(reg_bp - 8, 0); W_MEMW(word_1D748, 1); } // seg000:A32F W_MEMW(draw_func, 0); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 97D3 void do_draw_mural() { RETLOC(97DF); RETLOC(97E5); RETLOC(97EE); RETLOC(97E2); assert(reg_eip == 0x97D3); PUSH(bp); MOV(bp, sp); W_MEMW(draw_func, a_draw_mural); EMU_CALL(a_sync_drawing, 97DF, do_draw_mural); EMU_CALL(a_draw_screen, 97E2, do_draw_mural); EMU_CALL(a_draw_screen, 97E5, do_draw_mural); W_MEMW(draw_func, 0); EMU_CALL(a_clear_keys, 97EE, do_draw_mural); POP(bp); RET; } // 97AB void draw_mural() { RETLOC(97CE); RETLOC(97BC); assert(reg_eip == 0x97AB); PUSH(bp); MOV(bp, sp); PUSHI(0); PUSHI(1); PUSHI(8); EMU_CALL(a_draw_filter, 97BC, draw_mural); reg_sp += 6; PUSHI(2); PUSHI(0xb6); PUSHI(0x10); EMU_CALL(a_draw_filter, 97CE, draw_mural); reg_sp += 6; POP(bp); RET; } // 60BE void draw_box_opening2() { RETLOC(6113); RETLOC(610C); RETLOC(6102); RETLOC(60EE); RETLOC(60E2); assert(reg_eip == 0x60BE); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 4); reg_si = MEMW(reg_bp + 6); // seg000:60C9 if ((short)reg_di > 2) { // seg000:60CE if ((short)reg_si > 2) { // seg000:60D3 MOV(ax, si); reg_ax += 0xfffe; PUSH(ax); MOV(ax, di); reg_ax += 0xfffe; PUSH(ax); EMU_CALL(a_draw_box_opening2, 60E2, draw_box_opening2); reg_sp += 4; } else { // seg000:60E4 PUSH(si); MOV(ax, di); reg_ax += 0xfffe; PUSH(ax); EMU_CALL(a_draw_box_opening, 60EE, draw_box_opening2); reg_sp += 4; } } else if ((short)reg_si > 2) { // seg000:60F8 MOV(ax, si); reg_ax += 0xfffe; PUSH(ax); PUSH(di); EMU_CALL(a_sub_614B, 6102, draw_box_opening2); reg_sp += 4; } // seg000:6105 PUSHI(1); EMU_CALL(a_delay, 610C, draw_box_opening2); reg_sp += 2; PUSH(si); PUSH(di); EMU_CALL(a_draw_box, 6113, draw_box_opening2); reg_sp += 4; POP(di); POP(si); POP(bp); RET; } // 611A void draw_box_opening() { RETLOC(6145); RETLOC(613C); RETLOC(6132); assert(reg_eip == 0x611A); PUSH(bp); MOV(bp, sp); PUSH(si); reg_si = MEMW(reg_bp + 4); // seg000:6121 if ((short)reg_si > 2) { // seg000:6126 PUSHI(MEMW(reg_bp + 6)); MOV(ax, si); reg_ax += 0xfffe; PUSH(ax); EMU_CALL(a_draw_box_opening, 6132, draw_box_opening); // recursive call reg_sp += 4; } // seg000:6135 PUSHI(1); EMU_CALL(a_delay, 613C, draw_box_opening); reg_sp += 2; // seg000:613E PUSHI(MEMW(reg_bp + 6)); PUSH(si); EMU_CALL(a_draw_box, 6145, draw_box_opening); reg_sp += 4; POP(si); POP(bp); RET; } // 8F90 void sub_8F90() { PUSH(bp); MOV(bp, sp); reg_sp -= 2; PUSH(si); PUSH(di); reg_di = 0; // seg000:8FE4 while ((short)reg_di < (short)MEMW(map_height_in_tiles)) { // seg000:8F9B reg_si = 0; // seg000:8FDD while ((short)reg_si < (short)MEMW(map_width_intiles)) { // seg000:8F9F MOV(ax, di); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_si; reg_ax <<= 1; // seg000:8FA9 reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); W_MEMW(reg_bp - 2, reg_ax); // seg000:8FB5 keen if (reg_ax == 0xff) { // seg000:8FBA int tmp1 = (short)reg_si; tmp1 = tmp1 << 0xc; reg_bx = MEMW(reg_bp + 4); W_MEMD(reg_bx, tmp1); // seg000:8FCA tmp1 = (short)reg_di; tmp1 = tmp1 << 0xc; reg_bx = MEMW(reg_bp + 6); W_MEMD(reg_bx, tmp1); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:8FDC reg_si++; } // seg000:8FE3 reg_di++; } // seg000:8FEA POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // A1D4 void sub_A1D4() { RETLOC(A1E6); assert(reg_eip == 0xA1D4); PUSH(bp); MOV(bp, sp); PUSHI(0xa); PUSHI(MEMW(word_1D740)); PUSHI(0x10); EMU_CALL(a_draw_filter, A1E6, sub_A1D4); reg_sp += 6; POP(bp); RET; } // 928F void draw_title() { RETLOC(92B4); RETLOC(92B1); RETLOC(92AC); RETLOC(92A9); RETLOC(95C0); RETLOC(95BD); RETLOC(95B1); RETLOC(95AB); RETLOC(95A1); RETLOC(959E); RETLOC(9594); RETLOC(9591); RETLOC(9587); RETLOC(957A); RETLOC(955F); RETLOC(9558); RETLOC(95CA); RETLOC(92EC); RETLOC(92DE); RETLOC(92CB); RETLOC(94FA); RETLOC(93A6); RETLOC(9377); RETLOC(935E); RETLOC(9354); RETLOC(930F); RETLOC(940E); RETLOC(93F4); RETLOC(93ED); RETLOC(93DF); RETLOC(93C9); RETLOC(953D); RETLOC(9536); RETLOC(9503); RETLOC(94F1); RETLOC(94D7); RETLOC(94D0); RETLOC(94C2); RETLOC(94AC); RETLOC(9489); RETLOC(945A); RETLOC(9441); RETLOC(9437); assert(reg_eip == 0x928F); PUSH(bp); MOV(bp, sp); reg_sp -= 0x20; PUSH(si); PUSH(di); do { // seg000:9297 if (MEMD(scroll_x_lo) != 0x2000) { // seg000:92A6 EMU_CALL(a_start_menu, 92A9, draw_title); EMU_CALL(a_fade_in, 92AC, draw_title); } else { // seg000:92AE EMU_CALL(a_start_menu, 92B1, draw_title); } // seg000:92B1 EMU_CALL(a_clear_keys, 92B4, draw_title); W_MEMW(reg_bp - 2, 0); reg_di = 0; W_MEMW(reg_bp - 8, 0x14); do { // seg000:92C0 reg_si = 0; // seg000:92F3 while ((short)reg_si < 6) { // seg000:92C4 PUSHI(1); EMU_CALL(a_delay, 92CB, draw_title); reg_sp += 2; // seg000:92CD reg_ax = reg_bp - 0xe; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x14; PUSH(ax); EMU_CALL(a_handle_ctrl, 92DE, draw_title); reg_sp += 6; // seg000:92E1 reg_ax = reg_bp - 0x14; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 92EC, draw_title); // seg000:92EC if (MEMW(reg_bp - 0xe) != 8) break; // seg000:92F2 reg_si++; } // seg000:92F8 MOV(ax, di); reg_ax += 9; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 930F, draw_title); reg_sp += 6; reg_di++; MOV(ax, di); // seg000:9315 if ((short)reg_ax > 2) { // seg000:931A reg_di = 0; } // seg000:931C reg_ax = MEMW(reg_bp - 0xe); // seg000:931F if (reg_ax == 0) { // seg000:932E if (MEMW(reg_bp - 2) != 0) { // seg000:9334 W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) - 1); reg_si = 0; // seg000:9385 while ((short)reg_si < 8) { // seg000:933B MOV(ax, di); reg_ax += 9; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax -= reg_si; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 9354, draw_title); reg_sp += 6; // seg000:9357 PUSHI(1); EMU_CALL(a_delay, 935E, draw_title); reg_sp += 2; // seg000:9360 PUSHI(0x20); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax -= reg_si; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 9377, draw_title); reg_sp += 6; // seg000:937A reg_di++; MOV(ax, di); // seg000:937D if ((short)reg_ax > 2) { // seg000:9382 reg_di = 0; } // seg000:9384 reg_si++; } } else { // seg000:938C W_MEMW(reg_bp - 2, 7); PUSHI(0x20); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 93A6, draw_title); reg_sp += 6; } // seg000:93A9 reg_ax = MEMW(dword_1DB48); reg_ax += MEMW(reg_bp - 2); W_MEMW(word_1B348, reg_ax); MOV(ax, di); reg_ax += 9; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 93C9, draw_title); reg_sp += 6; while(1) { // seg000:93F6 reg_ax = MEMW(reg_bp - 8); W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) - 1); // seg000:93FC if (reg_ax == 0) break; // seg000:9400 if (MEMW(reg_bp - 0xe) == 8) break; // seg000:93CE reg_ax = reg_bp - 0xe; PUSHI(SegValue(ss)); PUSH(ax); reg_ax = 1; PUSH(ax); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x1a; PUSH(ax); EMU_CALL(a_handle_ctrl, 93DF, draw_title); reg_sp += 6; // seg000:93E2 reg_ax = reg_bp - 0x1a; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 93ED, draw_title); // seg000:93ED PUSHI(1); EMU_CALL(a_delay, 93F4, draw_title); reg_sp += 2; } // seg000:9406 W_MEMW(reg_bp - 8, 0x14); EMU_CALL(a_clear_keys, 940E, draw_title); } else if (reg_ax != 4) { // seg000:932B // goto // seg000:94F3 PUSHI(7); EMU_CALL(a_delay, 94FA, draw_title); reg_sp += 2; } else { // seg000:9328 // goto // seg000:9411 if ((short)MEMW(reg_bp - 2) < 7) { // seg000:9417 W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) + 1); reg_si = 0; // seg000:9468 while ((short)reg_si < 8) { // seg000:941E MOV(ax, di); reg_ax += 9; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += reg_si; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 9437, draw_title); reg_sp += 6; // seg000:943A PUSHI(1); EMU_CALL(a_delay, 9441, draw_title); reg_sp += 2; // seg000:9443 PUSHI(0x20); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += reg_si; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 945A, draw_title); reg_sp += 6; // seg000:945D reg_di++; MOV(ax, di); // seg000:9460 if ((short)reg_ax > 2) { // seg000:9465 reg_di = 0; } // seg000:9467 reg_si++; } } else { // seg000:946F W_MEMW(reg_bp - 2, 0); PUSHI(0x20); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 9489, draw_title); reg_sp += 6; } // seg000:948C reg_ax = MEMW(dword_1DB48); reg_ax += MEMW(reg_bp - 2); W_MEMW(word_1B348, reg_ax); MOV(ax, di); reg_ax += 9; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 94AC, draw_title); reg_sp += 6; while(1) { // seg000:94D9 reg_ax = MEMW(reg_bp - 8); W_MEMW(reg_bp - 8, MEMW(reg_bp - 8) - 1); // seg000:94DF if (reg_ax == 0) break; // seg000:94E3 if (MEMW(reg_bp - 0xe) == 8) break; // seg000:94B1 reg_ax = reg_bp - 0xe; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x20; PUSH(ax); EMU_CALL(a_handle_ctrl, 94C2, draw_title); reg_sp += 6; // seg000:94C5 reg_ax = reg_bp - 0x20; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 94D0, draw_title); // seg000:94D0 PUSHI(1); EMU_CALL(a_delay, 94D7, draw_title); reg_sp += 2; } // seg000:94E9 W_MEMW(reg_bp - 8, 0x14); EMU_CALL(a_clear_keys, 94F1, draw_title); } // seg000:94FC PUSHI(1); EMU_CALL(a_translate_key, 9503, draw_title); reg_sp += 2; reg_ax &= 0xff; W_MEMW(reg_bp - 6, reg_ax); // seg000:950B if (reg_ax != 0 && MEMW(ctrl_type) != 0) { // seg000:9516 W_MEMW(reg_bp - 0xc, 1); } // seg000:951B if ((MEMW(reg_bp - 6) == 0x20 || MEMW(reg_bp - 6) == 0xd) && MEMW(ctrl_type) == 0) { // seg000:952E W_MEMW(reg_bp - 0xc, 1); } // seg000:9533 EMU_CALL(a_handle_global_keys, 9536, draw_title); // seg000:9536 if (reg_ax == 0) continue; EMU_CALL(a_start_menu, 953D, draw_title); reg_ax = MEMW(dword_1DB48); reg_ax += MEMW(reg_bp - 2); W_MEMW(word_1B348, reg_ax); // seg000:9546 } while (MEMW(reg_bp - 0xc) == 0 && MEMW(reg_bp - 0xa) == 0); // seg000:9555 EMU_CALL(a_clear_keys, 9558, draw_title); PUSHI(8); EMU_CALL(a_delay, 955F, draw_title); reg_sp += 2; reg_bx = MEMW(reg_bp - 2); // seg000:9564 if (reg_bx <= 7) { bool do_fade_out = false; // seg000:9569 switch(reg_bx) { case 0: // seg000:9570 W_MEMW(reg_bp - 4, 1); break; case 1: // seg000:9577 EMU_CALL(a_continue_game, 957A, draw_title); W_MEMW(reg_bp - 4, reg_ax); break; case 2: // seg000:957F W_MEMW(reg_bp - 4, 0); EMU_CALL(a_do_story, 9587, draw_title); break; case 3: // seg000:9589 W_MEMW(reg_bp - 4, 0); EMU_CALL(a_fade_out, 9591, draw_title); EMU_CALL(a_show_about_us, 9594, draw_title); do_fade_out = true; break; case 4: // seg000:9596 W_MEMW(reg_bp - 4, 0); EMU_CALL(a_fade_out, 959E, draw_title); EMU_CALL(a_show_scores, 95A1, draw_title); do_fade_out = true; break; case 5: // seg000:95A3 W_MEMW(reg_bp - 4, 0); EMU_CALL(a_fade_out, 95AB, draw_title); PUSHI(0); EMU_CALL(a_do_ordering_info, 95B1, draw_title); reg_sp += 2; do_fade_out = true; break; case 6: // seg000:95B5 W_MEMW(reg_bp - 4, 0); EMU_CALL(a_fade_out, 95BD, draw_title); EMU_CALL(a_do_previews, 95C0, draw_title); do_fade_out = true; break; case 7: // seg000:95C2 W_MEMW(reg_bp - 4, 0); do_fade_out = true; break; } // seg000:95C7 if (do_fade_out) { EMU_CALL(a_fade_out, 95CA, draw_title); } } // seg000:95CA } while (MEMW(reg_bp - 2) != 7 && MEMW(reg_bp - 4) == 0); // seg000:95D9 if (MEMW(reg_bp - 4) != 0) { // seg000:95DF reg_ax = 1; } else { // seg000:95E4 reg_ax = 0; } // seg000:95E6 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 96B0 void start_menu() { RETLOC(96DA); RETLOC(96D1); RETLOC(96CE); assert(reg_eip == 0x96B0); PUSH(bp); MOV(bp, sp); W_MEMD(scroll_x_lo, 0x2000); W_MEMD(scroll_y_lo, 0x2000); EMU_CALL(a_clear_overlay, 96CE, start_menu); EMU_CALL(a_do_draw_mural, 96D1, start_menu); W_MEMW(draw_func, a_draw_menu); EMU_CALL(a_draw_screen, 96DA, start_menu); W_MEMW(draw_func, 0); POP(bp); RET; } // 95FD void draw_menu() { RETLOC(9696); RETLOC(9673); RETLOC(966A); RETLOC(9661); RETLOC(9658); RETLOC(964F); RETLOC(9646); RETLOC(963D); RETLOC(9634); RETLOC(962B); RETLOC(960B); assert(reg_eip == 0x95fd); PUSH(bp); MOV(bp, sp); PUSHI(0xa); PUSHI(0x12); EMU_CALL(a_draw_box_opening2, 960B, draw_menu); reg_sp += 4; int tmp1 = (short)MEMW(word_1B2D2); W_MEMD(dword_1DB44, tmp1); // related to the x position of the menu option selector tmp1 = (short)MEMW(word_1B348); W_MEMD(dword_1DB48, tmp1); // related to the y position of the menu option selector PUSHI(aNewGame); EMU_CALL(a_draw_string, 962B, draw_menu); reg_sp += 2; PUSHI(aContinueGame); EMU_CALL(a_draw_string, 9634, draw_menu); reg_sp += 2; PUSHI(aStory); EMU_CALL(a_draw_string, 963D, draw_menu); reg_sp += 2; PUSHI(aAboutId___); EMU_CALL(a_draw_string, 9646, draw_menu); reg_sp += 2; PUSHI(aHighScores); EMU_CALL(a_draw_string, 964F, draw_menu); reg_sp += 2; PUSHI(aOrderingInfo); EMU_CALL(a_draw_string, 9658, draw_menu); reg_sp += 2; PUSHI(aPreviews); EMU_CALL(a_draw_string, 9661, draw_menu); reg_sp += 2; PUSHI(aRestartDemo); EMU_CALL(a_draw_string, 966A, draw_menu); reg_sp += 2; PUSHI(aUseThe); EMU_CALL(a_draw_string, 9673, draw_menu); reg_sp += 2; reg_bx = MEMW(ctrl_type); // seg000:9679 if (reg_bx <= 3) { // seg000:967E switch(reg_bx) { case 0: // seg000:9685 reg_ax = aArrows; break; case 1: // seg000:968A reg_ax = aMouse; break; case 2: case 3: // seg000:968F reg_ax = aJoystick; break; } // seg000:9692 PUSH(ax); EMU_CALL(a_draw_string, 9696, draw_menu); reg_sp += 2; } // seg000:9698 reg_ax = MEMW(dword_1DB44); reg_ax++; W_MEMW(word_1B2D2, reg_ax); // related to the x position of the menu selector reg_ax = MEMW(dword_1DB48); W_MEMW(word_1B348, reg_ax); // related to the y position of the menu selector POP(bp); RET; } // 805E void mark_cities_done() { PUSH(bp); MOV(bp, sp); reg_sp -= 2; PUSH(si); PUSH(di); W_MEMW(reg_bp - 2, 0); // seg000:807F while ((short)MEMW(reg_bp - 2) < 0x10) { // seg000:806C reg_ax = MEMW(reg_bp - 2); reg_dx = 6; reg_ax *= reg_dx; MOV(bx, ax); W_MEMW(word_1D75E + reg_bx, 0); W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) + 1); } // seg000:8085 reg_cx = 0; // seg000:8121 while ((short)reg_cx < (short)MEMW(map_height_in_tiles)) { // seg000:808A reg_di = 0; // seg000:8117 while ((short)reg_di < (short)MEMW(map_width_intiles)) { // seg000:808F MOV (ax, cx); reg_ax *= MEMW(map_width_intiles); reg_ax += reg_di; reg_ax <<= 1; // seg000:8099 reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); reg_ax &= 0x7fff; MOV(si, ax); // seg000:80A7 if ((short)reg_ax > 0 && (short)reg_ax < 0x100) { // seg000:80B0 reg_dx = 6; reg_ax *= reg_dx; MOV(bx, ax); // seg000:80B7 if (MEMW(dword_1D756 + 2 + reg_bx) == 0) { // seg000:80BE MOV(ax, si); reg_dx = 6; reg_ax *= reg_dx; MOV(bx, ax); W_MEMW(dword_1D756 + 2 + reg_bx, reg_di); MOV(ax, si); reg_dx = 6; reg_ax *= reg_dx; MOV(dx, cx); MOV(bx, ax); W_MEMW(story_text + reg_bx, reg_dx); MOV(ax, si); reg_dx = 6; reg_ax *= reg_dx; MOV(bx, ax); W_MEMW(story_text + 2 + reg_bx, 0); MOV(ax, cx); reg_ax *= MEMW(map_width_intiles); MOV(dx, di); reg_dx += reg_ax; reg_dx++; reg_dx <<= 1; reg_bx = MEMW(tile_data_sprites); reg_bx += reg_dx; reg_ax = mem_readw(SegPhys(es) + reg_bx); reg_ax &= 0x7fff; // seg000:8102 if (reg_ax == reg_si) { // seg000:8106 reg_di++; MOV(ax, si); reg_dx = 6; reg_ax *= reg_dx; MOV(bx, ax); W_MEMW(story_text + 2 + reg_bx, 1); } } } // seg000:8116 reg_di++; } // seg000:8120 reg_cx++; } // seg000:812C POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 8F26 void show_keens_left() { RETLOC(8F88); RETLOC(8F79); RETLOC(8F48); RETLOC(8F38); assert(reg_eip == 0x8F26); PUSH(bp); MOV(bp, sp); reg_sp -= 2; PUSH(si); PUSH(di); PUSHI(4); PUSHI(0x10); EMU_CALL(a_draw_box_opening2, 8F38, show_keens_left); reg_sp += 4; reg_ax = MEMW(word_1B2D2); W_MEMW(reg_bp - 2, reg_ax); PUSHI(aKeensLeft); EMU_CALL(a_draw_string, 8F48, show_keens_left); reg_sp += 2; reg_di = MEMW(num_keens_left); if ((short)reg_di > 6) { reg_di = 6; } // seg000:8F56 reg_si = 0; // seg000:8F7D while ((short)reg_si < (short)reg_di) { // seg000:8F5A PUSHI(0x90); reg_ax = MEMW(word_1B348); reg_ax <<= 3; reg_ax += 0xb; PUSH(ax); MOV(ax, si); reg_ax <<= 1; reg_dx = MEMW(reg_bp - 2); reg_dx += reg_ax; reg_dx++; PUSH(dx); EMU_CALL(a_draw_sprite, 8F79, show_keens_left); reg_sp += 6; reg_si++; } // seg000:8F81 PUSHI(0x29); EMU_CALL(a_set_cur_sound, 8F88, show_keens_left); reg_sp += 2; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 2AE9 void detect_worldmap_col() { RETLOC(2B36); assert(reg_eip == 0x2AE9); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); int tmp1 = (MEMD(reg_si + 4) >> 9) % 4; reg_dx = MEMW(reg_si + 0x28); reg_dx <<= 2; reg_dx += tmp1 & 0xffff; MOV(di, dx); PUSHI(SegValue(ds)); PUSHI(word_1B356); tmp1 = (short)reg_di; tmp1 = tmp1 << 5; tmp1 = N_PADD(MEMD(sprite_data), tmp1); PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); reg_cx = 0x20; EMU_CALL(a_N_SCOPY, 2B36, detect_worldmap_col); // seg000:2B36 tmp1 = MEMD(reg_si + 4); tmp1 += (short)MEMW(word_1B35E); W_MEMD(reg_si + 0xc, tmp1); // seg000:2B4E tmp1 = MEMD(reg_si + 4); tmp1 += (short)MEMW(word_1B362); W_MEMD(reg_si + 0x14, tmp1); // seg000:2B66 tmp1 = MEMD(reg_si + 8); tmp1 += (short)MEMW(word_1B360); W_MEMD(reg_si + 0x10, tmp1); // seg000:2B7E tmp1 = MEMD(reg_si + 8); tmp1 += (short)MEMW(word_1B364); W_MEMD(reg_si + 0x18, tmp1); // seg000:2B96 POP(di); POP(si); POP(bp); RET; } // A616 void check_world_map_col() { RETLOC(A658); assert(reg_eip = 0xA616); PUSH(bp); MOV(bp, sp); reg_sp -= 0xe; PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); // seg000:A621 if (MEMW(god_mode) != 0) { // seg000:A628 reg_ax = 0; POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:A62D reg_ax = MEMW(reg_si + 0x20); reg_ax *= MEMW(sprite_sync); reg_dx = MEMW(reg_si + 0x1c); reg_dx += reg_ax; W_MEMW(reg_si + 0x1c, reg_dx); reg_ax = MEMW(reg_si + 0x22); reg_ax *= MEMW(sprite_sync); reg_dx = MEMW(reg_si + 0x1e); reg_dx += reg_ax; W_MEMW(reg_si + 0x1e, reg_dx); reg_ax = unk_1DC1A; PUSHI(SegValue(ds)); PUSH(ax); PUSHI(SegValue(ds)); PUSH(si); reg_cx = 0x36; EMU_CALL(a_N_SCOPY, A658, check_world_map_col); W_MEMW(reg_bp - 0xe, 0); int tmp1 = (short)MEMW(word_1DC38); W_MEMD(dword_1DC32, MEMD(dword_1DC32) + tmp1); W_MEMD(dword_1DC2A, MEMD(dword_1DC2A) + tmp1); tmp1 = MEMD(dword_1DC26); tmp1 /= 0x1000; W_MEMW(reg_bp - 6, tmp1 & 0xffff); // seg000:A68A tmp1 = MEMD(dword_1DC2E); tmp1 /= 0x1000; W_MEMW(reg_bp - 8, tmp1 & 0xffff); // seg000:A69F if ((short)MEMW(word_1DC38) > 0) { // seg000:A6A9 tmp1 = MEMD(dword_1DC32); tmp1 /= 0x1000; int tmp2 = MEMD(dword_1DC32) - (short)MEMW(word_1DC38); // seg000:A6DA if (tmp1 != tmp2) { // seg000:A6E6 // ok W_MEMW(reg_bp - 0xc, tmp1 & 0xffff); reg_ax = MEMW(reg_bp - 6); W_MEMW(reg_bp - 2, reg_ax); // seg000:A77E while ((short)MEMW(reg_bp - 2) <= (short)MEMW(reg_bp - 8)) { // seg000:A704 reg_ax = MEMW(reg_bp - 0xc); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; // seg000:A71B if (MEMW(word_13A84 + reg_bx) == 0) { // seg000:A722 reg_ax = MEMW(reg_bp - 0xc); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; reg_ax = MEMW(word_1D738); // seg000:A737 if ((mem_readw(SegPhys(es) + reg_bx) & reg_ax) == 0) { // seg000:A77B W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) + 1); continue; } } // seg000:A73C W_MEMW(reg_si + 0x22, 0); tmp1 = MEMD(dword_1DC32) + 1; tmp1 %= 0x1000; reg_ax = tmp1 & 0xffff; MOV(di, ax); W_MEMW(reg_si + 0x1e, MEMW(reg_si + 0x1e) - reg_ax); tmp1 = (short)reg_ax; W_MEMD(dword_1DC2A, MEMD(dword_1DC2A) - tmp1); MOV(ax, di); tmp1 = (short)reg_ax; W_MEMD(dword_1DC32, MEMD(dword_1DC32) - tmp1); W_MEMW(reg_bp - 0xe, 1); break; } // seg000:A789 // goto A875 } // fall to A875 } else { // seg000:A78C if ((short)MEMW(word_1DC38) < 0) { // seg000:A796 int tmp1 = MEMD(dword_1DC2A) / 0x1000; int tmp2 = MEMD(dword_1DC2A) - (short)MEMW(word_1DC38); tmp2 /= 0x1000; // seg000:A7C7 if (tmp1 != tmp2) { // seg000:A7D3 // ok // seg000:A7E5 W_MEMW(reg_bp - 0xa, tmp1 & 0xffff); reg_ax = MEMW(reg_bp - 6); W_MEMW(reg_bp - 2, reg_ax); // seg000:A86A while ((short)MEMW(reg_bp - 2) <= (short)MEMW(reg_bp - 8)) { // seg000:A7F1 reg_ax = MEMW(reg_bp - 0xa); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; // seg000:A808 if (MEMW(word_14410 + reg_bx) == 0) { // seg000:A80F reg_ax = MEMW(reg_bp - 0xa); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; reg_ax = MEMW(word_1D738); if ((mem_readw(SegPhys(es) + reg_bx) & reg_ax) == 0) { // seg000:A867 W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) + 1); continue; } } // seg000:A829 W_MEMW(reg_si + 0x22, 0); tmp1 = MEMD(dword_1DC2A) % 0x1000; reg_dx = 0x1000 - (tmp1 & 0xffff); MOV(di, dx); W_MEMW(reg_si + 0x1e, MEMW(reg_si + 0x1e) + reg_dx); MOV(ax, di); tmp1 = (short)reg_ax; W_MEMD(dword_1DC2A, MEMD(dword_1DC2A) + tmp1); MOV(ax, di); tmp1 = (short)reg_ax; W_MEMD(dword_1DC32, MEMD(dword_1DC32) + tmp1); W_MEMW(reg_bp - 0xe, 1); break; } } } } // seg000:A875 tmp1 = (short)MEMW(word_1DC36); W_MEMD(dword_1DC26, MEMD(dword_1DC26) + tmp1); tmp1 = (short)MEMW(word_1DC36); W_MEMD(dword_1DC2E, MEMD(dword_1DC2E) + tmp1); tmp1 = MEMD(dword_1DC2A) / 0x1000; W_MEMW(reg_bp - 0xa, tmp1 & 0xffff); tmp1 = MEMD(dword_1DC32) / 0x1000; W_MEMW(reg_bp - 0xc, tmp1 & 0xffff); // seg000:A8B7 if ((short)MEMW(word_1DC36) > 0) { // seg000:A8C1 tmp1 = MEMD(dword_1DC2E) / 0x1000; int tmp2 = MEMD(dword_1DC2E) - (short)MEMW(word_1DC36); tmp2 /= 0x1000; // seg000:A8F2 if (tmp1 != tmp2) { // seg000:A8FE // ok // seg000:A910 W_MEMW(reg_bp - 8, tmp1 & 0xffff); reg_ax = MEMW(reg_bp - 0xa); W_MEMW(reg_bp - 4, reg_ax); // seg000:A996 while ((short)MEMW(reg_bp - 4) <= (short)MEMW(reg_bp - 0xc)) { // seg000:A91C reg_ax = MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 8); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; // seg000:A933 if (MEMW(word_148D6 + reg_bx) == 0) { // seg000:A93A reg_ax = MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 8); reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; reg_ax = MEMW(word_1D738); if ((mem_readw(SegPhys(es) + reg_bx) & reg_ax) == 0) { // seg000:A993 W_MEMW(reg_bp - 4, MEMW(reg_bp - 4) + 1); continue; } } // seg000:A954 W_MEMW(reg_si + 0x20, 0); tmp1 = MEMD(dword_1DC2E) + 1; tmp1 %= 0x1000; reg_di = tmp1 & 0xffff; W_MEMW(reg_si + 0x1c, MEMW(reg_si + 0x1c) - reg_di); tmp1 = (short)reg_di; W_MEMD(dword_1DC26, MEMD(dword_1DC26) - tmp1); W_MEMD(dword_1DC2E, MEMD(dword_1DC2E) - tmp1); W_MEMW(reg_bp - 0xe, 1); break; } // seg000:A9A1 // goto AA8c } } else { // seg000:A9A4 if ((short)MEMW(word_1DC36) < 0) { // seg000:A9AE tmp1 = MEMD(dword_1DC26) / 0x1000; int tmp2 = MEMD(dword_1DC26) - (short)MEMW(word_1DC36); tmp2 /= 0x1000; // seg000:A9DF if (tmp1 != tmp2) { // seg000:A9EB // ok // seg000:A9FD W_MEMW(reg_bp - 6, tmp1 & 0xffff); reg_ax = MEMW(reg_bp - 0xa); W_MEMW(reg_bp - 4, reg_ax); // seg000:AA81 while ((short)MEMW(reg_bp - 4) <= (short)MEMW(reg_bp - 0xc)) { // seg000:AA09 reg_ax = MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 6); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_bx = mem_readw(SegPhys(es) + reg_bx); reg_bx <<= 1; // seg000:AA20 if (MEMW(word_13F4A + reg_bx) == 0) { // seg000:AA27 reg_ax = MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 6); reg_ax <<= 1; reg_bx = MEMW(tile_data_sprites); SegSet16(es, MEMW(tile_data_sprites + 2)); reg_bx += reg_ax; reg_ax = MEMW(word_1D738); if ((mem_readw(SegPhys(es) + reg_bx) & reg_ax) == 0) { // seg000:AA7E W_MEMW(reg_bp - 4, MEMW(reg_bp - 4) + 1); continue; } } // seg000:AA41 W_MEMW(reg_si + 0x20, 0); tmp1 = MEMD(dword_1DC26); tmp1 %= 0x1000; reg_di = 0x1000 - (tmp1 & 0xffff); W_MEMW(reg_si + 0x1c, MEMW(reg_si + 0x1c) + reg_di); tmp1 = (short)reg_di; W_MEMD(dword_1DC26, MEMD(dword_1DC26) + tmp1); W_MEMD(dword_1DC2E, MEMD(dword_1DC2E) + tmp1); W_MEMW(reg_bp - 0xe, 1); break; } } } } // seg000:AA8C reg_ax = MEMW(reg_bp - 0xe); // seg000:AA8F POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 0D52 void add_score() { RETLOC(DA3); RETLOC(D83); assert(reg_eip == 0x0D52); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(reg_bp + 4); int tmp1 = (short)reg_ax; W_MEMD(value, MEMD(value) + tmp1); tmp1 = MEMD(value); tmp1 -= MEMD(dword_19F12); if (tmp1 >= 0x4e20) { // seg000:0D7C PUSHI(0x1c); EMU_CALL(a_set_cur_sound, D83, add_score); reg_sp += 2; tmp1 = MEMD(value); tmp1 /= 0x4e20; reg_cx = tmp1 >> 16; reg_bx = tmp1 & 0xffff; reg_ax = 0x4e20; reg_dx = 0; EMU_CALL(a__LXMUL, DA3, add_score); W_MEMW(dword_19F12, reg_ax); W_MEMW(dword_19F12 + 2, reg_dx); W_MEMW(num_keens_left, MEMW(num_keens_left) + 1); } POP(bp); RET; } // BC3B // referenced through blit_funcs void blit_1() { SegSet16(ss, reg_ax); do { reg_al = mem_readb(SegPhys(es) + reg_di); reg_al &= mem_readb(SegPhys(ss) + reg_si); reg_al |= MEMB(reg_si); mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_si++; reg_di += 0x2f; reg_cx--; } while (reg_cx != 0); // seg000:BC4C reg_ax = dseg; SegSet16(ds, reg_ax); SegSet16(ss, reg_ax); RET; } // BC54 void blit_2() { SegSet16(ss, reg_ax); do { // seg000:BC56 reg_ax = mem_readw(SegPhys(es) + reg_di); reg_ax &= mem_readw(SegPhys(ss) + reg_si); reg_ax |= MEMW(reg_si); mem_writew(SegPhys(es) + reg_di, reg_ax); reg_di += 2; reg_si += 2; reg_di += 0x2e; reg_cx--; } while (reg_cx != 0); // seg000:BC67 reg_ax = dseg; SegSet16(ds, reg_ax); SegSet16(ss, reg_ax); RET; } // BC6F void blit_3() { SegSet16(ss, reg_ax); do { // seg000:BC71 reg_ax = mem_readw(SegPhys(es) + reg_di); reg_ax &= mem_readw(SegPhys(ss) + reg_si); reg_ax |= MEMW(reg_si); mem_writew(SegPhys(es) + reg_di, reg_ax); reg_di += 2; reg_al = mem_readb(SegPhys(es) + reg_di); reg_al &= mem_readb(SegPhys(ss) + reg_si + 2); reg_al |= MEMB(reg_si + 2); mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_si += 3; reg_di += 0x2d; reg_cx--; } while (reg_cx != 0); // seg000:BC8D reg_ax = dseg; SegSet16(ds, reg_ax); SegSet16(ss, reg_ax); RET; } // BC95 void blit_4() { SegSet16(ss, reg_ax); do { // seg000:BC97 reg_ax = mem_readw(SegPhys(es) + reg_di); reg_ax &= mem_readw(SegPhys(ss) + reg_si); reg_ax |= mem_readw(SegPhys(ds) + reg_si); mem_writew(SegPhys(es) + reg_di, reg_ax); reg_di += 2; // seg000:BCA0 reg_ax = mem_readw(SegPhys(es) + reg_di); reg_ax &= mem_readw(SegPhys(ss) + reg_si + 2); reg_ax |= mem_readw(SegPhys(ds) + reg_si + 2); mem_writew(SegPhys(es) + reg_di, reg_ax); reg_di += 2; // seg000:BCAB reg_si += 4; reg_di += 0x2c; reg_cx--; } while (reg_cx != 0); // seg000:BCB3 reg_ax = dseg; SegSet16(ds, reg_ax); SegSet16(ss, reg_ax); RET; } // BCBB void blit_5() { printf("blit_5\n"); reg_eip = 0xBCBB; return; } // BCEC void blit_6() { printf("blit_6\n"); reg_eip = 0xBCEC; return; } // BD1D void blit_7() { printf("blit_7\n"); reg_eip = 0xBD1D; return; } // BD59 void blit_8() { printf("blit_8\n"); reg_eip = 0xBD59; return; } // 9A24 void do_scores() { RETLOC(9A51); RETLOC(9A4E); RETLOC(9A45); RETLOC(9A42); assert(reg_eip == 0x9A24); PUSH(bp); MOV(bp, sp); W_MEMD(scroll_x_lo, 0x54000); W_MEMD(scroll_y_lo, 0x2000); EMU_CALL(a_clear_overlay, 9A42, do_scores); EMU_CALL(a_sync_drawing, 9A45, do_scores); W_MEMW(draw_func, a_draw_scores); EMU_CALL(a_draw_screen, 9A4E, do_scores); EMU_CALL(a_draw_screen, 9A51, do_scores); W_MEMW(draw_func, 0); POP(bp); RET; } // 8ADF void game_over() { RETLOC(8F20); RETLOC(8F11); RETLOC(8EF4); RETLOC(8EED); RETLOC(8EEA); RETLOC(8EDC); RETLOC(8ECB); RETLOC(8EC8); RETLOC(8EBA); RETLOC(8EB7); RETLOC(8EB2); RETLOC(8EAB); RETLOC(8EA8); RETLOC(8E98); RETLOC(8E85); RETLOC(8E77); RETLOC(8E64); RETLOC(8E55); RETLOC(8E46); RETLOC(8E38); RETLOC(8BC5); RETLOC(8BBB); RETLOC(8B86); RETLOC(8B77); RETLOC(8B74); RETLOC(8B71); RETLOC(8B12); RETLOC(8B07); RETLOC(8AF7); RETLOC(8E24); RETLOC(8D9D); RETLOC(8D8B); RETLOC(8CE0); RETLOC(8CD7); RETLOC(8CC5); RETLOC(8CBC); RETLOC(8CA7); RETLOC(8C80); RETLOC(8C59); RETLOC(8C33); RETLOC(8C07); RETLOC(8C00); RETLOC(8BEB); RETLOC(8D7D); assert(reg_eip == 0x8ADF); PUSH(bp); MOV(bp, sp); reg_sp -= 0x6a; PUSH(si); PUSH(di); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x38; PUSH(ax); PUSHI(SegValue(ds)); reg_ax = aScores__0; PUSH(ax); reg_cx = 0xd; EMU_CALL(a_N_SCOPY, 8AF7, game_over); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x6a; PUSH(ax); PUSHI(SegValue(ds)); PUSHI(aFirst); reg_cx = 0x31; EMU_CALL(a_N_SCOPY, 8B07, game_over); PUSHI(MEMW(pExt)); reg_ax = reg_bp - 0x38; PUSH(ax); EMU_CALL(a__strcat, 8B12, game_over); reg_sp += 4; reg_di = 0; reg_si = 0; // seg000:8B3F while ((short)reg_si < 7) { // seg000:8B1B MOV(bx, si); reg_bx <<= 2; int tmp1 = MEMD(dword_1DB4E + reg_bx); if (tmp1 < (int)MEMD(value)) { // seg000:8B37 MOV(ax, si); reg_ax++; MOV(di, ax); break; } // seg000:8B3E reg_si++; } // seg000:8B44 // align screen to tile boundaries int tmp1 = MEMD(scroll_x_lo); tmp1 &= 0xfffff000; W_MEMD(scroll_x_lo, tmp1); tmp1 = MEMD(scroll_y_lo); tmp1 &= 0xfffff000; W_MEMD(scroll_y_lo, tmp1); // seg000:8B6E EMU_CALL(a_clear_overlay, 8B71, game_over); EMU_CALL(a_sync_drawing, 8B74, game_over); EMU_CALL(a_draw_screen, 8B77, game_over); // seg000:8B77 if (reg_di != 0) { // seg000:8B7B PUSHI(0xd); PUSHI(0x20); EMU_CALL(a_draw_box_opening2, 8B86, game_over); reg_sp += 4; reg_ax = MEMW(word_1B2D2); W_MEMW(reg_bp - 8, reg_ax); reg_ax = MEMW(word_1B348); W_MEMW(reg_bp - 0xa, reg_ax); } else { // seg000:8B97 W_MEMW(word_1B2D2, 7); W_MEMW(word_1B348, 0xa); } // seg000:8BA3 PUSHI(7); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B2D2); reg_ax += 9; PUSH(ax); EMU_CALL(a_draw_filter, 8BBB, game_over); reg_sp += 6; // seg000:8BBE PUSHI(0x10); EMU_CALL(a_set_cur_sound, 8BC5, game_over); reg_sp += 2; // seg000:8BC7 MOV(ax, di); reg_di--; // seg000:8BCA if (reg_ax != 0) { // seg000:8BD1 reg_ax = MEMW(reg_bp - 8); reg_ax++; W_MEMW(word_1B3A4, reg_ax); W_MEMW(word_1B2D2, reg_ax); reg_ax = MEMW(reg_bp - 0xa); reg_ax += 4; W_MEMW(word_1B348, reg_ax); PUSHI(aScore); EMU_CALL(a_draw_string, 8BEB, game_over); reg_sp += 2; // seg000:8BED PUSHI(0xa); reg_ax = reg_bp - 0x18; PUSH(ax); PUSHI(MEMW(value + 2)); PUSHI(MEMW(value)); EMU_CALL(a__ltoa, 8C00, game_over); reg_sp += 8; PUSH(ax); EMU_CALL(a_draw_string, 8C07, game_over); reg_sp += 2; reg_ax = MEMW(word_1B3A4); reg_ax += 0xb; W_MEMW(word_1B2D2, reg_ax); // seg000:8C12 if (MEMW(got_part_1) != 0) { // seg000:8C19 PUSHI(0x1c0); reg_ax = MEMW(word_1B348); reg_ax += 2; reg_ax <<= 3; reg_ax += 0xfffc; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_do_overdraw, 8C33, game_over); reg_sp += 6; } // seg000:8C36 if (MEMW(got_part_2) != 0) { // seg000:8C3D PUSHI(0x1c1); reg_ax = MEMW(word_1B348); reg_ax += 2; reg_ax <<= 3; reg_ax += 0xfffc; PUSH(ax); reg_ax = MEMW(word_1B2D2); reg_ax += 2; PUSH(ax); EMU_CALL(a_do_overdraw, 8C59, game_over); reg_sp += 6; } // seg000:8C5C if (MEMW(got_part_3) != 0) { // seg000:8C63 PUSHI(0x1c2); reg_ax = MEMW(word_1B348); reg_ax += 2; reg_ax <<= 3; reg_ax += 0xfffc; PUSH(ax); reg_ax = MEMW(word_1B2D2); reg_ax += 4; PUSH(ax); EMU_CALL(a_do_overdraw, 8C80, game_over); reg_sp += 6; } // seg000:8C83 if (MEMW(got_part_4) != 0) { // seg000:8C8A PUSHI(0x1c3); reg_ax = MEMW(word_1B348); reg_ax += 2; reg_ax <<= 3; reg_ax += 0xfffc; PUSH(ax); reg_ax = MEMW(word_1B2D2); reg_ax += 6; PUSH(ax); EMU_CALL(a_do_overdraw, 8CA7, game_over); reg_sp += 6; } // seg000:8CAA reg_ax = MEMW(word_1B3A4); W_MEMW(word_1B2D2, reg_ax); W_MEMW(word_1B348, MEMW(word_1B348) + 4); PUSHI(aCongratulations); EMU_CALL(a_draw_string, 8CBC, game_over); reg_sp += 2; PUSHI(aYouGot); EMU_CALL(a_draw_string, 8CC5, game_over); reg_sp += 2; // seg000:8CC7 MOV(ax, di); reg_ax *= 7; reg_dx = reg_bp - 0x6a; reg_ax += reg_dx; PUSH(ax); EMU_CALL(a_draw_string, 8CD7, game_over); reg_sp += 2; PUSHI(aPlaceEnterYourName); EMU_CALL(a_draw_string, 8CE0, game_over); reg_sp += 2; reg_si = 5; // seg000:8D81 if ((short)reg_si >= (short)reg_di) { // seg000:8CE8 MOV(bx, si); reg_bx <<= 2; int tmp1 = MEMD(dword_1DB4E + reg_bx); MOV(bx, si); reg_bx <<= 2; W_MEMD(dword_1DB52 + reg_bx, tmp1); // seg000:8D04 MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1DBA2 + reg_bx); MOV(bx, si); reg_bx <<= 1; W_MEMW(word_1DBA4 + reg_bx, reg_ax); // seg000:8D14 MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1DBB0 + reg_bx); MOV(bx, si); reg_bx <<= 1; W_MEMW(word_1DBB2 + reg_bx, reg_ax); // seg000:8D24 MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1DB6A + reg_bx); MOV(bx, si); reg_bx <<= 1; W_MEMW(word_1DB6C + reg_bx, reg_ax); // seg000:8D34 MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1DB78 + reg_bx); MOV(bx, si); reg_bx <<= 1; W_MEMW(word_1DB7A + reg_bx, reg_ax); // seg000:8D44 MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1DB94 + reg_bx); MOV(bx, si); reg_bx <<= 1; W_MEMW(word_1DB96 + reg_bx, reg_ax); // seg000:8D54 MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1DB86 + reg_bx); MOV(bx, si); reg_bx <<= 1; W_MEMW(word_1DB88 + reg_bx, reg_ax); // seg000:8D64 MOV(ax, si); reg_ax *= 0xd; reg_ax += unk_1DBBE; PUSH(ax); MOV(ax, si); reg_ax *= 0xd; reg_ax += unk_1DBCB; PUSH(ax); EMU_CALL(a__strcpy, 8D7D, game_over); reg_sp += 4; // seg000:8D80 reg_si--; } // seg000:8D88 EMU_CALL(a_clear_keys, 8D8B, game_over); PUSHI(0xc); MOV(ax, di); reg_ax *= 0xd; reg_ax += unk_1DBBE; PUSH(ax); EMU_CALL(a_get_string_input, 8D9D, game_over); reg_sp += 4; // seg000:8DA0 MOV(bx, di); reg_bx <<= 2; int tmp1 = MEMD(value); W_MEMD(dword_1DB4E + reg_bx, tmp1); MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(got_part_1); W_MEMW(word_1DB6A + reg_bx, reg_ax); MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(got_part_2); W_MEMW(word_1DB78 + reg_bx, reg_ax); MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(got_part_3); W_MEMW(word_1DB94 + reg_bx, reg_ax); MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(got_part_4); W_MEMW(word_1DB86 + reg_bx, reg_ax); // seg000:8DE1 reg_ax = 0; MOV(si, ax); W_MEMW(reg_bp - 0xe, reg_ax); // seg000:8DF6 while ((short)reg_si < 8) { // seg000:8DEA MOV(bx, si); reg_bx <<= 1; reg_ax = MEMW(word_1DB2E + reg_bx); W_MEMW(reg_bp - 0xe, MEMW(reg_bp - 0xe) + reg_ax); reg_si++; } // seg000:8DFB MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(reg_bp - 0xe); W_MEMW(word_1DBA2 + reg_bx, reg_ax); MOV(bx, di); reg_bx <<= 1; reg_ax = MEMW(word_1DB3E); W_MEMW(word_1DBB0 + reg_bx, reg_ax); // seg000:8E11 reg_ax = 0; reg_dx = 0xcc; PUSH(ax); PUSH(dx); PUSHI(SegValue(ds)); reg_ax = dword_1DB4E; PUSH(ax); reg_ax = reg_bp - 0x38; PUSH(ax); EMU_CALL(a_write_file, 8E24, game_over); reg_sp += 0xa; } do { // seg000:8E27 reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x1e; PUSH(ax); EMU_CALL(a_handle_ctrl, 8E38, game_over); reg_sp += 6; // seg000:8E3B reg_ax = reg_bp - 0x1e; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 8E46, game_over); // seg000:8E46 } while (MEMW(reg_bp - 4) != 0 || MEMW(reg_bp - 2) != 0); // seg000:8E52 EMU_CALL(a_clear_keys, 8E55, game_over); // seg000:8E55 if ((short)reg_di < 0) { reg_si = 0; // seg000:8E9F while ((short)reg_si < 0x168) { // seg000:8E5D PUSHI(1); EMU_CALL(a_delay, 8E64, game_over); reg_sp += 2; reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x24; PUSH(ax); EMU_CALL(a_handle_ctrl, 8E77, game_over); reg_sp += 6; // seg000:8E7A reg_ax = reg_bp - 0x24; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 8E85, game_over); // seg000:8E85 if (MEMW(reg_bp - 4) != 0) break; // seg000:8E8B if (MEMW(reg_bp - 2) != 0) break; // seg000:8E91 PUSHI(1); EMU_CALL(a_translate_key, 8E98, game_over); reg_sp += 2; // seg000:8E9A if (reg_ax != 0) break; // seg000:8E9E reg_si++; } } // seg000:8EA5 EMU_CALL(a_fade_out, 8EA8, game_over); EMU_CALL(a_clear_keys, 8EAB, game_over); // seg000:8EAB PUSHI(90); EMU_CALL(a_load_level_data, 8EB2, game_over); reg_sp += 2; // seg000:8EB4 EMU_CALL(a_do_scores, 8EB7, game_over); EMU_CALL(a_fade_in, 8EBA, game_over); W_MEMW(reg_bp - 0xc, 0x960); W_MEMW(on_world_map, 0); do { // seg000:8EC5 EMU_CALL(a_sync_drawing, 8EC8, game_over); EMU_CALL(a_draw_screen, 8ECB, game_over); // seg000:8ECB reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x2a; PUSH(ax); EMU_CALL(a_handle_ctrl, 8EDC, game_over); reg_sp += 6; // seg000:8EDF reg_ax = reg_bp - 0x2a; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 8EEA, game_over); EMU_CALL(a_handle_global_keys, 8EED, game_over); // seg000:8EED if (reg_ax != 0) { // seg000:8EF1 EMU_CALL(a_do_scores, 8EF4, game_over); } // seg000:8EF4 reg_ax = MEMW(reg_bp - 0xc); reg_ax -= MEMW(sprite_sync); W_MEMW(reg_bp - 0xc, reg_ax); // seg000:8EFE if (MEMW(reg_bp - 4) != 0) break; // seg000:8F04 if (MEMW(reg_bp - 2) != 0) break; // seg000:8F0A PUSHI(1); EMU_CALL(a_translate_key, 8F11, game_over); reg_sp += 2; // seg000:8F13 if (reg_ax != 0) break; // seg000:8F17 } while ((short)MEMW(reg_bp - 0xc) > 0); // seg000:8F1D EMU_CALL(a_fade_out, 8F20, game_over); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // A5BC void draw_invvid_string() { RETLOC(A600); assert(reg_eip == 0xA5BC); PUSH(bp); MOV(bp, sp); reg_sp -= 2; while(1) { // seg000:A603 reg_bx = MEMW(reg_bp + 4); W_MEMW(reg_bp + 4, MEMW(reg_bp + 4) + 1); reg_al = MEMB(reg_bx); W_MEMB(reg_bp - 1, reg_al); if (reg_al == 0) break; // seg000:A5C3 if (MEMB(reg_bp - 1) == 0xa) { // seg000:A5C9 W_MEMW(word_1B348, MEMW(word_1B348) + 1); reg_ax = MEMW(word_1B3A4); W_MEMW(word_1B2D2, reg_ax); continue; } // seg000:A5D5 if (MEMB(reg_bp - 1) == 0xd) { // seg000:A5DB reg_ax = MEMW(word_1B3A4); W_MEMW(word_1B2D2, reg_ax); continue; } // seg000:A5E3 reg_al = MEMB(reg_bp - 1); reg_ax = (char)reg_al; reg_ax += 0x80; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B2D2); W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 1); PUSH(ax); EMU_CALL(a_draw_char, A600, draw_invvid_string); reg_sp += 6; } // seg000:A612 MOV(sp, bp); POP(bp); RET; } // B750 void do_drawing() { RETLOC(B879); RETLOC(B875); RETLOC(B86F); RETLOC(B867); RETLOC(B75D); RETLOC(B75C); RETLOC(B755); RETLOC(B863); RETLOC(B85F); RETLOC(B85B); RETLOC(B857); RETLOC(B849); RETLOC(B845); RETLOC(B841); RETLOC(B83D); RETLOC(B839); RETLOC(B82F); RETLOC(B81A); RETLOC(B7F9); RETLOC(B7D8); RETLOC(B7B6); RETLOC(B7AE); PUSH(si); PUSH(di); EMU_CALL(a_sub_B87C, B755, do_drawing); // seg000:B755 reg_ax = 0x105; reg_dx = 0x3CE; EMU_INSTR(B75B, B75C, do_drawing); // out dx, ax EMU_INSTR(B75C, B75D, do_drawing); // cld // seg000:B75D reg_di = 0; W_MEMW(word_16606, reg_di); reg_ax = MEMW(scroll_y_lo + 1); // WTF? reg_ax >>= 4; reg_bx = MEMW(map_width_intiles_x2); reg_ax *= reg_bx; MOV(bx, ax); // seg000:B776 reg_ax = MEMW(scroll_x_lo + 1); reg_ax >>= 4; reg_ax <<= 1; reg_bx += reg_ax; reg_bx += MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); // seg000:B78D reg_bp = MEMW(tick_count); reg_cl = MEMB(word_19CB2); reg_bp >>= reg_cl; reg_bp &= 6; reg_bp = MEMW(word_1804C + reg_bp); W_MEMW(word_1660E, reg_bp); reg_ax = MEMW(word_186A2); // seg000:B7A5 if (reg_ax == 0) { // seg000:B7A9 EMU_INSTR(B7A9, B7AE, do_drawing); } else { // seg000:B7B1 EMU_INSTR(B7B1, B7B6, do_drawing); } // seg000:B7B6 PUSHI(MEMW(dstseg)); reg_ax = MEMW(word_16602); W_MEMW(dstseg, reg_ax); reg_cx = MEMW(sprite_draw_guard); if (reg_cx != 0) { // seg000:B7C6 reg_bp = 0; do { // seg000:B7C8 PUSH(cx); PUSHI(MEMW(word_190A2 + reg_bp)); PUSHI(MEMW(word_190A0 + reg_bp)); PUSHI(MEMW(word_1909E + reg_bp)); EMU_CALL(a_draw_sprite, B7D8, do_drawing); reg_sp += 6; POP(cx); reg_bp += 6; reg_cx--; } while (reg_cx != 0); } // seg000:B7E1 reg_cx = MEMW(overdraw_draw_guard); if (reg_cx != 0) { // seg000:B7E7 reg_bp = 0; do { // seg000:B7E9 PUSH(cx); PUSHI(MEMW(word_19CB8 + reg_bp)); PUSHI(MEMW(word_19CB6 + reg_bp)); PUSHI(MEMW(word_19CB4 + reg_bp)); EMU_CALL(a_do_overdraw, B7F9, do_drawing); reg_sp += 6; POP(cx); reg_bp += 6; reg_cx--; } while (reg_cx != 0); } // seg000:B802 reg_cx = MEMW(filter_draw_guard); if (reg_cx != 0) { // seg000:B808 reg_bp = 0; do { // seg000:B80A PUSH(cx); PUSHI(MEMW(word_19C5E + reg_bp)); PUSHI(MEMW(word_19C5C + reg_bp)); PUSHI(MEMW(word_19C5A + reg_bp)); EMU_CALL(a_draw_filter, B81A, do_drawing); reg_sp += 6; POP(cx); reg_bp += 6; reg_cx--; } while (reg_cx != 0); } // seg000:B823 POP(cx); W_MEMW(dstseg, reg_cx); reg_cx = MEMW(draw_func); if (reg_cx != 0) { // seg000:B82D EMU_CALL(reg_cx, B82F, do_drawing); } // seg000:B82F reg_cx = MEMW(ega_regen_start_addr); reg_dx = 0x3d4; reg_al = 0xc; EMU_INSTR(B838, B839, do_drawing); reg_dx++; MOV(al, ch); EMU_INSTR(B83C, B83D, do_drawing); reg_dx--; reg_al = 0xd; EMU_INSTR(B840, B841, do_drawing); reg_dx++; MOV(al, cl); EMU_INSTR(B844, B845, do_drawing); do { // seg000:B845 reg_dx = 0x3da; EMU_INSTR(B848, B849, do_drawing); } while (reg_al & 8); // seg000:B84D reg_bx = MEMW(ega_regen_start_addr); reg_dx = 0x3d4; reg_al = 0xc; EMU_INSTR(B856, B857, do_drawing); reg_dx++; MOV(al, bh); EMU_INSTR(B85A, B85B, do_drawing); reg_dx--; reg_al = 0xd; EMU_INSTR(B85E, B85F, do_drawing); reg_dx++; MOV(al, bl); EMU_INSTR(B862, B863, do_drawing); do { // seg000:B863 reg_dx = 0x3da; EMU_INSTR(B866, B867, do_drawing); } while ((reg_al & 8) == 0); // seg000:B86B reg_dx = 0x3da; EMU_INSTR(B86E, B86F, do_drawing); reg_dx = 0x3c0; reg_al = 0x33; EMU_INSTR(B874, B875, do_drawing); // seg000:B875 reg_ax = MEMW(ega_colors); EMU_INSTR(B878, B879, do_drawing); POP(di); POP(si); RET; } // seg000:0501 void slide_sprite() { PUSH(bp); MOV(bp, sp); reg_sp -= 0x0c; PUSH(si); PUSH(di); int tmp1 = MEMD(reg_bp + 4); tmp1 /= 0x100; PUSHI(tmp1 & 0xffff); tmp1 = MEMD(scroll_x_lo); tmp1 /= 0x100; tmp1 = tmp1 & 0xfff0; POP(dx); reg_dx -= tmp1 & 0xffff; W_MEMW(reg_bp - 0xa, reg_dx); // seg000:0535 tmp1 = MEMD(reg_bp + 8); tmp1 /= 0x100; PUSHI(tmp1 & 0xffff); tmp1 = MEMD(scroll_y_lo); tmp1 /= 0x100; tmp1 = tmp1 & 0xfff0; POP(dx); reg_dx -= tmp1 & 0xffff; W_MEMW(reg_bp - 0xc, reg_dx); // seg000:0561 if ((short)MEMW(reg_bp - 0xa) < -32 || (short)reg_dx < -32) { // seg000:056C reg_ax = 0; } else { // seg000:0571 reg_ax = MEMW(reg_bp - 0xa); reg_ax += 0x20; tmp1 = (short)reg_ax; tmp1 /= 8; reg_ax = tmp1 & 0xffff; reg_ax += 0xfffc; W_MEMW(reg_bp - 0xa, reg_ax); // seg000:0583 tmp1 = (short)reg_ax; tmp1 /= 2; reg_ax = tmp1 & 0xffff; W_MEMW(reg_bp - 2, reg_ax); // seg000:058C if ((short)reg_ax < 0) { // seg000:0590 W_MEMW(reg_bp - 2, 0); } else if ((short)MEMW(reg_bp - 2) > 0x15) { // seg000:059D reg_ax = 0; goto loc_665; } // seg000:05A2 reg_ax = MEMW(reg_bp - 0xa); reg_ax += MEMW(word_1B356); reg_ax--; tmp1 = (short)reg_ax; tmp1 /= 2; reg_ax = tmp1 & 0xffff; W_MEMW(reg_bp - 4, reg_ax); // seg000:05B3 if ((short)reg_ax > 0x14) { // seg000:05B8 W_MEMW(reg_bp - 4, 0x14); } else if ((short)MEMW(reg_bp - 4) < 0) { // seg000:05C5 reg_ax = 0; goto loc_665; } // seg000:05CA reg_ax = MEMW(reg_bp - 0xc); tmp1 = (short)reg_ax; tmp1 /= 0x10; reg_ax = tmp1 & 0xffff; W_MEMW(reg_bp - 6, reg_ax); // seg000:05D6 if ((short)reg_ax < 0) { // seg000:05DA W_MEMW(reg_bp - 6, 0); } else if ((short)MEMW(reg_bp - 6) > 0xd) { // seg000:05E7 reg_ax = 0; goto loc_665; } // seg000:05EB reg_ax = MEMW(reg_bp - 0xc); reg_ax += MEMW(word_1B358); reg_ax--; tmp1 = (short)reg_ax; tmp1 /= 0x10; reg_ax = tmp1 & 0xffff; W_MEMW(reg_bp - 8, reg_ax); // seg000:05FC if ((short)reg_ax > 0xd) { // seg000:0601 W_MEMW(reg_bp - 8, 0xd); } else if ((short)MEMW(reg_bp - 8) < 0) { // seg000:060E reg_ax = 0; goto loc_665; } // seg000:0612 W_MEMW(reg_bp - 0xa, MEMW(reg_bp - 0xa) + 4); W_MEMW(reg_bp - 0xc, MEMW(reg_bp - 0xc) + 0x20); reg_di = MEMW(reg_bp - 6); // seg000:063F while ((short)reg_di <= (short)MEMW(reg_bp - 8)) { // seg000:061F reg_si = MEMW(reg_bp - 2); // seg000:0639 while ((short)reg_si <= (short)MEMW(reg_bp - 4)) { // seg000:0624 MOV(ax, di); reg_ax *= 0x15; reg_ax += reg_si; reg_bx = MEMW(sprite_scratch_back); W_MEMW(reg_bx, reg_ax); W_MEMW(sprite_scratch_back, MEMW(sprite_scratch_back) + 2); reg_si++; } // seg000:063E reg_di++; } // seg000:0644 reg_bx = MEMW(sprite_scratch_overdraw); reg_ax = MEMW(reg_bp - 0xa); W_MEMW(reg_bx, reg_ax); // seg000:064D reg_ax = MEMW(reg_bp - 0xc); W_MEMW(reg_bx + 2, reg_ax); // seg000:0653 reg_ax = MEMW(reg_bp + 12); W_MEMW(reg_bx + 4, reg_ax); // seg000:0659 W_MEMW(overdraw_draw_guard, MEMW(overdraw_draw_guard) + 1); W_MEMW(sprite_scratch_overdraw, MEMW(sprite_scratch_overdraw) + 6); reg_ax = 1; } loc_665: // seg000:0665 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // seg000:A1EB void show_logo_text() { RETLOC(A25D); RETLOC(A24B); RETLOC(A239); RETLOC(A227); RETLOC(A212); RETLOC(A200); assert(reg_eip == 0xA1EB); PUSH(bp); MOV(bp, sp); PUSHI(8); reg_ax = MEMW(word_1D740); reg_ax += 0xfff6; PUSH(ax); PUSHI(0x16); EMU_CALL(a_draw_filter, A200, show_logo_text); reg_sp += 6; PUSHI(0xa); PUSHI(MEMW(word_1D740)); PUSHI(0x10); EMU_CALL(a_draw_filter, A212, show_logo_text); reg_sp += 6; PUSHI(9); reg_ax = MEMW(word_1D740); reg_ax += 0x20; PUSH(ax); PUSHI(0x12); EMU_CALL(a_draw_filter, A227, show_logo_text); reg_sp += 6; PUSHI(0xf); PUSHI(0x63); PUSHI(0x15); EMU_CALL(a_draw_filter, A239, show_logo_text); reg_sp += 6; PUSHI(0x11); PUSHI(0x72); PUSHI(0x13); EMU_CALL(a_draw_filter, A24B, show_logo_text); reg_sp += 6; PUSHI(0x10); PUSHI(0x9F); PUSHI(0x13); EMU_CALL(a_draw_filter, A25D, show_logo_text); reg_sp += 6; POP(bp); RET; } // 0983 void show_image_file() { RETLOC(0AEC); RETLOC(0AE6); RETLOC(0AD9); RETLOC(0AB9); RETLOC(0AA6); RETLOC(0A99); RETLOC(0A8C); RETLOC(0A79); RETLOC(0A6C); RETLOC(0A5F); RETLOC(0A4C); RETLOC(0A3F); RETLOC(0A32); RETLOC(0A1F); RETLOC(0A12); RETLOC(09FD); RETLOC(09F2); RETLOC(09EF); RETLOC(09BA); RETLOC(09A6); PUSH(bp); MOV(bp, sp); reg_sp -= 0xe; PUSH(si); PUSH(di); int tmp1 = MEMD(level_data); tmp1 += 0x8000; W_MEMD(reg_bp - 4, tmp1); PUSHI(tmp1 >> 16); PUSHI(MEMW(reg_bp - 4)); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_map_file_to_mem, 09A6, show_image_file); reg_sp += 6; // seg000:09A9 PUSHI(MEMW(level_data + 2)); PUSHI(MEMW(level_data)); PUSHI(MEMW(reg_bp - 2)); PUSHI(MEMW(reg_bp - 4)); EMU_CALL(a_sub_C513, 09BA, show_image_file); reg_sp += 8; // seg000:09BD reg_ax = MEMW(reg_bp - 2); W_MEMW(reg_bp - 8, reg_ax); reg_ax += 0x200; W_MEMW(reg_bp - 0xa, reg_ax); reg_ax += 0x200; W_MEMW(reg_bp - 0xc, reg_ax); reg_ax += 0x200; W_MEMW(reg_bp - 0xe, reg_ax); // seg000:09D5 reg_di = 0; reg_si = 4; W_MEMD(scroll_y_lo, 0); W_MEMD(scroll_x_lo, 0); EMU_CALL(a_sync_drawing, 09EF, show_image_file); EMU_CALL(a_draw_screen, 09F2, show_image_file); // seg000:09F2 PUSHI(5); PUSHI(0x3ce); EMU_CALL(a__outport, 09FD, show_image_file); reg_sp += 4; W_MEMW(reg_bp - 6, 0); // seg000:0AC5 while ((short)MEMW(reg_bp - 6) < 0xc8) { // seg000:0A08 PUSHI(2); PUSHI(0x3c4); EMU_CALL(a__outportb, 0A12, show_image_file); reg_sp += 4; // seg000:0A15 PUSHI(1); PUSHI(0x3c5); EMU_CALL(a__outportb, 0A1F, show_image_file); reg_sp += 4; // seg000:0A22 PUSHI(0x28); PUSH(si); PUSHI(MEMW(dstseg)); PUSH(di); PUSHI(MEMW(reg_bp - 8)); EMU_CALL(a__movedata, 0A32, show_image_file); reg_sp += 0xa; // seg000:0A35 PUSHI(2); PUSHI(0x3c4); EMU_CALL(a__outportb, 0A3F, show_image_file); reg_sp += 4; // seg000:0A42 PUSHI(2); PUSHI(0x3c5); EMU_CALL(a__outportb, 0A4C, show_image_file); reg_sp += 4; // seg000:0A4F PUSHI(0x28); PUSH(si); PUSHI(MEMW(dstseg)); PUSH(di); PUSHI(MEMW(reg_bp - 0xa)); EMU_CALL(a__movedata, 0A5F, show_image_file); reg_sp += 0xa; // seg000:0A62 PUSHI(2); PUSHI(0x3c4); EMU_CALL(a__outportb, 0A6C, show_image_file); reg_sp += 4; // seg000:0A6F PUSHI(4); PUSHI(0x3c5); EMU_CALL(a__outportb, 0A79, show_image_file); reg_sp += 4; // seg000:0A7C PUSHI(0x28); PUSH(si); PUSHI(MEMW(dstseg)); PUSH(di); PUSHI(MEMW(reg_bp - 0xc)); EMU_CALL(a__movedata, 0A8C, show_image_file); reg_sp += 0xa; // seg000:0A8F PUSHI(2); PUSHI(0x3c4); EMU_CALL(a__outportb, 0A99, show_image_file); reg_sp += 4; // seg000:0A9C PUSHI(8); PUSHI(0x3c5); EMU_CALL(a__outportb, 0AA6, show_image_file); reg_sp += 4; // seg000:0AA9 PUSHI(0x28); PUSH(si); PUSHI(MEMW(dstseg)); PUSH(di); PUSHI(MEMW(reg_bp - 0xe)); EMU_CALL(a__movedata, 0AB9, show_image_file); reg_sp += 0xa; // seg000:0ABC reg_di += 0x28; reg_si += 0x30; W_MEMW(reg_bp - 6, MEMW(reg_bp - 6) + 1); } // seg000:0ACF PUSHI(2); PUSHI(0x3c4); EMU_CALL(a__outportb, 0AD9, show_image_file); reg_sp += 4; // seg000:0ADC PUSHI(0xf); PUSHI(0x3c5); EMU_CALL(a__outportb, 0AE6, show_image_file); EMU_CALL(a_clear_overlay, 0AEC, show_image_file); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 1920 void add_special_body() { RETLOC(1927); assert(reg_eip == 0x1920); PUSH(bp); MOV(bp, sp); PUSH(si); EMU_CALL(a_add_body, 1927, add_special_body); //make room for body, return pointer in ax MOV(si, ax); W_MEMW(reg_si + 8, 3); W_MEMW(reg_si + 34, a_think_15); // ice cannon think reg_ax = MEMW(reg_bp + 8); W_MEMW(reg_si + 0xa, reg_ax); reg_ax = MEMW(reg_bp + 4); int tmp1 = (short)reg_ax; //cwd W_MEMD(reg_si, tmp1); reg_ax = MEMW(reg_bp + 6); tmp1 = (short)reg_ax; //cwd W_MEMD(reg_si + 4, tmp1); POP(si); POP(bp); RET; } // 2369 void think_body_6() { RETLOC(24CB); RETLOC(24A9); RETLOC(2487); RETLOC(244B); RETLOC(2429); RETLOC(2407); RETLOC(23E2); RETLOC(23C0); RETLOC(239E); assert(reg_eip == 0x2369); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_ax = MEMW(tick_count); reg_ax >>= 5; // seg000:2378 if (reg_ax != MEMW(reg_si + 0xc)) { // seg000:2380 reg_ax = MEMW(tick_count); reg_ax >>= 5; W_MEMW(reg_si + 0xc, reg_ax); reg_ax = MEMW(reg_si); reg_ax += 0xfffc; MOV(di, ax); reg_cx = MEMW(reg_si + 6); reg_bx = MEMW(reg_si + 4); reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 239E, think_body_6); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x9b); // seg000:23AD int tmp1 = MEMD(reg_si + 4); tmp1++; reg_cx = tmp1 >> 16; reg_bx = tmp1 & 0xffff; reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 23C0, think_body_6); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x1dc); // seg000:23CF tmp1 = MEMD(reg_si + 4); tmp1 += 2; reg_cx = tmp1 >> 16; reg_bx = tmp1 & 0xffff; reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 23E2, think_body_6); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x1e9); // seg000:23F1 reg_ax = MEMW(reg_si); reg_ax += 0xfffd; MOV(di, ax); while (1) { // seg000:245B tmp1 = (short)reg_di; int tmp2 = MEMD(reg_si); tmp2 += 3; // seg000:2469 if (tmp1 > tmp2) break; // seg000:23FA reg_cx = MEMW(reg_si + 6); reg_bx = MEMW(reg_si + 4); reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 2407, think_body_6); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x9b); // seg000:2416 tmp1 = MEMD(reg_si + 4); tmp1 += 1; reg_cx = tmp1 >> 16; reg_bx = tmp1 & 0xffff; reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 2429, think_body_6); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x1dd); // seg000:2438 tmp1 = MEMD(reg_si + 4); tmp1 += 2; reg_cx = tmp1 >> 16; reg_bx = tmp1 & 0xffff; reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 244B, think_body_6); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x1ea); // seg000:245A reg_di++; } // seg000:2473 reg_ax = MEMW(reg_si); reg_ax += 4; MOV(di, ax); // seg000:247A reg_cx = MEMW(reg_si + 6); reg_bx = MEMW(reg_si + 4); reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 2487, think_body_6); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x9b); // seg000:2496 tmp1 = MEMD(reg_si + 4); tmp1 += 1; reg_cx = tmp1 >> 16; reg_bx = tmp1 & 0xffff; reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 24A9, think_body_6); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x1de); // seg000:24B8 tmp1 = MEMD(reg_si + 4); tmp1 += 2; reg_cx = tmp1 >> 16; reg_bx = tmp1 & 0xffff; reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 24CB, think_body_6); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x1eb); // seg000:24DA W_MEMD(reg_si + 4, MEMD(reg_si + 4) + 1); W_MEMW(reg_si + 0xa, MEMW(reg_si + 0xa) + 1); // seg000:24E5 if (MEMW(reg_si + 0xa) == 4) { // seg000:24EB W_MEMW(reg_si + 8, 0); } } // seg000:24F0 POP(di); POP(si); POP(bp); RET; } // 273D void slide_door() { RETLOC(27F1); RETLOC(27D4); RETLOC(27B7); RETLOC(2789); assert(reg_eip == 0x273D); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_ax = MEMW(reg_si + 0xa); reg_ax += MEMW(sprite_sync); W_MEMW(reg_si + 0xa, reg_ax); reg_ax = MEMW(reg_si + 0xa); int tmp1 = (short)reg_ax; tmp1 /= 5; reg_ax = tmp1 & 0xffff; MOV(di, ax); // seg000:275A if ((short)reg_ax > 0x20) { // seg000:275F reg_di = 0x20; W_MEMW(reg_si + 8, 0); } // seg000:2767 PUSHI(MEMW(reg_si + 0x10)); int tmp2 = MEMD(reg_si + 4); MOV(ax, di); reg_ax <<= 8; tmp1 = (short)reg_ax; tmp2 += tmp1; PUSHI(tmp2 >> 16); PUSHI(tmp2 & 0xffff); PUSHI(MEMW(reg_si + 2)); PUSHI(MEMW(reg_si)); EMU_CALL(a_slide_sprite, 2789, slide_door); reg_sp += 0xa; // seg000:278C reg_ax = MEMW(reg_si + 0x10); reg_ax++; PUSH(ax); tmp2 = MEMD(reg_si + 4); MOV(ax, di); reg_ax <<= 8; tmp1 = (short)reg_ax; tmp2 += tmp1; tmp2 += 0x1000; PUSHI(tmp2 >> 16); PUSHI(tmp2 & 0xffff); PUSHI(MEMW(reg_si + 2)); PUSHI(MEMW(reg_si)); EMU_CALL(a_slide_sprite, 27B7, slide_door); reg_sp += 0xa; // seg000:27BA reg_ax = MEMW(reg_si + 0xe); PUSH(ax); tmp2 = MEMD(reg_si + 4); tmp2 += 0x2000; PUSHI(tmp2 >> 16); PUSHI(tmp2 & 0xffff); PUSHI(MEMW(reg_si + 2)); PUSHI(MEMW(reg_si)); EMU_CALL(a_slide_sprite, 27D4, slide_door); reg_sp += 0xa; // seg000:27D7 PUSHI(MEMW(reg_si + 0xc)); tmp2 = (int)MEMD(reg_si + 4); tmp2 += 0x3000; PUSHI(tmp2 >> 16); PUSHI(tmp2 & 0xffff); PUSHI(MEMW(reg_si + 2)); PUSHI(MEMW(reg_si)); EMU_CALL(a_slide_sprite, 27F1, slide_door); reg_sp += 0xa; // seg000:27F4 POP(di); POP(si); POP(bp); RET; } void lights_on() { RETLOC(35B0); RETLOC(35A2); printf("lights_on\n"); // never seen it assert(reg_eip == 0x3592); PUSH(bp); MOV(bp, sp); W_MEMW(toggle_lights, 1); PUSHI(1); EMU_CALL(a_delay, 35A2, lights_on); reg_sp += 2; reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_dx = byte_1558B; reg_ax = 0x1002; EMU_INSTR(35AE, 35B0, lights_on); POP(bp); RET; } void lights_out() { RETLOC(35D0); RETLOC(35C2); printf("lights_out\n"); // never seen it assert(reg_eip == 0x35B2); PUSH(bp); MOV(bp, sp); W_MEMW(toggle_lights, 0); PUSHI(1); EMU_CALL(a_delay, 35C2, lights_out); reg_sp += 2; reg_ax = SegValue(ds); SegSet16(es, reg_ax); reg_dx = byte_15569; reg_ax = 0x1002; EMU_INSTR(35CE, 35D0, lights_out); POP(bp); RET; } //seg000:4A45 void think_body_3() //flash border { RETLOC(4A88); RETLOC(4A65); assert(reg_eip == 0x4a45); PUSH(bp); MOV(bp, sp); PUSH(si); reg_si = MEMW(reg_bp + 4); reg_ax = MEMW(reg_si + 10); reg_ax += MEMW(sprite_sync); W_MEMW(reg_si + 10, reg_ax); // seg000:4A56 if ((short)MEMW(reg_si + 10) > 0x12c) { // border flash length // seg000:4A5D reg_ah = 0x10; reg_al = 1; reg_bh = 3; EMU_INSTR(4A63, 4A65, think_body_3); // int 10h AX = 1001h W_MEMW(reg_si + 8, 0); } else { // seg000:4A6C reg_ax = MEMW(tick_count); reg_ax >>= 6; // seg000:4A73 if (reg_ax & 1) { // seg000:4A78 reg_ah = 0x10; reg_al = 1; reg_bh = 0xe; } else { // seg000:4A80 reg_ah = 0x10; reg_al = 1; reg_bh = 3; } // seg000:4A86 EMU_INSTR(4A86, 4A88, think_body_3); } // seg000:4A88 POP(si); POP(bp); RET; } void bridge_extend() //bridge growing { RETLOC(4AE1); RETLOC(4ABB); assert(reg_eip == 0x4a8b); printf("bridge_extend\n"); // never seen it PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); // pointer to special_body? reg_ax = MEMW(reg_si + 0xa); reg_ax += MEMW(sprite_sync); W_MEMW(reg_si + 0xa, reg_ax); // seg000:4A9D if ((short)MEMW(reg_si + 0xa) >= 0xc) { //bridge growing time 0xC // seg000:4AA3 W_MEMW(reg_si + 0xa, MEMW(reg_si + 0xa) - 0xc); //also here reg_ax = MEMW(reg_si); reg_ax += MEMW(reg_si + 0x10); MOV(di, ax); reg_cx = MEMW(reg_si + 6); reg_bx = MEMW(reg_si + 4); reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 4ABB, bridge_extend); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = mem_readw(SegPhys(es) + reg_bx); // seg000:4AC8 if (reg_ax != MEMW(reg_si + 0xe)) { // seg000:4ACD W_MEMW(reg_si + 34, a_think_contact_nop); } else { // seg000:4AD4 reg_cx = MEMW(reg_si + 6); reg_bx = MEMW(reg_si + 4); reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 4AE1, bridge_extend); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; mem_writew(SegPhys(es) + reg_bx, 0x10e); reg_ax = MEMW(reg_si + 0xc); W_MEMW(reg_si + 0x10, reg_ax); } } // seg000:4AF6 POP(di); POP(si); POP(bp); RET; } void bridge_retract() { RETLOC(4B55); RETLOC(4B30); printf("bridge_retract\n"); // never seen it assert(reg_eip == 0x4afa); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_si = MEMW(reg_bp + 4); reg_ax = MEMW(reg_si + 0xa); reg_ax += MEMW(sprite_sync); W_MEMW(reg_si + 0xa, reg_ax); // seg000:4B0C if ((short)MEMW(reg_si + 0xa) >= 0xc) { // seg000:4B12 W_MEMW(reg_si + 0xa, MEMW(reg_si + 0xa) - 0xc); reg_ax = MEMW(reg_si + 0xc); W_MEMW(reg_si + 0x10, MEMW(reg_si + 0x10) - reg_ax); reg_ax = MEMW(reg_si); reg_ax += MEMW(reg_si + 0x10); MOV(di, ax); reg_cx = MEMW(reg_si + 6); reg_bx = MEMW(reg_si + 4); reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 4B30, bridge_retract); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; // seg000:4B3A if (mem_readw(SegPhys(es) + reg_bx) != 0x10e) { // seg000:4B41 W_MEMW(reg_si + 8, 0); } else { // seg000:4B48 reg_cx = MEMW(reg_si + 6); reg_bx = MEMW(reg_si + 4); reg_ax = MEMW(map_width_intiles); reg_dx = 0; EMU_CALL(a__LXMUL, 4B55, bridge_retract); reg_ax += reg_di; reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = MEMW(reg_si + 0xe); mem_writew(SegPhys(es) + reg_bx, reg_ax); } } // seg000:4B65 POP(di); POP(si); POP(bp); RET; } // 608C void sub_608C() { RETLOC(60AB); assert(reg_eip == 0x608c); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_di = MEMW(reg_bp + 6); // seg000:60B5 while ((short)reg_di <= (short)MEMW(reg_bp + 0xa)) { // seg000:6096 reg_si = MEMW(reg_bp + 4); // seg000:60AF while ((short)reg_si <= MEMW(reg_bp + 8)) { // seg000:609B PUSHI(MEMW(reg_bp + 12)); MOV(ax, di); reg_ax <<= 3; PUSH(ax); PUSH(si); EMU_CALL(a_draw_char, 60AB, sub_608C); reg_sp += 6; reg_si++; } // seg000:60B4 reg_di++; } // seg000:60BA POP(di); POP(si); POP(bp); RET; } void sub_614B() { printf("sub_614B\n"); } void sub_7ABB() { printf("sub_7ABB\n"); } // 8132 void sub_8132() { RETLOC(814B); assert(reg_eip == 0x8132); PUSH(bp); MOV(bp, sp); PUSHI(0); PUSHI(MEMW(word_1B3B0)); PUSHI(MEMW(word_1B3AA)); PUSHI(MEMW(word_1B3AE)); PUSHI(MEMW(word_1B3A8)); EMU_CALL(a_sub_608C, 814B, sub_8132); reg_sp += 0xa; POP(bp); RET; } // 8919 void handle_secret_city() { RETLOC(8AB1); RETLOC(8AAE); RETLOC(8AAB); RETLOC(8AA5); RETLOC(8A93); RETLOC(8A85); RETLOC(8A74); RETLOC(8A42); RETLOC(8A08); RETLOC(8A05); RETLOC(89C7); RETLOC(89C4); RETLOC(89C1); RETLOC(89BE); RETLOC(8931); RETLOC(8928); assert(reg_eip == 0x8919); PUSH(bp); MOV(bp, sp); reg_sp -= 0x14; PUSH(si); PUSH(di); PUSHI(80); EMU_CALL(a_load_level_data, 8928, handle_secret_city); reg_sp += 2; PUSHI(0x12); EMU_CALL(a_set_cur_sound, 8931, handle_secret_city); reg_sp += 2; // seg000:8933 reg_si = sprite_array_offset; W_MEMW(reg_si + 0x1c, 0); W_MEMW(reg_si + 0x1e, 0); W_MEMW(reg_si + 0x20, 0); W_MEMW(reg_si + 0x22, 0); W_MEMW(reg_si + 0x28, 0x24); int tmp1 = MEMD(dword_158F2); W_MEMD(dword_1D74A, tmp1); W_MEMD(dword_1DB44, tmp1); W_MEMD(reg_si + 4, tmp1); tmp1 = MEMD(dword_158F6); W_MEMD(dword_1D74E, tmp1); W_MEMD(dword_1DB48, tmp1); W_MEMD(reg_si + 8, tmp1); // seg000:8985 tmp1 = MEMD(reg_si + 4); tmp1 += 0xffff7000; W_MEMD(scroll_x_lo, tmp1); W_MEMD(dword_1D752, tmp1); tmp1 = MEMD(reg_si + 8); tmp1 += 0xffffd000; W_MEMD(scroll_y_lo, tmp1); W_MEMD(dword_1D756, tmp1); EMU_CALL(a_sync_drawing, 89BE, handle_secret_city); EMU_CALL(a_clear_overlay, 89C1, handle_secret_city); EMU_CALL(a_draw_screen, 89C4, handle_secret_city); EMU_CALL(a_fade_in, 89C7, handle_secret_city); // seg000:89C7 tmp1 = MEMD(reg_si + 4); tmp1 /= 0x1000; W_MEMW(reg_bp - 2, tmp1 & 0xffff); tmp1 = MEMD(reg_si + 8); tmp1 /= 0x1000; W_MEMW(reg_bp - 4, tmp1 & 0xffff); W_MEMW(reg_bp - 8, 0x152); // seg000:89F2 if (MEMW(word_158FA) != 0) { // seg000:89F9 W_MEMW(reg_bp - 8, 0x156); } // seg000:89FE reg_di = 0; // seg000:8A43 while ((short)reg_di < 0x10) { // seg000:8A02 EMU_CALL(a_sync_drawing, 8A05, handle_secret_city); EMU_CALL(a_clear_overlay, 8A08, handle_secret_city); MOV(ax, di); tmp1 = (short)reg_ax; reg_dx = tmp1 % 2; // seg000:8A10 if (reg_dx == 0) { // seg000:8A14 W_MEMW(reg_bp - 6, MEMW(reg_bp - 6) + 1); reg_ax = MEMW(reg_bp - 6); // seg000:8A1A if ((short)reg_ax > 3) { // seg000:8A1F W_MEMW(reg_bp - 6, 0); } } // seg000:8A24 reg_ax = MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = MEMW(reg_bp - 6); reg_ax += MEMW(reg_bp - 8); mem_writew(SegPhys(es) + reg_bx, reg_ax); EMU_CALL(a_draw_screen, 8A42, handle_secret_city); reg_di++; } // seg000:8A48 W_MEMW(reg_bp - 8, 0x145); // seg000:8A4D if (MEMW(word_158FA) != 0) { // seg000:8A54 W_MEMW(reg_bp - 8, 0x63); } // seg000:8A59 reg_ax = MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_ax += MEMW(reg_bp - 2); reg_ax <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_ax; reg_ax = MEMW(reg_bp - 8); mem_writew(SegPhys(es) + reg_bx, reg_ax); do { // seg000:8A71 EMU_CALL(a_sync_drawing, 8A74, handle_secret_city); reg_ax = reg_bp - 0xe; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x14; PUSH(ax); EMU_CALL(a_handle_ctrl, 8A85, handle_secret_city); reg_sp += 6; // seg000:8A88 reg_ax = reg_bp - 0x14; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 8A93, handle_secret_city); PUSHI(MEMW(reg_si + 0x28)); PUSHI(MEMW(reg_si + 0xa)); PUSHI(MEMW(reg_si + 8)); PUSHI(MEMW(reg_si + 6)); PUSHI(MEMW(reg_si + 4)); EMU_CALL(a_draw_sprite_at, 8AA5, handle_secret_city); reg_sp += 0xa; EMU_CALL(a_draw_screen, 8AAB, handle_secret_city); EMU_CALL(a_handle_cheat_keys, 8AAE, handle_secret_city); EMU_CALL(a_handle_global_keys, 8AB1, handle_secret_city); // seg000:8AB1 } while (MEMW(reg_bp - 0xc) != 0 || MEMW(reg_bp - 0xa) != 0); // seg000:8ABD tmp1 = MEMD(scroll_x_lo); W_MEMD(dword_1D752, tmp1); tmp1 = MEMD(scroll_y_lo); W_MEMD(dword_1D756, tmp1); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // 96E2 void do_previews() { RETLOC(972D); RETLOC(9719); RETLOC(9710); RETLOC(9709); RETLOC(9704); RETLOC(96FD); RETLOC(96F8); RETLOC(96F1); RETLOC(96EC); assert(reg_eip == 0x96e2); PUSH(bp); MOV(bp, sp); PUSHI(aPreview2_ck1); EMU_CALL(a_show_image_file, 96EC, do_previews); reg_sp += 2; EMU_CALL(a_fade_in, 96F1, do_previews); PUSHI(0x12c); EMU_CALL(a_delay, 96F8, do_previews); reg_sp += 2; EMU_CALL(a_fade_out, 96FD, do_previews); PUSHI(aPreview3_ck1); EMU_CALL(a_show_image_file, 9704, do_previews); reg_sp += 2; EMU_CALL(a_fade_in, 9709, do_previews); PUSHI(90); EMU_CALL(a_load_level_data, 9710, do_previews); reg_sp += 2; PUSHI(300); EMU_CALL(a_delay, 9719, do_previews); reg_sp += 2; // seg000:971B PUSHI(0x16); PUSHI(0); PUSHI(MEMW(previews_text + 2)); PUSHI(MEMW(previews_text)); EMU_CALL(a_do_text_viewer, 972D, do_previews); reg_sp += 8; POP(bp); RET; } void show_about_us() { RETLOC(97A1); RETLOC(978E); RETLOC(9780); RETLOC(976F); RETLOC(9768); RETLOC(9765); RETLOC(9762); RETLOC(975F); RETLOC(975C); RETLOC(9759); RETLOC(9756); RETLOC(9753); assert(reg_eip == 0x9732); PUSH(bp); MOV(bp, sp); reg_sp -= 0xc; W_MEMD(scroll_x_lo, 0x3f000); W_MEMD(scroll_y_lo, 0x1c00); EMU_CALL(a_clear_overlay, 9753, show_about_us); EMU_CALL(a_sync_drawing, 9756, show_about_us); EMU_CALL(a_do_about_us, 9759, show_about_us); EMU_CALL(a_fade_in, 975C, show_about_us); EMU_CALL(a_clear_keys, 975F, show_about_us); do { // seg000:975F EMU_CALL(a_sync_drawing, 9762, show_about_us); EMU_CALL(a_draw_screen, 9765, show_about_us); EMU_CALL(a_handle_global_keys, 9768, show_about_us); // seg000:9768 if (reg_ax != 0) { // seg000:976C EMU_CALL(a_do_about_us, 976F, show_about_us); } // seg000:976F reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0xc; PUSH(ax); EMU_CALL(a_handle_ctrl, 9780, show_about_us); reg_sp += 6; // seg000:9783 reg_ax = reg_bp - 0xc; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 978E, show_about_us); // seg000:978E if (MEMW(reg_bp - 4) != 0 || MEMW(reg_bp - 2) != 0) break; // seg000:979A PUSHI(1); EMU_CALL(a_translate_key, 97A1, show_about_us); reg_sp += 2; // seg000:97A7 } while (reg_ax == 0); // seg000:97A7 MOV(sp, bp); POP(bp); RET; } void draw_about_us() { RETLOC(983F); RETLOC(9818); RETLOC(9809); assert(reg_eip == 0x97F0); PUSH(bp); MOV(bp, sp); reg_sp -= 0x1b8; PUSH(si); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x1b8; PUSH(ax); PUSHI(SegValue(ds)); reg_ax = aWeAreAGroupOfSoftw; PUSH(ax); reg_cx = 0x1b8; EMU_CALL(a_N_SCOPY, 9809, draw_about_us); PUSHI(1); PUSHI(0x17); PUSHI(0x11); EMU_CALL(a_draw_filter, 9818, draw_about_us); reg_sp += 6; reg_ax = 7; W_MEMW(word_1B3A4, reg_ax); W_MEMW(word_1B2D2, reg_ax); W_MEMW(word_1B348, 9); reg_si = 0; // seg000:9842 while ((short)reg_si < 0xb) { // seg000:982E MOV(ax, si); reg_ax *= 0x28; reg_dx = reg_bp - 0x1b8; reg_ax += reg_dx; PUSH(ax); EMU_CALL(a_draw_invvid_string, 983F, draw_about_us); reg_sp += 2; reg_si++; } // seg000:9847 POP(si); MOV(sp, bp); POP(bp); RET; } void do_about_us() { RETLOC(986A); RETLOC(9861); RETLOC(985E); RETLOC(985B); RETLOC(9858); assert(reg_eip == 0x984C); PUSH(bp); MOV(bp, sp); W_MEMW(draw_func, a_draw_about_us); EMU_CALL(a_clear_overlay, 9858, do_about_us); EMU_CALL(a_sync_drawing, 985B, do_about_us); EMU_CALL(a_draw_screen, 985E, do_about_us); EMU_CALL(a_draw_screen, 9861, do_about_us); W_MEMW(draw_func, 0); EMU_CALL(a_clear_keys, 986A, do_about_us); POP(bp); RET; } void draw_scores() { RETLOC(9A13); RETLOC(99FD); RETLOC(99EB); RETLOC(99E1); RETLOC(98B9); RETLOC(98A7); RETLOC(9895); RETLOC(9883); assert(reg_eip == 0x986C); PUSH(bp); MOV(bp, sp); reg_sp -= 0x10; PUSH(si); PUSH(di); PUSHI(3); PUSHI(7); PUSHI(0x0f); EMU_CALL(a_draw_filter, 9883, draw_scores); reg_sp += 6; // seg000:9886 PUSHI(4); PUSHI(0x2c); PUSHI(9); EMU_CALL(a_draw_filter, 9895, draw_scores); reg_sp += 6; // seg000:9898 PUSHI(5); PUSHI(0x2c); PUSHI(0x17); EMU_CALL(a_draw_filter, 98A7, draw_scores); reg_sp += 6; // seg000:98AA PUSHI(6); PUSHI(0x2c); PUSHI(0x21); EMU_CALL(a_draw_filter, 98B9, draw_scores); // seg000:98BC reg_si = 0; // seg000:9A16 while ((short)reg_si < 7) { // seg000:98C1 int tmp1 = MEMD(scroll_x_lo); tmp1 /= 0x1000; W_MEMW(reg_bp - 2, tmp1 & 0xffff); // seg000:98D6 tmp1 = MEMD(scroll_y_lo); tmp1 /= 0x1000; W_MEMW(reg_bp - 4, tmp1 & 0xffff); // seg000:98EB MOV(ax, si); reg_dx = reg_ax % 4; MOV(di, dx); MOV(ax, si); reg_ax <<= 1; reg_ax += 8; W_MEMW(word_1B348, reg_ax); MOV(bx, si); reg_bx <<= 1; // seg000:9903 if (MEMW(word_1DB6A + reg_bx) != 0) { // seg000:990A tmp1 = (short)reg_ax; tmp1 /= 2; reg_ax += MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_dx = MEMW(reg_bp - 2); reg_dx += reg_ax; reg_dx += 0xe; reg_dx <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; MOV(ax, di); reg_ax += 0xdd; mem_writew(SegPhys(es) + reg_bx, reg_ax); } // seg000:992F MOV(bx, si); reg_bx <<= 1; // seg000:9933 if (MEMW(word_1DB78 + reg_bx) != 0) { // seg000:993A reg_ax = MEMW(word_1B348); tmp1 = (short)reg_ax; tmp1 /= 2; reg_ax += MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_dx = MEMW(reg_bp - 2); reg_dx += reg_ax; reg_dx += 0xf; reg_dx <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; MOV(ax, di); reg_ax += 0xed; mem_writew(SegPhys(es) + reg_bx, reg_ax); } // seg000:9962 MOV(bx, si); reg_bx <<= 1; // seg000:9966 if (MEMW(word_1DB94 + reg_bx) != 0) { // seg000:996D reg_ax = MEMW(word_1B348); tmp1 = (short)reg_ax; tmp1 /= 2; reg_ax += MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_dx = MEMW(reg_bp - 2); reg_dx += reg_ax; reg_dx += 0x10; reg_dx <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; MOV(ax, di); reg_ax += 0xf1; mem_writew(SegPhys(es) + reg_bx, reg_ax); } // seg000:9995 MOV(bx, si); reg_bx <<= 1; // seg000:9999 if (MEMW(word_1DB86 + reg_bx) != 0) { // seg000:99A0 reg_ax = MEMW(word_1B348); tmp1 = (short)reg_ax; tmp1 /= 2; reg_ax += MEMW(reg_bp - 4); reg_ax *= MEMW(map_width_intiles); reg_dx = MEMW(reg_bp - 2); reg_dx += reg_ax; reg_dx += 0x11; reg_dx <<= 1; reg_bx = MEMW(tile_data_1); SegSet16(es, MEMW(tile_data_1 + 2)); reg_bx += reg_dx; MOV(ax, di); reg_ax += 0xf5; mem_writew(SegPhys(es) + reg_bx, reg_ax); } // seg000:99C8 PUSHI(0xa); PUSHI(reg_bp - 0x10); MOV(bx, si); reg_bx <<= 2; PUSHI(MEMW(dword_1DB4E + 2 + reg_bx)); PUSHI(MEMW(dword_1DB4E + reg_bx)); EMU_CALL(a__ltoa, 99E1, draw_scores); reg_sp += 8; // seg000:99E4 PUSHI(reg_bp - 0x10); EMU_CALL(a__strlen, 99EB, draw_scores); reg_sp += 2; // seg000:99ED reg_dx = 0x1d; reg_dx -= reg_ax; W_MEMW(word_1B2D2, reg_dx); PUSHI(reg_bp - 0x10); EMU_CALL(a_draw_invvid_string, 99FD, draw_scores); reg_sp += 2; // seg000:99FF W_MEMW(word_1B2D2, 9); MOV(ax, si); reg_ax *= 0xd; reg_ax += unk_1DBBE; PUSH(ax); EMU_CALL(a_draw_invvid_string, 9A13, draw_scores); reg_sp += 2; reg_si++; } // seg000:9A1E POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } void show_scores() { RETLOC(9AAA); RETLOC(9A97); RETLOC(9A89); RETLOC(9A78); RETLOC(9A71); RETLOC(9A6E); RETLOC(9A6B); RETLOC(9A68); RETLOC(9A65); RETLOC(9A62); assert(reg_eip == 0x9A59); PUSH(bp); MOV(bp, sp); reg_sp -= 0xc; EMU_CALL(a_do_scores, 9A62, show_scores); EMU_CALL(a_fade_in, 9A65, show_scores); EMU_CALL(a_clear_keys, 9A68, show_scores); do { // seg000:9A68 EMU_CALL(a_sync_drawing, 9A6B, show_scores); EMU_CALL(a_draw_screen, 9A6E, show_scores); EMU_CALL(a_handle_global_keys, 9A71, show_scores); // seg000:9A71 if (reg_ax != 0) { // seg000:9A75 EMU_CALL(a_do_scores, 9A78, show_scores); } // seg000:9A78 reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0xc; PUSH(ax); EMU_CALL(a_handle_ctrl, 9A89, show_scores); reg_sp += 6; // seg000:9A8C reg_ax = reg_bp - 0xc; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, 9A97, show_scores); // seg000:9A97 if (MEMW(reg_bp - 4) != 0 || MEMW(reg_bp - 2) != 0) break; // seg000:9AA3 PUSHI(1); EMU_CALL(a_translate_key, 9AAA, show_scores); reg_sp += 2; // seg000:9AAC } while (reg_ax == 0); // seg000:9AB0 MOV(sp, bp); POP(bp); RET; } void continue_game() { RETLOC(9D6C); RETLOC(9D67); RETLOC(9D5E); RETLOC(9D54); RETLOC(9D3B); RETLOC(9D20); RETLOC(9D1B); RETLOC(9D12); RETLOC(9D08); RETLOC(9CEE); RETLOC(9CE4); RETLOC(9CB5); RETLOC(9CB0); RETLOC(9CA7); RETLOC(9C87); RETLOC(9C79); RETLOC(9C64); assert(reg_eip == 0x9C4E); PUSH(bp); MOV(bp, sp); reg_sp -= 0x14; PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x14; PUSH(ax); PUSHI(SegValue(ds)); reg_ax = aSaved__0; PUSH(ax); reg_cx = 0xd; EMU_CALL(a_N_SCOPY, 9C64, continue_game); PUSHI(0x20); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_draw_char, 9C79, continue_game); while(1) { // seg000:9C7C PUSHI(2); PUSHI(0x19); EMU_CALL(a_draw_box_opening2, 9C87, continue_game); reg_sp += 4; int tmp1 = (short)MEMW(word_1B2D2); W_MEMD(dword_1DB44, tmp1); tmp1 = (short)MEMW(word_1B348); W_MEMD(dword_1DB48, tmp1); PUSHI(aContinueWhichGame); EMU_CALL(a_draw_string, 9CA7, continue_game); reg_sp += 2; PUSHI(a19OrEsc_0); EMU_CALL(a_draw_string, 9CB0, continue_game); reg_sp += 2; do { // seg000:9CB2 EMU_CALL(a_read_char_with_echo, 9CB5, continue_game); reg_al &= 0xff; W_MEMB(reg_bp - 1, reg_al); // seg000:9CBA if ((char)reg_al >= '1' || (char)reg_al <= '9') break; // seg000:9CC2 } while(MEMB(reg_bp - 1) != 0x1b); // seg000:9CC8 if (MEMB(reg_bp - 1) == 0x1b) { // seg000:9CCE reg_ax = 0; break; } else { // seg000:9CD3 reg_al = MEMB(reg_bp - 1); W_MEMB(reg_bp - 0xf, reg_al); PUSHI(MEMW(pExt)); reg_ax = reg_bp - 0x14; PUSH(ax); EMU_CALL(a__strcat, 9CE4, continue_game); reg_sp += 4; reg_ax = reg_bp - 0x14; PUSH(ax); EMU_CALL(a_get_file_length, 9CEE, continue_game); reg_sp += 2; W_MEMW(reg_bp - 6, reg_ax); W_MEMW(reg_bp - 4, reg_dx); reg_ax = MEMW(reg_bp - 6); // seg000:9CF9 if (reg_ax == reg_dx) { // seg000:9CFD PUSHI(2); PUSHI(0x19); EMU_CALL(a_draw_box_opening2, 9D08, continue_game); PUSHI(aThatGameHasnT); EMU_CALL(a_draw_string, 9D12, continue_game); reg_sp += 2; PUSHI(aBeenSavedYet); EMU_CALL(a_draw_string, 9D1B, continue_game); reg_sp += 2; EMU_CALL(a_read_char_with_echo, 9D20, continue_game); continue; } // seg000:9D23 if (MEMW(reg_bp - 4) == 0 && MEMW(reg_bp - 6) == 0x5c) { // seg000:9D2F PUSHI(SegValue(ds)); PUSHI(got_part_1); reg_ax = reg_bp - 0x14; PUSH(ax); EMU_CALL(a_map_file_to_mem, 9D3B, continue_game); reg_sp += 6; W_MEMW(word_1DADE, 1); reg_ax = 1; break; } else { // seg000:9D49 PUSHI(2); PUSHI(0x19); EMU_CALL(a_draw_box_opening2, 9D54, continue_game); reg_sp += 4; PUSHI(aThatFileIsIncompat); EMU_CALL(a_draw_string, 9D5E, continue_game); reg_sp += 2; PUSHI(aWithThisVerionOfCk); EMU_CALL(a_draw_string, 9D67, continue_game); reg_sp += 2; EMU_CALL(a_read_char_with_echo, 9D6C, continue_game); } } } // seg000:9D6F MOV(sp, bp); POP(bp); RET; } // 9D73 void do_story() { RETLOC(9DB2); RETLOC(9DAC); RETLOC(9D9A); RETLOC(9D97); RETLOC(9D94); RETLOC(9D79); assert(reg_eip == 0x9D73); PUSH(bp); MOV(bp, sp); EMU_CALL(a_fade_out, 9D79, do_story); W_MEMD(scroll_x_lo, 0x2A000); W_MEMD(scroll_y_lo, 0x2000); EMU_CALL(a_clear_overlay, 9D94, do_story); EMU_CALL(a_draw_screen, 9D97, do_story); EMU_CALL(a_fade_in, 9D9A, do_story); PUSHI(0x10); PUSHI(0); PUSHI(MEMW(story_text + 2)); PUSHI(MEMW(story_text)); EMU_CALL(a_do_text_viewer, 9DAC, do_story); reg_sp += 8; EMU_CALL(a_fade_out, 9DB2, do_story); POP(bp); RET; } // 9DB4 void do_help() { RETLOC(9E11); assert(reg_eip == 0x9db4); PUSH(bp); MOV(bp, sp); reg_sp -= 8; // seg000:9DBA int tmp1 = MEMD(scroll_x_lo); W_MEMD(reg_bp - 4, tmp1); tmp1 = MEMD(scroll_y_lo); W_MEMD(reg_bp - 8, tmp1); // seg000:9DD4 tmp1 = MEMD(scroll_x_lo); tmp1 &= 0xfffff000; W_MEMD(scroll_x_lo, tmp1); tmp1 = MEMD(scroll_y_lo); tmp1 &= 0xfffff000; W_MEMD(scroll_y_lo, tmp1); // seg000:9DFE PUSHI(0x14); PUSHI(1); PUSHI(MEMW(help_text + 2)); PUSHI(MEMW(help_text)); EMU_CALL(a_do_text_viewer, 9E11, do_help); reg_sp += 8; // seg000:9E14 tmp1 = MEMD(reg_bp - 4); W_MEMD(scroll_x_lo, tmp1); tmp1 = MEMD(reg_bp - 8); W_MEMD(scroll_y_lo, tmp1); // seg000:9E2E MOV(sp, bp); POP(bp); RET; } // 9E32 void sub_9E32() { RETLOC(9E5F); RETLOC(9E57); assert(reg_eip == 0x9e32); PUSH(bp); MOV(bp, sp); PUSH(si); PUSH(di); reg_di = MEMW(word_1B2D2); reg_si = MEMW(word_1B348); reg_ax = MEMW(reg_bp + 6); W_MEMW(word_1B2D2, reg_ax); reg_ax = MEMW(reg_bp + 8); W_MEMW(word_1B348, reg_ax); // seg000:9E4B if (MEMW(reg_bp + 4) != 0) { // seg000:9E51 PUSHI(MEMW(reg_bp + 0xa)); EMU_CALL(a_draw_invvid_string, 9E57, sub_9E32); } else { // seg000:9E59 PUSHI(MEMW(reg_bp + 0xa)); EMU_CALL(a_draw_string, 9E5F, sub_9E32); } // seg000:9E5F reg_sp += 2; W_MEMW(word_1B2D2, reg_di); W_MEMW(word_1B348, reg_si); POP(di); POP(si); POP(bp); RET; } // 9E6D void sub_9E6D() { RETLOC(9F42); RETLOC(9F23); RETLOC(9F06); RETLOC(9EEA); RETLOC(9ED0); RETLOC(9EB6); RETLOC(9E9D); RETLOC(9E84); assert(reg_eip == 0x9e6d); PUSH(bp); MOV(bp, sp); PUSH(si); PUSHI(MEMW(word_1D746)); PUSHI(0x2b); PUSHI(MEMW(word_1D742)); PUSHI(4); EMU_CALL(a_draw_box2, 9E84, sub_9E6D); reg_sp += 8; PUSHI(4); reg_ax = MEMW(word_1D746); reg_ax++; reg_ax <<= 3; PUSH(ax); PUSHI(4); EMU_CALL(a_draw_char, 9E9D, sub_9E6D); reg_sp += 6; PUSHI(4); reg_ax = MEMW(word_1D746); reg_ax++; reg_ax <<= 3; PUSH(ax); PUSHI(0x2b); EMU_CALL(a_draw_char, 9EB6, sub_9E6D); reg_sp += 6; PUSHI(1); reg_ax = MEMW(word_1D746); reg_ax += 2; reg_ax <<= 3; PUSH(ax); PUSHI(4); EMU_CALL(a_draw_char, 9ED0, sub_9E6D); reg_sp += 6; PUSHI(3); reg_ax = MEMW(word_1D746); reg_ax += 2; reg_ax <<= 3; PUSH(ax); PUSHI(0x2b); EMU_CALL(a_draw_char, 9EEA, sub_9E6D); reg_sp += 6; reg_si = 5; // seg000:9F0A while ((short)reg_si < 0x2b) { // seg000:9EF2 PUSHI(2); reg_ax = MEMW(word_1D746); reg_ax += 2; reg_ax <<= 3; PUSH(ax); PUSH(si); EMU_CALL(a_draw_char, 9F06, sub_9E6D); reg_sp += 6; reg_si++; } // seg000:9F0F PUSHI(0x32b5); reg_ax = MEMW(word_1D746); reg_ax++; PUSH(ax); PUSHI(5); PUSHI(1); EMU_CALL(a_sub_9E32, 9F23, sub_9E6D); reg_sp += 8; // seg000:9F26 PUSHI(MEMW(word_1D744)); PUSHI(MEMW(word_1D73A)); PUSHI(MEMW(dword_1D73C + 2)); PUSHI(MEMW(dword_1D73C)); reg_ax = MEMW(word_1D742); reg_ax++; PUSH(ax); PUSHI(MEMW(word_1D740)); EMU_CALL(a_sub_B243, 9F42, sub_9E6D); reg_sp += 0xc; POP(si); POP(bp); RET; } // 9FB2 void do_text_viewer() { RETLOC(A1CE); RETLOC(A1BF); RETLOC(A1B1); RETLOC(A189); RETLOC(A17F); RETLOC(A13F); RETLOC(A135); RETLOC(A096); RETLOC(A08C); RETLOC(A069); RETLOC(A0FF); RETLOC(A0F5); RETLOC(A0CA); RETLOC(A043); RETLOC(A035); RETLOC(A022); RETLOC(A013); RETLOC(A010); RETLOC(9FD8); assert(reg_eip == 0x9fb2); PUSH(bp); MOV(bp, sp); reg_sp -= 0x14; PUSH(si); PUSH(di); reg_ax = MEMW(reg_bp + 10); reg_ax -= MEMW(reg_bp + 8); reg_ax--; MOV(di, ax); PUSHI(0xc8); PUSHI(0x26); PUSHI(unk_1D7BE); PUSHI(MEMW(reg_bp + 6)); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a_draw_text_page, 9FD8, do_text_viewer); reg_sp += 0xa; // seg000:9FDB W_MEMW(reg_bp - 8, reg_ax); W_MEMW(word_1D740, 5); reg_ax = MEMW(reg_bp + 8); W_MEMW(word_1D742, reg_ax); int tmp1 = MEMD(reg_bp + 4); W_MEMD(dword_1D73C, tmp1); W_MEMW(word_1D73A, unk_1D7BE); W_MEMW(word_1D744, reg_di); // seg000:A001 reg_ax = MEMW(reg_bp + 10); W_MEMW(word_1D746, reg_ax); W_MEMW(draw_func, a_sub_9E6D); EMU_CALL(a_draw_screen, A010, do_text_viewer); EMU_CALL(a_draw_screen, A013, do_text_viewer); W_MEMW(draw_func, 0); reg_si = 0; PUSHI(8); EMU_CALL(a_delay, A022, do_text_viewer); reg_sp += 2; do { // seg000:A024 reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0xe; PUSH(ax); EMU_CALL(a_handle_ctrl, A035, do_text_viewer); reg_sp += 6; reg_ax = reg_bp - 0xe; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, A043, do_text_viewer); // seg000:A043 if (MEMB(byte_180C4) == 0 && MEMW(reg_bp - 6) != 0) { // seg000:A09A if (MEMB(byte_180CC) != 0 || MEMW(reg_bp - 6) == 4) { // seg000:A0A7 reg_ax = MEMW(reg_bp - 8); reg_ax -= reg_di; // seg000:A0AC if ((short)reg_ax >= (short)reg_si) { // seg000:A0B0 reg_ax = 0xc8; reg_ax -= reg_di; // seg000:A0B5 if ((short)reg_ax >= (short)reg_si) { // seg000:A0B9 reg_si++; PUSHI(0); reg_ax = MEMW(reg_bp + 10); reg_ax--; PUSH(ax); reg_ax = MEMW(reg_bp + 8); reg_ax++; PUSH(ax); EMU_CALL(a_scroll_text, A0CA, do_text_viewer); reg_sp += 6; // seg000:A0CD PUSHI(1); MOV(ax, si); reg_ax <<= 2; MOV(dx, di); reg_dx <<= 2; reg_ax += reg_dx; reg_ax += unk_1D7BA; PUSH(ax); PUSHI(MEMW(reg_bp + 6)); PUSHI(MEMW(reg_bp + 4)); reg_ax = MEMW(reg_bp + 10); reg_ax--; PUSH(ax); PUSHI(5); EMU_CALL(a_sub_B243, A0F5, do_text_viewer); reg_sp += 0xc; PUSHI(2); EMU_CALL(a_delay, A0FF, do_text_viewer); reg_sp += 2; } } } } else if ((short)reg_si > 0) { // seg000:A057 reg_si--; PUSHI(1); reg_ax = MEMW(reg_bp + 10); reg_ax--; PUSH(ax); reg_ax = MEMW(reg_bp + 8); reg_ax++; PUSH(ax); EMU_CALL(a_scroll_text, A069, do_text_viewer); reg_sp += 6; PUSHI(1); MOV(ax, si); reg_ax <<= 2; reg_ax += unk_1D7BE; PUSH(ax); PUSHI(MEMW(reg_bp + 6)); PUSHI(MEMW(reg_bp + 4)); reg_ax = MEMW(reg_bp + 8); reg_ax++; PUSH(ax); PUSHI(5); EMU_CALL(a_sub_B243, A08C, do_text_viewer); reg_sp += 0xc; PUSHI(2); EMU_CALL(a_delay, A096, do_text_viewer); reg_sp += 2; } // seg000:A101 if (MEMB(byte_180C5) != 0) { // seg000:A108 MOV(ax, si); reg_ax -= reg_di; reg_ax++; if ((short)reg_ax > 0) { // seg000:A10F MOV(ax, di); reg_ax--; reg_si -= reg_ax; } else { // seg000:A116 reg_si = 0; } // seg000:A118 PUSH(di); MOV(ax, si); reg_ax <<= 2; reg_ax += unk_1D7BE; PUSH(ax); PUSHI(MEMW(reg_bp + 6)); PUSHI(MEMW(reg_bp + 4)); reg_ax = MEMW(reg_bp + 8); reg_ax++; PUSH(ax); PUSHI(5); EMU_CALL(a_sub_B243, A135, do_text_viewer); reg_sp += 0xc; // seg000:A138 EMU_INSTR(A138, A13F, do_text_viewer); // loop until byte_180C5 is not zero } // seg000:A13F if (MEMB(byte_180CD) != 0) { // seg000:A146 MOV(ax, di); reg_ax <<= 1; MOV(dx, si); reg_dx += reg_ax; // seg000:A14E if ((short)reg_dx < (short)MEMW(reg_bp - 8)) { // seg000:A153 MOV(ax, di); reg_ax--; reg_si += reg_ax; } else { // seg000:A15A reg_ax = MEMW(reg_bp - 8); reg_ax -= reg_di; reg_ax++; MOV(si, ax); } // seg000:A162 PUSH(di); MOV(ax, si); reg_ax <<= 2; reg_ax += unk_1D7BE; PUSH(ax); PUSHI(MEMW(reg_bp + 6)); PUSHI(MEMW(reg_bp + 4)); reg_ax = MEMW(reg_bp + 8); reg_ax++; PUSH(ax); PUSHI(5); EMU_CALL(a_sub_B243, A17F, do_text_viewer); reg_sp += 0xc; // seg000:A182 EMU_INSTR(A182, A189, do_text_viewer); // loops until byte_180CD is not zero } // seg000:A189 reg_ax = (char)MEMB(byte_1807D); } while (reg_ax == 0 && MEMW(reg_bp - 4) == 0 && MEMW(reg_bp - 2) == 0); do { // seg000:A1A0 reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x14; PUSH(ax); EMU_CALL(a_handle_ctrl, A1B1, do_text_viewer); reg_sp += 6; // seg000:A1B4 reg_ax = reg_bp - 0x14; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, A1BF, do_text_viewer); // seg000:A1BF } while (MEMW(reg_bp - 4) != 0 || MEMW(reg_bp - 2) != 0); // seg000:A1CB EMU_CALL(a_clear_keys, A1CE, do_text_viewer); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } void do_ordering_info() { RETLOC(A47D); RETLOC(A46A); RETLOC(A467); RETLOC(A460); RETLOC(A44A); RETLOC(A444); RETLOC(A3E2); RETLOC(A3C5); RETLOC(A3B1); RETLOC(A3AE); RETLOC(A3A0); RETLOC(A38A); RETLOC(A387); RETLOC(A384); RETLOC(A373); RETLOC(A363); RETLOC(A353); assert(reg_eip == 0xA33B); PUSH(bp); MOV(bp, sp); reg_sp -= 0x26; PUSH(si); PUSH(di); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0xa; PUSH(ax); PUSHI(SegValue(ds)); reg_ax = a0_0; PUSH(ax); reg_cx = 4; EMU_CALL(a_N_SCOPY, A353, do_ordering_info); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x12; PUSH(ax); PUSHI(SegValue(ds)); reg_ax = unk_16156; PUSH(ax); reg_cx = 8; EMU_CALL(a_N_SCOPY, A363, do_ordering_info); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x1a; PUSH(ax); PUSHI(SegValue(ds)); reg_ax = unk_1615E; PUSH(ax); reg_cx = 8; EMU_CALL(a_N_SCOPY, A373, do_ordering_info); reg_di = 0; W_MEMW(reg_bp - 0x1c, 0); reg_si = 0; W_MEMW(reg_bp - 0x20, 0); EMU_CALL(a_show_ordering_info, A384, do_ordering_info); EMU_CALL(a_fade_in, A387, do_ordering_info); EMU_CALL(a_clear_keys, A38A, do_ordering_info); W_MEMW(reg_bp - 0x1e, 0x960); do { // seg000:A38F reg_ax = reg_bp - 6; PUSHI(SegValue(ss)); PUSH(ax); PUSHI(1); PUSHI(SegValue(ss)); reg_ax = reg_bp - 0x26; PUSH(ax); EMU_CALL(a_handle_ctrl, A3A0, do_ordering_info); reg_sp += 6; // seg000:A3A3 reg_ax = reg_bp - 0x26; PUSHI(SegValue(ss)); PUSH(ax); reg_cx = 6; EMU_CALL(a_N_SCOPY, A3AE, do_ordering_info); EMU_CALL(a_sync_drawing, A3B1, do_ordering_info); // seg000:A3B1 reg_ax = MEMW(reg_bp - 0x20); int tmp1 = (short)reg_ax; reg_dx = tmp1 % 6; // seg000:A3BA if (reg_dx == 0) { // seg000:A3BE PUSHI(3); EMU_CALL(a_calc_jump_height, A3C5, do_ordering_info); reg_sp += 2; MOV(dx, di); reg_dx += reg_ax; reg_dx += 0xfffe; MOV(di, dx); reg_ax += reg_dx; // seg000:A3D2 if ((short)reg_ax > 7 || (short)reg_dx < 0) { // seg000:A3DB PUSHI(0x31); EMU_CALL(a_calc_jump_height, A3E2, do_ordering_info); reg_sp += 2; tmp1 = (short)reg_ax; tmp1 /= 7; reg_di = tmp1 & 0xffff; } } // seg000:A3EC W_MEMW(reg_bp - 0x1c, MEMW(reg_bp - 0x1c) + 1); reg_ax = MEMW(reg_bp - 0x1c); // seg000:A3F2 if ((short)reg_ax > 0x1f4) { // seg000:A3F7 reg_si ^= 1; W_MEMW(reg_bp - 0x1c, 0); } // seg000:A3FF MOV(bx, si); reg_bx <<= 1; reg_ax = reg_bp - 0xa; reg_bx += reg_ax; reg_ax = MEMW(reg_bx); reg_ax += reg_di; PUSH(ax); MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0x12; reg_bx += reg_ax; tmp1 = MEMD(reg_bx); tmp1 += MEMD(scroll_y_lo); PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); MOV(bx, si); reg_bx <<= 2; reg_ax = reg_bp - 0x1a; reg_bx += reg_ax; tmp1 = MEMD(reg_bx); tmp1 += MEMD(scroll_x_lo); PUSHI(tmp1 >> 16); PUSHI(tmp1 & 0xffff); EMU_CALL(a_draw_sprite_at, A444, do_ordering_info); reg_sp += 0xa; EMU_CALL(a_draw_screen, A44A, do_ordering_info); W_MEMW(reg_bp - 0x20, MEMW(reg_bp - 0x20) + 1); // seg000:A44D if (MEMW(reg_bp + 4) != 0) { // seg000:A453 reg_ax = MEMW(reg_bp - 0x1e); reg_ax -= MEMW(sprite_sync); W_MEMW(reg_bp - 0x1e, reg_ax); } // seg000:A45D EMU_CALL(a_handle_global_keys, A460, do_ordering_info); // seg000:A460 if (reg_ax != 0) { // seg000:A464 EMU_CALL(a_clear_keys, A467, do_ordering_info); EMU_CALL(a_show_ordering_info, A46A, do_ordering_info); } // seg000:A46A if (MEMW(reg_bp - 4) == 0 && MEMW(reg_bp - 2) == 0) { // seg000:A476 PUSHI(1); EMU_CALL(a_translate_key, A47D, do_ordering_info); reg_sp += 2; // seg000:A47F if (reg_ax == 0) continue; } // seg000:A483 W_MEMW(reg_bp - 0x1e, 0); // seg000:A488 } while((short)MEMW(reg_bp - 0x1e) > 0); // seg000:A491 POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } void draw_ordering_info() { RETLOC(A562); RETLOC(A553); RETLOC(A54A); RETLOC(A541); RETLOC(A538); RETLOC(A52F); RETLOC(A526); RETLOC(A51D); RETLOC(A514); RETLOC(A50B); RETLOC(A4F8); RETLOC(A4E6); RETLOC(A4DD); RETLOC(A4D4); RETLOC(A4CB); RETLOC(A4C2); RETLOC(A4B9); RETLOC(A4B0); assert(reg_eip = 0xA497); PUSH(bp); MOV(bp, sp); reg_ax = 0xc; W_MEMW(word_1B2D2, reg_ax); W_MEMW(word_1B3A4, reg_ax); W_MEMW(word_1B348, 4); PUSHI(aCommanderKeenInvas); EMU_CALL(a_draw_invvid_string, A4B0, draw_ordering_info); reg_sp += 2; PUSHI(aOfTheVorticonsCons); EMU_CALL(a_draw_invvid_string, A4B9, draw_ordering_info); reg_sp += 2; PUSHI(aOfThreeUniqueAnd); EMU_CALL(a_draw_invvid_string, A4C2, draw_ordering_info); reg_sp += 2; PUSHI(aChallengingEpisode); EMU_CALL(a_draw_invvid_string, A4CB, draw_ordering_info); reg_sp += 2; PUSHI(a1_MaroonedOnMars15); EMU_CALL(a_draw_invvid_string, A4D4, draw_ordering_info); reg_sp += 2; PUSHI(a2_TheEarthExplodes); EMU_CALL(a_draw_invvid_string, A4DD, draw_ordering_info); reg_sp += 2; PUSHI(a3_KeenMustDie15); EMU_CALL(a_draw_invvid_string, A4E6, draw_ordering_info); reg_sp += 2; reg_ax = 5; W_MEMW(word_1B2D2, reg_ax); W_MEMW(word_1B3A4, reg_ax); PUSHI(aOrderTheTrilogyFor); EMU_CALL(a_draw_invvid_string, A4F8, draw_ordering_info); reg_sp += 2; W_MEMW(word_1B2D2, MEMW(word_1B2D2) - 1); reg_ax = MEMW(word_1B2D2); W_MEMW(word_1B3A4, reg_ax); PUSHI(aTheSecretHintsTric); EMU_CALL(a_draw_invvid_string, A50B, draw_ordering_info); reg_sp += 2; PUSHI(aTheSpecialCheatMod); EMU_CALL(a_draw_invvid_string, A514, draw_ordering_info); reg_sp += 2; PUSHI(aTheLatestVersionOf); EMU_CALL(a_draw_invvid_string, A51D, draw_ordering_info); reg_sp += 2; PUSHI(aSeveralFreeBonusGa); EMU_CALL(a_draw_invvid_string, A526, draw_ordering_info); reg_sp += 2; PUSHI(aMailOrdersTo); EMU_CALL(a_draw_invvid_string, A52F, draw_ordering_info); reg_sp += 2; PUSHI(aU_s_FundsOnlyApoge); EMU_CALL(a_draw_invvid_string, A538, draw_ordering_info); reg_sp += 2; PUSHI(aChecksOrMOSP_o_Box); EMU_CALL(a_draw_invvid_string, A541, draw_ordering_info); reg_sp += 2; PUSHI(aInclude2PHGarlandT); EMU_CALL(a_draw_invvid_string, A54A, draw_ordering_info); reg_sp += 2; PUSHI(aSpecify5_253_5Disk); EMU_CALL(a_draw_invvid_string, A553, draw_ordering_info); reg_sp += 2; W_MEMW(word_1B2D2, 0); PUSHI(aOrOrderTollFree180); EMU_CALL(a_draw_invvid_string, A562, draw_ordering_info); reg_sp += 2; POP(bp); RET; } void show_ordering_info() { RETLOC(A5BA); RETLOC(A5B1); RETLOC(A5AE); RETLOC(A5A5); RETLOC(A5A2); assert(reg_eip == 0xA566); PUSH(bp); MOV(bp, sp); W_MEMD(scroll_x_lo, 0x16000); W_MEMD(scroll_y_lo, 0x2000); int tmp1 = MEMD(scroll_x_lo) >> 0xc; W_MEMW(word_186A6, reg_ax); tmp1 = MEMD(scroll_y_lo) >> 0xc; W_MEMW(word_18B62, tmp1); EMU_CALL(a_clear_overlay, A5A2, show_ordering_info); EMU_CALL(a_sync_drawing, A5A5, show_ordering_info); W_MEMW(draw_func, a_draw_ordering_info); EMU_CALL(a_draw_screen, A5AE, show_ordering_info); EMU_CALL(a_draw_screen, A5B1, show_ordering_info); W_MEMW(draw_func, 0); EMU_CALL(a_clear_keys, A5BA, show_ordering_info); POP(bp); RET; } // B243 void sub_B243() { RETLOC(B343); RETLOC(B31A); assert(reg_eip == 0xB243); PUSH(bp); MOV(bp, sp); reg_sp -= 6; PUSH(si); PUSH(di); reg_ax = MEMW(reg_bp + 4); W_MEMW(word_1B2D2, reg_ax); reg_ax = MEMW(reg_bp + 6); W_MEMW(word_1B348, reg_ax); W_MEMW(reg_bp - 6, 0); W_MEMW(reg_bp - 2, 0); // seg000:B353 while (MEMW(reg_bp - 2) < MEMW(reg_bp + 0xe)) { // seg000:B264 reg_ax = MEMW(reg_bp - 2); reg_ax <<= 2; reg_bx = MEMW(reg_bp + 12); reg_bx += reg_ax; reg_ax = MEMW(reg_bx); W_MEMW(reg_bp - 4, reg_ax); // seg000:B275 if (reg_ax == 0xffff) break; // seg000:B27D reg_ax = MEMW(reg_bp - 2); reg_ax <<= 2; reg_bx = MEMW(reg_bp + 12); reg_bx += reg_ax; reg_di = MEMW(reg_bx + 2); reg_bx = MEMW(reg_bp - 4); reg_cx = 0; int tmp1 = N_PADD(MEMD(reg_bp + 8), reg_bx); tmp1 = N_PADD(tmp1, reg_di); tmp1 = N_PADD(tmp1, -1); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); // seg000:B2AE if (mem_readb(SegPhys(es) + reg_bx) == 0xd) { // seg000:B2B4 reg_di--; } // seg000:B2B5 reg_bx = MEMW(reg_bp - 4); tmp1 = N_PADD(MEMD(reg_bp + 8), reg_bx); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); // seg000:B2C7 if (mem_readb(SegPhys(es) + reg_bx) == 0x7e) { // seg000:B2CD W_MEMW(reg_bp - 6, 0x80); W_MEMW(reg_bp - 4, MEMW(reg_bp - 4) + 1); reg_di--; } else { // seg000:B2D8 W_MEMW(reg_bp - 6, 0); } // seg000:B2DD reg_si = 0; // seg000:B31E while (reg_si < reg_di) { // seg000:B2E1 reg_bx = MEMW(reg_bp - 4); tmp1 = N_PADD(MEMD(reg_bp + 8), reg_bx); tmp1 = N_PADD(tmp1, reg_si); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); reg_ax = (char)mem_readb(SegPhys(es) + reg_bx); reg_ax += MEMW(reg_bp - 6); reg_ax &= 0xff; PUSH(ax); reg_ax = MEMW(word_1B348); reg_ax <<= 3; PUSH(ax); reg_ax = MEMW(word_1B2D2); W_MEMW(word_1B2D2, MEMW(word_1B2D2) + 1); PUSH(ax); EMU_CALL(a_draw_char, B31A, sub_B243); reg_sp += 6; reg_si++; } // seg000:B322 if ((short)MEMW(word_1B2D2) < 0x2b) { // seg000:B329 reg_ax = MEMW(reg_bp - 6); reg_ax += 0x20; PUSH(ax); PUSHI(MEMW(word_1B348)); PUSHI(0x2a); PUSHI(MEMW(word_1B348)); PUSHI(MEMW(word_1B2D2)); EMU_CALL(a_sub_608C, B343, sub_B243); reg_sp += 0xa; } // seg000:B346 W_MEMW(word_1B348, MEMW(word_1B348) + 1); reg_ax = MEMW(reg_bp + 4); W_MEMW(word_1B2D2, reg_ax); // B350 W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) + 1); } // seg000:B35E POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // B4DF void draw_text_page() { assert(reg_eip == 0xB4DF); PUSH(bp); MOV(bp, sp); reg_sp -= 4; PUSH(si); PUSH(di); W_MEMW(reg_bp - 2, 0); W_MEMW(reg_bp - 4, 0); reg_di = 0; reg_si = 0; do { // seg000:B4F5 W_MEMW(reg_bp - 4, 0); MOV(ax, di); reg_ax <<= 2; reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; reg_ax = MEMW(reg_bp - 2); W_MEMW(reg_bx, reg_ax); MOV(si, ax); while (1) { // seg000:B59A reg_ax = MEMW(reg_bp - 2); reg_ax += MEMW(reg_bp + 10); if (reg_ax <= reg_si) break; // seg000:B50F MOV(bx, si); int tmp1 = N_PADD(MEMD(reg_bp + 4), reg_bx); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); // seg000:B520 if (mem_readb(SegPhys(es) + reg_bx) == 0x1a) { // seg000:B526 W_MEMW(reg_bp - 4, 2); MOV(ax, di); reg_ax <<= 2; reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; MOV(ax, si); reg_ax -= MEMW(reg_bp - 2); W_MEMW(reg_bx + 2, reg_ax); MOV(ax, di); reg_ax++; reg_ax <<= 2; reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; W_MEMW(reg_bx, 0xffff); MOV(ax, di); reg_ax++; reg_ax <<= 2; reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; W_MEMW(reg_bx + 2, 0xffff); break; } // seg000:B561 MOV(bx, si); tmp1 = N_PADD(MEMD(reg_bp + 4), reg_bx); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); // seg000:B572 if (mem_readb(SegPhys(es) + reg_bx) == 0xd) { // seg000:B578 MOV(ax, di); reg_ax <<= 2; reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; MOV(ax, si); reg_ax -= MEMW(reg_bp - 2); reg_ax++; W_MEMW(reg_bx + 2, reg_ax); reg_di++; MOV(ax, si); reg_ax += 2; W_MEMW(reg_bp - 2, reg_ax); W_MEMW(reg_bp - 4, MEMW(reg_bp - 4) + 1); break; } // seg000:B599 reg_si++; } // seg000:B5A7 if (MEMW(reg_bp - 4) == 0) { // seg000:B5E3 while ((short)reg_si > (short)MEMW(reg_bp - 2)) { // seg000:B5AF MOV(bx, si); int tmp1 = N_PADD(MEMD(reg_bp + 4), reg_bx); reg_bx = tmp1 & 0xffff; SegSet16(es, tmp1 >> 16); // seg000:B5C0 if (mem_readb(SegPhys(es) + reg_bx) == 0x20) { // seg000:B5C6 MOV(ax, di); reg_ax <<= 2; reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; MOV(ax, si); reg_ax -= MEMW(reg_bp - 2); W_MEMW(reg_bx + 2, reg_ax); reg_di++; MOV(ax, si); reg_ax++; W_MEMW(reg_bp - 2, reg_ax); break; } // seg000:B5E2 reg_si--; } // seg000:B5E8 if (reg_si == MEMW(reg_bp - 2)) { // seg000:B5ED MOV(ax, di); reg_ax <<= 2; reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; reg_ax = MEMW(reg_bp + 10); W_MEMW(reg_bx + 2, reg_ax); reg_di++; reg_si += reg_ax; W_MEMW(reg_bp - 2, MEMW(reg_bp - 2) + reg_ax); } } // seg000:B604 if (reg_di == MEMW(reg_bp + 12)) { // seg000:B609 MOV(ax, di); reg_ax--; reg_ax <<= 2; reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; W_MEMW(reg_bx, 0xffff); MOV(ax, di); reg_ax--; reg_ax <<= 2; reg_bx = MEMW(reg_bp + 8); reg_bx += reg_ax; W_MEMW(reg_bx + 2, 0xffff); W_MEMW(reg_bp - 4, 2); } // seg000:B62F } while (MEMW(reg_bp - 4) < 2); // seg000:B638 MOV(ax, di); POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // B640 void scroll_text() { RETLOC(B6CA); RETLOC(B6AD); RETLOC(B69E); RETLOC(B691); RETLOC(B684); RETLOC(B677); RETLOC(B72F); RETLOC(B712); RETLOC(B6FE); RETLOC(B6F1); RETLOC(B6E4); RETLOC(B6D7); assert(reg_eip == 0xb640); PUSH(bp); MOV(bp, sp); reg_sp -= 2; PUSH(si); PUSH(di); reg_ax = MEMW(reg_bp + 6); reg_ax -= MEMW(reg_bp + 4); reg_ax <<= 3; reg_ax *= 0x30; W_MEMW(reg_bp - 2, reg_ax); reg_ax = MEMW(reg_bp + 8); // seg000:B65E if (reg_ax != 0) { // seg000:B662 if (reg_ax == 1) { // seg000:B6CD PUSHI(5); PUSHI(0x3ce); EMU_CALL(a__outportb, B6D7, scroll_text); reg_sp += 4; PUSHI(1); PUSHI(0x3cf); EMU_CALL(a__outportb, B6E4, scroll_text); reg_sp += 4; PUSHI(2); PUSHI(0x3c4); EMU_CALL(a__outportb, B6F1, scroll_text); reg_sp += 4; PUSHI(0xf); PUSHI(0x3c5); EMU_CALL(a__outportb, B6FE, scroll_text); reg_sp += 4; // seg000:B701 reg_ax = MEMW(reg_bp + 6); reg_ax *= 0x180; W_MEMW(reg_bp + 6, reg_ax); W_MEMW(reg_bp + 6, MEMW(reg_bp + 6) + 0x17f); EMU_INSTR(B711, B712, scroll_text); PUSH(si); PUSH(di); PUSHI(SegValue(ds)); // seg000:B715 reg_di = MEMW(reg_bp + 6); MOV(si, di); reg_si -= 0x180; reg_cx = MEMW(reg_bp - 2); reg_ax = MEMW(dstseg); SegSet16(es, reg_ax); SegSet16(ds, reg_ax); // seg000:B729 while (reg_cx != 0) { mem_writeb(SegPhys(es) + reg_di, mem_readb(SegPhys(ds) + reg_si)); reg_si--; reg_di--; reg_cx--; } POP(ax); SegSet16(ds, reg_ax); POP(di); POP(si); EMU_INSTR(B72E, B72F, scroll_text); } } else { // seg000:B66D PUSHI(5); PUSHI(0x3ce); EMU_CALL(a__outportb, B677, scroll_text); reg_sp += 4; PUSHI(1); PUSHI(0x3cf); EMU_CALL(a__outportb, B684, scroll_text); reg_sp += 4; PUSHI(2); PUSHI(0x3c4); EMU_CALL(a__outportb, B691, scroll_text); reg_sp += 4; PUSHI(0xf); PUSHI(0x3c5); EMU_CALL(a__outportb, B69E, scroll_text); reg_sp += 4; // seg000:B6A1 reg_ax = MEMW(reg_bp + 4); reg_ax *= 0x180; W_MEMW(reg_bp + 4, reg_ax); EMU_INSTR(B6AC, B6AD, scroll_text); PUSH(si); PUSH(di); PUSHI(SegValue(ds)); reg_di = MEMW(reg_bp + 4); MOV(si, di); reg_si += 0x180; reg_cx = MEMW(reg_bp - 2); reg_ax = MEMW(dstseg); SegSet16(es, reg_ax); SegSet16(ds, reg_ax); // seg000:B6C4 while (reg_cx != 0) { mem_writeb(SegPhys(es) + reg_di, mem_readb(SegPhys(ds) + reg_si)); reg_si++; reg_di++; reg_cx--; } POP(ax); SegSet16(ds, reg_ax); POP(di); POP(si); EMU_INSTR(B6C9, B6CA, scroll_text); } // seg000:B72F POP(di); POP(si); MOV(sp, bp); POP(bp); RET; } // B736 void clear_overlay() { assert(reg_eip == 0xb736); PUSH(di); reg_cx = 294; SegSet16(es, SegValue(ds)); reg_di = word_18B66; reg_ax = 0xFFFF; // seg000:B744 while (reg_cx != 0) { mem_writew(SegPhys(es) + reg_di, reg_ax); reg_di += 2; reg_cx--; } // seg000:B746 reg_cx = 294; reg_di = word_18E08; // seg000:B74C while (reg_cx != 0) { mem_writew(SegPhys(es) + reg_di, reg_ax); reg_di += 2; reg_cx--; } // seg000:B74E POP(di); RET; } void sub_B87C() { W_MEMW(ega_regen_start_addr, 4); reg_ax = MEMW(scroll_x_lo); if (reg_ax & 0x800) { // seg000:B88A W_MEMW(ega_regen_start_addr, MEMW(ega_regen_start_addr) + 1); } // seg000:B88E reg_ax = MEMW(scroll_x_lo + 1); reg_ax &= 7; W_MEMW(ega_colors, reg_ax); W_MEMW(word_186A2, MEMW(word_186A2) ^ 1); // seg000:B89C if ((MEMW(word_186A2) & 1) == 0) { // seg000:B8A4 reg_cx = 0xa000; } else { // seg000:B8AA reg_cx = 0xa300; W_MEMW(ega_regen_start_addr, MEMW(ega_regen_start_addr) + 0x3000); } // seg000:B8B3 W_MEMW(word_16602, reg_cx); reg_ax = MEMW(scroll_y_lo + 1); reg_ax &= 0xf; reg_bl = 0x30; reg_ax *= reg_bl; reg_ax += 0x600; W_MEMW(ega_regen_start_addr, MEMW(ega_regen_start_addr) + reg_ax); reg_ax = MEMW(ega_regen_start_addr); reg_ax >>= 4; reg_ax += 0xa000; W_MEMW(dstseg, reg_ax); RET; } // BE65 void setup_int8() { RETLOC(BEAC); RETLOC(BEA7); RETLOC(BEA1); RETLOC(BE9D); RETLOC(BE98); RETLOC(BE7E); RETLOC(BE79); // seg000:BE65 if (MEMW(sound_disabled) & 0xFFFF) { // seg000:BE6D RET; } // eg000:BE6E if ((MEMW(int8_set) & 0xffff) == 0) { // seg000:BE76 EMU_CALL(a_stop_cur_sound, BE79, setup_int8); reg_ax = 0x3508; EMU_INSTR(BE7C, BE7E, setup_int8); W_MEMW(orig_int8_off, reg_bx); reg_ax = SegValue(es); W_MEMW(orig_int8_seg, reg_ax); W_MEMB(int8_divider, 8); PUSHI(SegValue(ds)); PUSHI(SegValue(cs)); POP(ax); SegSet16(ds, reg_ax); reg_dx = a_int8_handler; reg_ax = 0x2508; EMU_INSTR(BE96, BE98, setup_int8); POP(ax); SegSet16(ds, reg_ax); reg_bx = 0x2000; EMU_INSTR(BE9C, BE9D, setup_int8); reg_al = 0x36; EMU_INSTR(BE9F, BEA1, setup_int8); reg_al = 0; MOV(al, bl); EMU_INSTR(BEA5, BEA7, setup_int8); MOV(al, bh); EMU_INSTR(BEA9, BEAC, setup_int8); W_MEMW(int8_set, MEMW(int8_set) + 1); } // seg000:BEB0 W_MEMW(want_sound, 1); RET; } void stop_cur_sound() { RETLOC(BF43); RETLOC(BF3E); if (MEMW(sound_disabled) & 0xffff) { // seg000:BF32 RET; } // seg000:BF33 W_MEMW(cur_sound_pos, 0); W_MEMB(sound_limiter, 0); EMU_INSTR(BF3B, BF3E, stop_cur_sound); reg_al &= 0xfd; EMU_INSTR(BF40, BF43, stop_cur_sound); RET; } void save_cur_sound() { RETLOC(BF62); if (MEMW(sound_disabled) & 0xffff) { // seg000:BF4C RET; } // seg000:BF4D reg_ax = MEMW(cur_sound_pos); W_MEMW(saved_sound_pos, reg_ax); reg_al = MEMB(sound_limiter); W_MEMB(saved_sound_limiter, reg_al); reg_al = MEMB(int8_divider); W_MEMB(saved_int8_divider, reg_al); EMU_CALL(a_stop_cur_sound, BF62, save_cur_sound); RET; } void restore_cur_sound() { if (MEMW(sound_disabled) & 0xffff) { // seg000:BF6B RET; } // seg000:BF6C reg_ax = MEMW(saved_sound_pos); W_MEMW(cur_sound_pos, reg_ax); reg_al = MEMB(saved_sound_limiter); W_MEMB(sound_limiter, reg_al); reg_al = MEMB(saved_int8_divider); W_MEMB(int8_divider, reg_al); RET; } void finish_cur_sound() { RETLOC(BF91); RETLOC(BF8D); if (MEMW(sound_disabled) & 0xffff) { // seg000:BF87 RET; } // seg000:BF88 EMU_INSTR(BF88, BF8D, finish_cur_sound); do { // seg000:BF8E EMU_INSTR(BF8E, BF91, finish_cur_sound); // fetches cur_sound_pos } while (reg_ax != 0); RET; } void sub_C1FF() { printf("sub_C1FF\n"); } void sub_C22B() { printf("sub_C22B\n"); } void sub_C23B() { printf("sub_C23B\n"); } void sub_C27D() { printf("sub_C27D\n"); } void sub_C2C8() { printf("sub_C2C8\n"); } // C2D5 void sub_C2D5() { W_MEMW(word_18315, 0); W_MEMW(word_18318, 1); W_MEMW(word_18311, 0); W_MEMW(word_18313, 0); reg_si = MEMW(word_1830B); reg_di = MEMW(word_18309); RET; } void sub_C2F6() { printf("sub_C2F6\n"); } void sub_C328() { printf("sub_C328\n"); } // C35F void sub_C35F() { RETLOC(C362); assert(reg_eip == 0xC35F); EMU_CALL(a_sub_C2D5, C362, sub_C35F); short tmps = reg_si; reg_si = reg_di; reg_di = tmps; reg_dx = 1; // seg000:C367 SegSet16(es, MEMW(word_18307)); reg_ah = 0; while(1) { // seg000:C36D while (reg_di >= 0xfff0) { // seg000:C372 MOV(ax, di); reg_ax >>= 4; W_MEMW(word_18307, MEMW(word_18307) + reg_ax); reg_di = 0; MOV(ax, si); reg_ax >>= 4; W_MEMW(word_18305, MEMW(word_18305) + reg_ax); reg_si += 0xf; // duplicated from seg000:C367 SegSet16(es, MEMW(word_18307)); reg_ah = 0; } // seg000:C396 bool below = MEMD(dword_1830D) < reg_dx; W_MEMD(dword_1830D, MEMD(dword_1830D) - reg_dx); if (below) break; // seg000:C3A1 reg_dx = 0; PUSHI(SegValue(ds)); SegSet16(ds, MEMW(word_18305)); reg_al = MEMB(reg_si); reg_si++; // seg000:C3A9 if (reg_al >= 0x80) { // seg000:C3AD reg_al -= 0x7f; MOV(cx, ax); MOV(dx, ax); // seg000:C3B3 while (reg_cx != 0) { mem_writeb(SegPhys(es) + reg_di, MEMB(reg_si)); reg_si++; reg_di++; reg_cx--; } POP(cx); SegSet16(ds, reg_cx); } else { // seg000:C3B8 reg_al += 3; MOV(cx, ax); MOV(dx, ax); reg_al = MEMB(reg_si); reg_si++; while (reg_cx != 0) { mem_writeb(SegPhys(es) + reg_di, reg_al); reg_di++; reg_cx--; } POP(cx); SegSet16(ds, reg_cx); } } // seg000:C3C4 RET; } void sub_C3C5() { printf("sub_C3C5\n"); } // C513 void sub_C513() { RETLOC(C550); assert(reg_eip == 0xC513); PUSH(bp); MOV(bp, sp); reg_ax = MEMW(reg_bp + 4); W_MEMW(word_18309, reg_ax); reg_ax = MEMW(reg_bp + 6); W_MEMW(word_18305, reg_ax); reg_ax = MEMW(reg_bp + 8); W_MEMW(word_1830B, reg_ax); reg_ax = MEMW(reg_bp + 0xa); W_MEMW(word_18307, reg_ax); PUSHI(SegValue(es)); PUSH(si); reg_ax = MEMW(word_18305); SegSet16(es, reg_ax); reg_si = MEMW(word_18309); reg_ax = mem_readw(SegPhys(es) + reg_si); W_MEMW(dword_1830D, reg_ax); reg_ax = mem_readw(SegPhys(es) + reg_si + 2); W_MEMW(dword_1830D + 2, reg_ax); POP(si); POP(ax); SegSet16(es, reg_ax); W_MEMW(word_18309, MEMW(word_18309) + 4); EMU_CALL(a_sub_C35F, C550, sub_C513); POP(bp); RET; } void sub_C552() { RETLOC(C55F); assert(reg_eip == 0xc552); PUSH(bp); MOV(bp, sp); PUSH(si); PUSHI(0); PUSHI(MEMW(reg_bp + 4)); EMU_CALL(a___chmod, C55F, sub_C552); POP(cx); POP(cx); MOV(si, ax); // seg000:C563 if (reg_ax != 0xffff) { // seg000:C56A if ((MEMW(reg_bp + 6) & 2) == 0 || (reg_si & 1) == 0) { // seg000:C577 reg_ax = 0; } else { // seg000:C57B W_MEMW(word_130E2, 5); reg_ax = 0xffff; } } // seg000:C584 POP(si); POP(bp); RET; } // CD36 void sub_CD36() { PUSH(bp); MOV(bp, sp); reg_dx = MEMW(reg_bp + 4); // seg000:CD3C if (reg_dx == 0xffff) { // seg000:CD41 reg_ax = 0xffff; } else { // seg000:CD46 MOV(al, dl); reg_ah = 0; MOV(bx, ax); // seg000:CD4C if (MEMB(byte_1831F + reg_bx) & 8) { // seg000:CD53 MOV(al, dl); reg_ah = 0; reg_ax += 0xffe0; } else { // seg000:CD5C MOV(al, dl); reg_ah = 0; } } // seg000:CD60 POP(bp); RET; } void sub_CD62() { // very much looks like a library function for fputs } void sub_CE72() { printf("sub_CE72\n"); } void sub_D296() { PUSH(bp); MOV(bp, sp); PUSH(si); reg_si = MEMW(reg_bp + 4); // seg000:D29D if ((short)reg_si >= 0) { // seg000:D2A1 if ((short)reg_si > 0x58) { loc_D2A6: // seg000:D2A6 reg_si = 0x57; } // seg000:D2A9 W_MEMW(word_185B6, reg_si); reg_ax = (char)MEMB(byte_185B8 + reg_si); MOV(si, ax); } else { // seg000:D2B6 MOV(ax, si); reg_ax = -(short)reg_ax; MOV(si, ax); // seg000:D2BC if ((short)reg_ax > 0x23) goto loc_D2A6; // seg000:D2C1 W_MEMW(word_185B6, 0xffff); } // seg000:D2C7 W_MEMW(word_130E2, reg_si); reg_ax = 0xffff; POP(si); POP(bp); reg_eip = 0xd2d0; return; } int cpu_count = 0; typedef func *funcp; funcp *simmap = NULL; #define IS_KEEN_SEG (mem_readd(SegPhys(cs) + 8) == 0x21cd30b4) //#define SIM(a, f) if (reg_eip < 0x##a) return true; if (reg_eip == 0x##a && IS_KEEN_SEG) { int orig_eip = reg_eip; f(); cpu_count += 5; return (orig_eip == reg_eip); } #define SIM(a, f) simmap[0x##a] = f; Bit16u keen_seg; bool unhandled_addrs[0x10000]; int unhandled_addr_count = 0; #define COUNT_UNHANDLED 1 #define CHECK_FOR_UNHANDLED 1 #define DO_SIM 1 // returns true if the instruction pointed to by eip should be emulated bool do_keen_checks() { if (cpu_count > 0) { cpu_count--; return false; } if (trace) { static int trace_count = 0; trace_count++; //if ((trace_count % 10) == 0) // getchar(); //assert(trace_count < 30); if (SegValue(cs) != keen_seg) getchar(); printf("%x:%x %x\n", SegValue(cs), reg_ip, reg_eip); } // handle return location emulation for (int i = num_retlocs - 1; i >= 0; i--) if (reg_ip == retlocs[i].addr && IS_KEEN_SEG) { if (i == num_retlocs - 1) num_retlocs--; (*retlocs[i].func)(); return false; } if (simmap == NULL) { simmap = new funcp[0x10000]; memset(simmap, 0, sizeof(func*) * 0x10000); memset(unhandled_addrs, 0, sizeof(unhandled_addrs)); #if DO_SIM SIM(015C, int0_handler); SIM(0165, setup_int_vecs); SIM(0218, output_error); SIM(0239, sync_drawing); SIM(0289, draw_screen); SIM(02C5, draw_sprite_at); SIM(0501, slide_sprite); SIM(066B, load_level_data); SIM(082B, handle_quit); SIM(0983, show_image_file); SIM(0AF2, screenshot); SIM(0C51, handle_global_keys); SIM(0D52, add_score); SIM(0DB0, start_cheating); SIM(0E3A, show_pause_menu); SIM(11F0, handle_cheat_keys); SIM(1261, chg_vid_and_error); SIM(12CF, keen_main); SIM(15EB, init_level); SIM(1713, add_monster_1_tank_bot); SIM(1777, add_monster_2); SIM(17D5, add_monster_3); SIM(1843, add_monster_4); SIM(1880, add_monster_5); SIM(18E3, add_monster_6); SIM(1920, add_special_body); SIM(194F, think_yorp_walk); SIM(19D3, think_yorp_look); SIM(1A2C, think_20_yorp_incapacitated); SIM(1A68, contact_5_yorp); SIM(1AA8, think_22_garg_move); SIM(1B51, think_4_garg_look); SIM(1BCE, contact_4); SIM(1C0E, think_3); SIM(1CC8, think_23); SIM(1D15, think_24_vort_search); SIM(1D6E, contact_3); SIM(1DC7, think_2); SIM(1E5E, think_25); SIM(1E94, contact_2); SIM(1EA9, think_28_tankbot_move); SIM(1F75, think_1_tankbot_default); SIM(1F8F, think_27_tankbot_turn); SIM(1FC1, think_26_tankbot_shoot); SIM(2045, contact_nop); SIM(204A, think_15); SIM(20CB, add_monster_7); SIM(2151, think_8); SIM(2192, think_7); SIM(22A6, contact_7); SIM(22BB, contact_6); SIM(2369, think_body_6); SIM(24F4, show_message); SIM(26FE, think_14); SIM(273D, slide_door); SIM(27F8, open_door); SIM(290E, think_19); SIM(2919, default_think); SIM(2927, default_contact); SIM(2935, add_monster); SIM(297E, add_body); SIM(29BD, detect_mnstr_col); SIM(2A3B, sub_2A3B); SIM(2AE9, detect_worldmap_col); SIM(2B9A, move_left_right); SIM(2BDF, pogo_jump); SIM(2C2A, do_fall); SIM(2C6D, compute_sprite_delta); SIM(2C97, check_ground); SIM(3296, sprite_active_screen); SIM(3360, think_contact_nop); SIM(3365, check_ceiling); SIM(3418, do_scrolling); SIM(3592, lights_on); SIM(35B2, lights_out); SIM(35D2, toggle_switch); SIM(3867, think_13); SIM(3B8B, think_32); SIM(3C99, think_29); SIM(3E12, think_33_fire_raygun); SIM(3EC8, think_30); SIM(4054, think_31); SIM(40EF, think_18_keen_exit); SIM(41F8, think_17); SIM(4260, kill_keen); SIM(42EA, detect_background_col()); SIM(45C4, think_16); SIM(46BA, add_monster_8); SIM(47E8, think_11); SIM(4808, think_9_raygun_flight); SIM(4849, contact_9_raygun); SIM(488E, think_34); SIM(489D, think_12); SIM(48DE, add_monster_9_tank_shot); SIM(4A00, contact_10); SIM(4A45, think_body_3); SIM(4A8B, bridge_extend); SIM(4AFA, bridge_retract); SIM(4B69, draw_level); SIM(4FA9, handle_joystick); SIM(51FA, draw_keyname); SIM(53C0, handle_redef_keys); SIM(55A3, get_keyb_ctrl_state); SIM(56DB, get_mouse_ctrl); SIM(5811, poll_joystick); SIM(58AF, get_joystick_ctrl); SIM(5A39, handle_ctrl); SIM(5C3A, clear_keys); SIM(5C58, sub_5C58); SIM(5CB8, map_file_to_mem); SIM(5D63, write_file); SIM(5DE4, alloc_and_map_file); SIM(5F1E, draw_box2); SIM(604E, draw_box); SIM(608C, sub_608C); SIM(60BE, draw_box_opening2); SIM(614B, sub_614B); SIM(611A, draw_box_opening); SIM(6268, read_char_with_echo); SIM(62D2, draw_string); SIM(632A, draw_number); SIM(636B, get_file_length); SIM(6476, draw_stringz); SIM(65B7, get_string_input); SIM(665D, init_ctrls); SIM(67A9, save_ctrls); SIM(6884, decomp_file); SIM(6A30, sub_6A30); SIM(6B62, sub_6B62); SIM(6BD4, sub_6BD4); SIM(6C49, fade_in); SIM(6C8D, fade_out); SIM(6CE6, decomp_graphics); SIM(7881, init_background); SIM(7913, main_loop); SIM(7ABB, sub_7ABB); SIM(7C04, draw_worldmap); SIM(805E, mark_cities_done); SIM(8132, sub_8132); SIM(8150, draw_stringz2); SIM(818C, draw_win); SIM(8919, handle_secret_city); SIM(8ADF, game_over); SIM(8F26, show_keens_left); SIM(8F90, sub_8F90); SIM(8FF0, do_intro_and_menu); SIM(928F, draw_title); SIM(95FD, draw_menu); SIM(96B0, start_menu); SIM(96E2, do_previews); SIM(9732, show_about_us); SIM(97F0, draw_about_us); SIM(97AB, draw_mural); SIM(97D3, do_draw_mural); SIM(984C, do_about_us); SIM(986C, draw_scores); SIM(9A24, do_scores); SIM(9A59, show_scores); SIM(9AB4, save_game); SIM(9C4E, continue_game); SIM(9D73, do_story); SIM(9DB4, do_help); SIM(9E32, sub_9E32); SIM(9E6D, sub_9E6D); SIM(9FB2, do_text_viewer); SIM(A1D4, sub_A1D4); SIM(A1EB, show_logo_text); SIM(A262, scroll_up_logo); SIM(A33B, do_ordering_info); SIM(A497, draw_ordering_info); SIM(A566, show_ordering_info); SIM(A5BC, draw_invvid_string); SIM(A616, check_world_map_col); SIM(AA95, move_worldmap); SIM(AE1C, draw_game); SIM(B185, wait_for_key); SIM(B243, sub_B243); SIM(B364, process_text_file); SIM(B4DF, draw_text_page); SIM(B640, scroll_text); SIM(B736, clear_overlay); SIM(B750, do_drawing); SIM(B87C, sub_B87C); SIM(B8E0, draw_char); SIM(B939, do_overdraw); SIM(BAB6, draw_filter); SIM(BB2D, draw_sprite); SIM(BC3B, blit_1); SIM(BC54, blit_2); SIM(BC6F, blit_3); SIM(BC95, blit_4); SIM(BCBB, blit_5); SIM(BCEC, blit_6); SIM(BD1D, blit_7); SIM(BD59, blit_8); SIM(BD95, setup_int9); SIM(BDB0, restore_int9); SIM(BDCE, translate_key); SIM(BE1A, int9_handler); SIM(BE65, setup_int8); SIM(BEB7, restore_int8); SIM(BEF3, set_cur_sound); SIM(BF2A, stop_cur_sound); SIM(BF44, save_cur_sound); SIM(BF63, restore_cur_sound); SIM(BF7F, finish_cur_sound); SIM(BF97, int8_handler); SIM(C013, sub_C013); SIM(C05C, calc_jump_height); SIM(C0AC, init_rnd); SIM(C0CE, get_random); SIM(C0E2, delay); SIM(C104, vga_regplane_select); SIM(C169, detect_video); SIM(C1FF, sub_C1FF); SIM(C22B, sub_C22B); SIM(C23B, sub_C23B); SIM(C27D, sub_C27D); SIM(C297, check_vid_mode); SIM(C2C8, sub_C2C8); SIM(C2D5, sub_C2D5); SIM(C2F6, sub_C2F6); SIM(C328, sub_C328); SIM(C35F, sub_C35F); SIM(C3C5, sub_C3C5); SIM(C513, sub_C513); SIM(C552, sub_C552); SIM(C5FA, extend_bss); SIM(C678, check_extend_bss); SIM(C6B7, check_extend_bss2); SIM(CD36, sub_CD36); SIM(CD62, sub_CD62); SIM(CE72, sub_CE72); SIM(DEE4, alloc_mem); SIM(D296, sub_D296); #endif } func *fs = simmap[reg_ip]; if (fs && IS_KEEN_SEG) { keen_seg = SegValue(cs); int orig_eip = reg_eip; (*fs)(); return orig_eip == reg_eip; } #if CHECK_FOR_UNHANDLED if (mem_readb(SegPhys(cs) + reg_eip) == 0x55 && IS_KEEN_SEG) { if (reg_eip >= 0xC552) ; // library function else if (reg_eip != 0xc1af) printf("unhandled %x\n", reg_eip); } #endif #if COUNT_UNHANDLED if (IS_KEEN_SEG && reg_eip < 0xc552) { if (unhandled_addrs[reg_ip] == 0) { printf("unhandled addr %i: 0x%04x\n", unhandled_addr_count, reg_ip); unhandled_addrs[reg_ip] = 1; unhandled_addr_count++; } } #endif return true; } // last updated: 10/5 2009 (lemm)