     1                                  
     2                                  %if 0
     3                                  
     4                                  lDebug expression evaluator
     5                                  
     6                                  Copyright (C) 1995-2003 Paul Vojta
     7                                  Copyright (C) 2008-2026 E. C. Masloch
     8                                  
     9                                  Usage of the works is permitted provided that this
    10                                  instrument is retained with the works, so that any entity
    11                                  that uses the works is notified of this instrument.
    12                                  
    13                                  DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    14                                  
    15                                  %endif
    16                                  
    17                                  %define SOURCEFILENAME "expr.asm"
    18                                  %ifidni __OUTPUT_FORMAT__, obj
    19                                   %include "debug.mac"
     1                              <1> [list -]
    14                              <3> [list -]
    14                              <2> [list -]
    86                              <1> [list -]
    86          ------------------  <1>  note: Disable usesection detection
    86          ------------------  <1>  note: usesection lDEBUG_DATA_ENTRY
    86          ------------------  <1>  note: usesection ASMTABLE1
    86          ------------------  <1>  note: usesection ASMTABLE2
    86          ------------------  <1>  note: usesection DATASTACKBASE
    86          ------------------  <1>  note: usesection MESSAGESEGMENT
    86          ------------------  <1>  note: usesection lDEBUG_CODE
    86          ------------------  <1>  note: usesection lDEBUG_CODE2
    86          ------------------  <1>  note: usesection INIT
    86          ------------------  <1>  note: usesection WLEMITALIGNINITEND
    86          ------------------  <1>  note: usesection DEVICESHIM
    86          ------------------  <1>  note: usesection WLEMITALIGNRELOCZERO
    68                              <2> %endif
    69                              <2> 
    70                              <2> 
    71                              <2> 	usesection lDEBUG_CODE
    71          ------------------  <2>  note: usesection lDEBUG_CODE
    72                              <2> section_of puts, trimputs, puts_ext_done, puts_ext_next
    73                              <2> section_of putsz_exthelp, code_retf
    74                              <2> section_of puts_getline_ext_done
    75                              <2> section_of puts_copyoutput_ext_done
    76                              <2> section_of guard_auxbuff, guard_re
    77                              <2> section_of handle_serial_flags_ctrl_c
    78                              <2> section_of hexword_high
    79                              <2> section_of call_int2D
    80                              <2> section_of copy_single_counted_string
    81                              <2> section_of intchk
    82                              <2> section_of IsIISPEntry?
    83                              <2> section_of dd_store
    84                              <2> section_of dohack, getsegmented, hexbyte, hexnyb, iseol?.notsemicolon
    85                              <2> section_of peekc, getc, prephack, readmem, setds2si, setds2bx, setes2dx
    86                              <2> section_of silence_get_start, silence_get_start.have_di, silence_count_zeroes
    87                              <2> section_of setrmlimit, skipcomm0, unhack
    88                              <2> section_of skipequals
    89                              <2> section_of to_errret_pop
    90                              <2> section_of cmd3.have_cx_convenience
    91                              <2> section_of verifysegm, verifysegm_or_error
    92                              <2> section_of pp16, resetmode, resetmode_and_test_d_b_bit
    93                              <2> section_of pp_fix32bitflags, proceedbreakpoint
    94                              <2> section_of putsz, hexword, skipcomma, cmd3, cmd3_not_ext, cmd3_preprocessed
    95                              <2> section_of hexdword
    96                              <2> section_of cmd3_not_inject, cmd3_injected
    97                              <2> section_of aa_not_inject, aa_injected, aa_before_getline, aa_after_getline
    98                              <2> section_of transfer_ext_cx_nearcall_from_code2
    99                              <2> section_of traceone, unexpectedinterrupt, dumpregs_no_disasm
   100                              <2> section_of aa_imm_entry, ia_restore_a_addr, ia_restore_u_addr, disasm
   101                              <2> section_of ia_restore_ds
   102                              <2> %ifn _SYMBOLIC
   103                              <2> section_of selector_to_segment
   104                              <2> %endif
   105                              <2> section_of disp_al, disp_al_hex, disp_al_nybble_hex, disp_ax_dec, disp_ax_hex
   106                              <2> section_of disp_dxax_times_cx_width_bx_size
   107                              <2> section_of disp_dxax_times_cx_width_bx_size.store
   108                              <2> section_of disp_message, disp_message_length_cx
   109                              <2> section_of ispm
   110                              <2> section_of setrc, error
   111                              <2> section_of _doscall, _doscall_return_es, _doscall_return_es_parameter_es_ds
   112                              <2> section_of intcall_ext_return_es, close_ext, doscall_extseg
   113                              <2> section_of yy_reset_buf
   114                              <2> section_of init_bootcmd
   115                              <2> 
   116                              <2> section_of InDOS, bootgetmemorysize
   117                              <2> section_of chkeol, decword, decdword
   118                              <2> section_of dec_dword_minwidth
   119                              <2> section_of getexpression.lit_isdigit?, getexpression.lit_ishexdigit?
   120                              <2> section_of getlinearaddr
   121                              <2> section_of getlinear_d_b
   122                              <2> section_of getlinear_high_limit
   123                              <2> section_of getlinear_32bit
   124                              <2> section_of getlinear_high_limit.do_not_use_test
   125                              <2> section_of getlinear_common
   126                              <2> section_of ifsep, iseol?, isseparator?, isstring?, movp
   127                              <2> section_of putc, putsline, putsline_crlf, putsz_error
   128                              <2> section_of setrmsegm
   129                              <2> section_of skipwh0, skipwhite
   130                              <2> section_of test_d_b_bit, test_high_limit, push_cxdx_or_edx
   131                              <2> section_of capitalise
   132                              <2> section_of setes2ax
   133                              <2> section_of zz_copy_strings_to_str_buffer
   134                              <2> section_of call_xms_move, zz_call_xms, zz_detect_xms
   135                              <2> section_of code2_to_code_ret_to_ext
   136                              <2> section_of yy_dos_parse_name, yy_open_file, yy_check_lfn
   137                              <2> section_of yy_common_parse_name
   138                              <2> section_of yy_common_parse_name_bx_buffer
   139                              <2> section_of retry_open_scriptspath
   140                              <2> section_of yy_boot_read.bx, yy_boot_seek_start.bx, yy_boot_seek_current.bx
   141                              <2> section_of yy_boot_parse_name, yy_boot_open_file
   142                              <2> section_of yy_boot_parse_name_bx_buffer
   143                              <2> section_of near_transfer_ext_return, scan_dir_aux, read_sector
   144                              <2> section_of yy_boot_init_dir, got_yyentry, scan_dir_entry
   145                              <2> section_of ..@yy_filename_empty, boot_parse_fn
   146                              <2> section_of count_store, count_store.maybe_0
   147                              <2> section_of loader_get_resident_address, loader_prepare_resident
   148                              <2> 
   149                              <2> 
   150                              <2>  %if _SYMBOLIC && _DUALCODE && _SYMBOLASMDUALCODE
   151                              <2> 	usesection lDEBUG_CODE2
   152                              <2>  %else
   153                              <2> 	usesection lDEBUG_CODE
   153          ------------------  <2>  note: usesection lDEBUG_CODE
   154                              <2>  %endif
   155                              <2> section_of bxcx_to_cx_paragraphs
   156                              <2> section_of zz_list_symbol.first, zz_list_symbol.subsequent
   157                              <2> section_of zz_xms_to_86mm, zz_xms_try_free, zz_xms_try_free_handle
   158                              <2> section_of zz_86mm_to_xms, zz_del_match.add_poison_entrypoint
   159                              <2> section_of zz_free_nonxms, zz_free_xms, zz_free_reset, zz_free_dos
   160                              <2> section_of zz_get_literal, zz_restore_strat, zz_save_strat
   161                              <2> section_of zz_switch_s, zz_transfer_buffer
   162                              <2> 
   163                              <2> 
   164                              <2> %if _SYMBOLIC
   165                              <2>  %if _DUALCODE && _SYMBOLICDUALCODE
   166                              <2> 	usesection lDEBUG_CODE2
   167                              <2>  %else
   168                              <2> 	usesection lDEBUG_CODE
   169                              <2>  %endif
   170                              <2> section_of shift_left_4_bxcx
   171                              <2> section_of selector_to_segment
   172                              <2> 
   173                              <2> section_of anti_normalise_pointer_with_displacement_bxcx, displaystring
   174                              <2> section_of getfarpointer.hash, getfarpointer.main, getfarpointer.str
   175                              <2> section_of move_delete_farpointer.hash, move_delete_farpointer.hash.sidi
   176                              <2> section_of move_delete_farpointer.main, move_delete_farpointer.str.sidi
   177                              <2> section_of move_insert_farpointer.hash, move_insert_farpointer.hash.sidi
   178                              <2> section_of move_insert_farpointer.main, move_insert_farpointer.main.sidi
   179                              <2> section_of move_insert_farpointer.str.sidi
   180                              <2> section_of normalise_pointer, normalise_pointer_with_displacement_bxcx
   181                              <2> section_of pointer_to_linear
   182                              <2> section_of save_slice_farpointer.hash, save_slice_farpointer.main
   183                              <2> section_of save_slice_farpointer.str
   184                              <2> section_of segment_to_selector
   185                              <2> section_of zz_insert, zz_match_symbol, zz_match_symbol.continue, zz_relocate
   186                              <2> 
   187                              <2> section_of binsearchhash, binsearchmain
   188                              <2> section_of check_second_slice
   189                              <2> section_of disp_size_hash, disp_size_main, disp_size_str
   190                              <2> section_of displayresult, getstring1, getstring2
   191                              <2> section_of increment_ss_ref_count
   192                              <2> section_of list_sym_storage_usage, str_index_to_pointer
   193                              <2> section_of zz_commit_insert, zz_compact, zz_compact_expand_check_nonxms
   194                              <2> section_of zz_compact_expand_check_xms
   195                              <2> section_of zz_delete_hash, zz_delete_main, zz_delete_main_and_its_hash
   196                              <2> section_of zz_delete_string, zz_expand, zz_expand_common
   197                              <2> section_of zz_get_symstr_length_bytes
   198                              <2> section_of zz_get_symstr_length_bytes.ssLength_in_cx
   199                              <2> section_of zz_get_symstr_length_indices
   200                              <2> section_of zz_get_symstr_length_indices.ssLength_in_cx
   201                              <2> section_of zz_hash, zz_hash.bx_init
   202                              <2> section_of zz_insert_main.linklist, zz_reloc_main, zz_reloc_str
   203                              <2> section_of zz_store_pre_str, zz_store_string, zz_store_string.hash_bx
   204                              <2> section_of zz_unlink_main_next
   205                              <2> %endif
   206                              <2> 
   207                              <2> %if _DUALCODE
   208                              <2> 	usesection lDEBUG_CODE2
   208          ------------------  <2>  note: usesection lDEBUG_CODE2
   209                              <2> %else
   210                              <2> 	usesection lDEBUG_CODE
   211                              <2> %endif
   212                              <2> section_of FloatToStr
   213                              <2> 
   214                              <2> 
   215                              <2>  %if _DUALCODE && _EXPRDUALCODE
   216                              <2> 	usesection lDEBUG_CODE2
   216          ------------------  <2>  note: usesection lDEBUG_CODE2
   217                              <2>  %else
   218                              <2> 	usesection lDEBUG_CODE
   219                              <2>  %endif
   220                              <2> 
   221                              <2> section_of getofsforbx, checkpointer, getrangeX
   222                              <2> section_of getrangeX_have_address_need_length
   223                              <2> section_of getrange, getaddr, getofsforbx_remember_bitness
   224                              <2> section_of remember_bitness, getaddr_taken
   225                              <2> section_of getstr, get_length, get_length_keyword
   226                              <2> section_of isbracketorunaryoperator?, isunaryoperator?, isoperator?
   227                              <2> section_of ..@call_operator_dispatchers
   228                              <2> section_of isseparator?, istype?, isunsignedtype?
   229                              <2> section_of handlesegment, handle3byte, handlebyte, handleword
   230                              <2> section_of handledword, handlepointer
   231                              <2> section_of uoh_abs, uoh_minus, calculate_minus_bxdx, uoh_plus
   232                              <2> section_of uoh_not_bitwise, uoh_not_boolean
   233                              <2> section_of od_minus, od_plus, od_multiply, od_divide, od_modulo, od_retn
   234                              <2> section_of od_above, od_below, od_equal, od_not, od_or, od_and, od_xor
   235                              <2> section_of od_cond, od_o, od_a, od_x, od_c, od_string_common
   236                              <2> section_of of_modulo, of_minus, of_plus, or_hhtype, of_multiply
   237                              <2> section_of set_hhtype, of_divide, of_power
   238                              <2> section_of of_compare_below_equal, of_compare_below, of_compare_not_equal
   239                              <2> section_of of_compare_equal, of_compare_above_equal, of_compare_above
   240                              <2> section_of toboolean, of_helper_compare_true, of_rightop, of_helper_compare
   241                              <2> section_of of_shift_right, of_shift_right_signed, of_shift_left
   242                              <2> section_of of_helper_getshiftdata, of_bit_mirror
   243                              <2> section_of of_or_bitwise, or_hhtype_1, of_or_boolean, of_clr_bitwise
   244                              <2> section_of of_and_bitwise, of_and_boolean, of_xor_bitwise, of_xor_boolean
   245                              <2> section_of of_helper_retbool, of_helper_getbool
   246                              <2> 
   247                              <2> section_of var_cip_setup, var_csp_setup, var_lfsr_setup, var_reverselfsr_setup
   248                              <2> section_of var_dpspsel_setup, var_seldbg_setup, var_mt_setup
   249                              <2> section_of var_ioi_setup, var_psps_setup, var_ppr_setup, var_ppi_setup
   250                              <2> section_of var_iok_setup, var_rhcount_setup
   251                              <2> section_of var_get_psp_segment, var_get_psp_selector
   252                              <2> section_of var_bootldpunit_setup, var_bootsdpunit_setup, var_bootydpunit_setup
   253                              <2> section_of var_bootldppart_setup, var_bootsdppart_setup, var_bootydppart_setup
   254                              <2> section_of var_bootunitflags_setup
   255                              <2> 
   256                              <2> section_of issymbol?, isvariable?, var_mm_setup, var_ri_setup, var_ysf_setup
   257                              <2> section_of default_variable_setup
   258                              <2> section_of var_ext_setup
   259                              <2> section_of var_ext_setup_done
   260                              <2> 
   261                              <2> section_of getstmmxdigit
   262                              <2> section_of getexpression.lit_ishexdigit?, getexpression.lit_isdigit?
   263                              <2> section_of of_cond, count_unary_operators, count_unary_operators_restrict
   264                              <2> section_of get3byte.checksignificantbits, getbyte, checksignificantbitscommon
   265                              <2> section_of getnyb, get_value_range
   266                              <2> 
   267                              <2> section_of getaddrX, getword, getdword, getexpression
   268                              <2> 
   269                              <2> section_of getrangeX.lines, getrangeX.ecx_and_0_valid
   270                              <2> section_of getrange.lines, getrange.ecx_and_0_valid, get_length.lines
   271                              <2> section_of getrangeX.lines_and_uu, getrange.lines_and_uu
   272                              <2> section_of isseparator?.except_L_or_dot, isvariable?.return_name
   273                              <2> section_of getword.checksignificantbits, getbyte.checksignificantbits
   274                              <2> 
   275                              <2> section_of seg_bx_to_sel
   276                              <2> section_of getexpression.countsignificantbits
   277                              <2> section_of ..@rr_checksignificantbits, ..@rr_operatordispatchers
   278                              <2> section_of ..@rr_operatorfunctions, ..@parsecm_getaddr
   279                              <2> section_of stack_check.internal
   280                              <2> 
   281                              <2> 
   282                              <2> 	usesection INIT
   282          ------------------  <2>  note: usesection INIT
   283                              <2> section_of init_capitalise
   284                              <2> section_of init_skipwhite, init_skipwh0
   285                              <2> section_of init_skipcomma, init_skipcomm0
   286                              <2> section_of init_skipequals
   287                              <2> 
   288                              <2> 
   289                              <2> 	usesection lDEBUG_DATA_ENTRY
   289          ------------------  <2>  note: usesection lDEBUG_DATA_ENTRY
   290                              <2> section_of entry_retn
   291                              <2> 
   292                              <2> 
   293                              <2> %if _LINK
   294                              <2>  %include "extern.mac"
     1                              <3> 
     2                              <3> ; expr.asm
     3                              <3>  extern PPLEN, PPLEN_ONLY_PREFIXES, a_addr, alloc_seg, alloc_size
     4                              <3>  extern amis_multiplex_number, asm_options, asm_startoptions
     5                              <3>  extern auxbuff_current_size, auxbuff_segorsel, behind_r_u_addr
     6                              <3>  extern bp_offset, code_seg, code_size, d_addr, dcount_addr
     7                              <3>  extern dcpm_addr, dd_default_length, dd_default_lines, dd_text_and
     8                              <3>  extern debuggerfunction, default_pp_count, default_tp_count
     9                              <3>  extern default_tt_count, device_header_address, device_mcb_paragraphs
    10                              <3>  extern dwcount_addr, dz_addr, e_addr, encodedmach87, entryseg_size
    11                              <3>  extern env_size, envseg, erc, errret
    12                              <3>  extern extdata, extdata_size, extdata_used, extseg, extseg_size
    13                              <3>  extern extseg_used, flagbits.amount, flagnames, flagvaron
    14                              <3>  extern getrange_is_uu, getrange_lines, has_mmx, hhresult
    15                              <3>  extern history.segorsel, historyseg_size, immseg, input_file_handles
    16                              <3>  extern input_file_handles.active, internalflags, internalflags2
    17                              <3>  extern internalflags3, intr8_limit, io_columns, io_columns_getline
    18                              <3>  extern io_end_buffer, io_flags, io_levels, io_rows, io_start_buffer
    19                              <3>  extern line_out, line_out_end, linkinfoaddress, load_data
    20                              <3>  extern load_input_file, load_input_file.active, load_unit_flags
    21                              <3>  extern loaddata_loadedfrom, machine, maxmachinetype, messageseg
    22                              <3>  extern messageseg_size, mmxbuff, msg.as, msg.end, msg.executing
    23                              <3>  extern msg.executing_value_range, msg.from, msg.in, msg.length
    24                              <3>  extern msg.linear, msg.lines, msg.lr, msg.nd, msg.nottaken
    25                              <3>  extern msg.nt, msg.or, msg.questionmark, msg.r, msg.stack_overflow
    26                              <3>  extern msg.stack_overflow.caller, msg.stack_overflow.cond
    27                              <3>  extern msg.stack_overflow.indirection, msg.stack_overflow.linear
    28                              <3>  extern msg.stack_overflow.parens, msg.stack_overflow.precedence
    29                              <3>  extern msg.stack_overflow.value_in, msg.t, msg.taken, msg.to
    30                              <3>  extern msg.value, msgtable_value_range, options, options2, parent
    31                              <3>  extern ppbytes, priorrc, psp22, pspdbe, pspdbg
    32                              <3>  extern qqtermcode, rc_count, rc_limit, re_count, re_limit
    33                              <3>  extern reading_access_variables, reg16names, reg8names, reg_cs
    34                              <3>  extern reg_ds, reg_efl, reg_eip, reg_esp, search_results
    35                              <3>  extern serial_columns, serial_fifo_size, serial_keep_timeout
    36                              <3>  extern serial_rows, serial_use_baseport, serial_use_dl
    37                              <3>  extern serial_use_fifo, serial_use_intnum, serial_use_irqmask
    38                              <3>  extern serial_use_params, serial_var_baseport, serial_var_dl
    39                              <3>  extern serial_var_fifo, serial_var_intnum, serial_var_irqmask
    40                              <3>  extern serial_var_params, sscounter, stack, startoptions
    41                              <3>  extern table_length_keywords, throwsp, transfer_ext_cx
    42                              <3>  extern try_amis_multiplex_number, try_debugger_amis_multiplex_number
    43                              <3>  extern types, types.addresses_minus_end, types.end, u_addr
    44                              <3>  extern usertermcode, uu_default_length, uu_default_lines, vregs
    45                              <3>  extern vregs.amount, writing_access_variables
    46                              <3>  extern flagbits, regs
    47                              <3> 
    48                              <3> ; run.asm
    49                              <3>  extern ..@aa_access_end, ..@aa_access_start, ..@dd_access_end
    50                              <3>  extern ..@dd_access_start, ..@ee_access_end, ..@ee_access_start
    51                              <3>  extern ..@ee_interactive_access_end, ..@ee_interactive_access_start
    52                              <3>  extern ..@hh_indirection_memory_access_end
    53                              <3>  extern ..@hh_indirection_memory_access_start
    54                              <3>  extern ..@readmem_fault_skip_4_near_call, ..@rr_access_end
    55                              <3>  extern ..@rr_access_start, ..@rr_variable_read_access_end
    56                              <3>  extern ..@rr_variable_read_access_start
    57                              <3>  extern ..@rr_variable_write_access_end
    58                              <3>  extern ..@rr_variable_write_access_start, ..@sss_access_end
    59                              <3>  extern ..@sss_access_start, ..@uu_access_end, ..@uu_access_start
    60                              <3>  extern ..@uu_referenced_memory_access_end
    61                              <3>  extern ..@uu_referenced_memory_access_start, ..@uu_simulate_cmps_end
    62                              <3>  extern ..@uu_simulate_cmps_start, ..@uu_simulate_scas_end
    63                              <3>  extern ..@uu_simulate_scas_start, InDOS_or_BIOS_IO, PPLEN_ONLY_STRING
    64                              <3>  extern auxbuff_behind_last_silent
    65                              <3>  extern auxbuff_start_silent, bInDbg, b_bplist.bp, b_bplist.counter
    66                              <3>  extern b_bplist.disabled_mask, b_bplist.idbuffer, b_bplist.used_mask
    67                              <3>  extern b_bplist.when, bb_deferred_message_in_lineout_behind
    68                              <3>  extern bp_display_offset, calcpointbit, cmd2_reset_re, cmd_goto
    69                              <3>  extern debug22.cleartraceflag, decbyte, dmycmd, dumpregs_extended
    70                              <3>  extern enable_rh, entry_to_code_seg, entry_to_code_segsel, eqflag
    71                              <3>  extern eqladdr, exccsip, exception_csip, exception_stack, excloc
    72                              <3>  extern g_bplist.bp, g_bplist.used_count, get_set_id_offset_length
    73                              <3>  extern getc_if_any, getcseipbyte, getint2324, getpsp
    74                              <3>  extern gg_deferred_message, gg_first_cseip_linear
    75                              <3>  extern gg_next_cseip_linear, guard_auxbuff.1_or_2, idle, in_getinput
    76                              <3>  extern int19msg, internalflags6, intr8_counter, lastcmd, msg.again
    77                              <3>  extern msg.alreadytsr, msg.area_aa_access, msg.area_dd_access
    78                              <3>  extern msg.area_ee_access, msg.area_ee_interactive_access
    79                              <3>  extern msg.area_hh_indirection_memory_access, msg.area_rr_access
    80                              <3>  extern msg.area_rr_variable_read_access
    81                              <3>  extern msg.area_rr_variable_write_access, msg.area_run_access
    82                              <3>  extern msg.area_sss_access, msg.area_uu_access
    83                              <3>  extern msg.area_uu_referenced_memory_access
    84                              <3>  extern msg.area_uu_simulate_cmps, msg.area_uu_simulate_scas
    85                              <3>  extern msg.bb_hit.1, msg.bb_hit.2.counter, msg.bb_hitpass_id.after
    86                              <3>  extern msg.bb_hitpass_id.long, msg.bb_hitpass_id.short, msg.bb_pass.1
    87                              <3>  extern msg.cant_bp_linear, msg.cant_bp_linear.address1
    88                              <3>  extern msg.cant_bp_reason, msg.cant_bp_reason0, msg.cant_bp_reason1
    89                              <3>  extern msg.cant_bp_reason2, msg.cant_bp_reason3
    90                              <3>  extern msg.cant_bp_reason3.value, msg.cant_bp_reasonu
    91                              <3>  extern msg.cant_bp_restore, msg.cant_bp_restore.value
    92                              <3>  extern msg.cant_bp_the, msg.cant_bp_type_gg
    93                              <3>  extern msg.cant_bp_type_permanent, msg.cant_bp_type_permanent.index
    94                              <3>  extern msg.cant_bp_type_proceed, msg.cant_bp_write, msg.ctrlc
    95                              <3>  extern msg.empty_message, msg.goto, msg.invalidpsp, msg.list
    96                              <3>  extern msg.list_bp.address1, msg.list_bp.first, msg.list_bp.second
    97                              <3>  extern msg.list_bp.third, msg.list_bp.value, msg.list_bp_csip_16
    98                              <3>  extern msg.list_bp_none, msg.list_bp_not_cseip, msg.notyettsr
    99                              <3>  extern msg.nowattached, msg.nowtsr1, msg.nowtsr2, msg.psphooked
   100                              <3>  extern msg.pspnotfound, msg.remember, msg.selfownedpsp, msg.silent
   101                              <3>  extern msg.warnprefix, msg.while, msg.while_not_true
   102                              <3>  extern msg.while_terminated_after, msg.while_terminated_before
   103                              <3>  extern oldcols, oldcrtp, oldcsrpos, oldmr, options3
   104                              <3>  extern options6, pp_instruction, pp_operand, progexit, progtrm
   105                              <3>  extern rc, reg_eax, reg_es, reg_gs, reg_ss
   106                              <3>  extern run_int, run_sp, run_sp_reserve, savesp, setcseipbyte
   107                              <3>  extern setint2324, setpsp, setpspdbg
   108                              <3>  extern showstring, silence_dump, spadjust, swapscreen
   109                              <3>  extern tmode0, tmode1, tmodes, tmodev, tpg_possible_breakpoint
   110                              <3>  extern tpg_proceed_bp, tt_silent_mode_number, vpage, vrows
   111                              <3>  extern while_buffer, while_buffer.length, writemem
   112                              <3> 
   113                              <3>  extern ..@getcseipbyte_fault_skip_2_near_call
   114                              <3>  extern ..@setcseipbyte_fault_skip_2_near_call
   115                              <3>  extern ..@writemem_fault_skip_4_near_call_a
   116                              <3>  extern ..@writemem_fault_skip_4_near_call_b, int0Cmsg, int0Dmsg
   117                              <3>  extern int0msg, int18msg, int1msg, int3msg, int6msg
   118                              <3>  extern int8_kbd_msg, int8msg, runint_ctrlc_msg, serial_flags
   119                              <3> 
   120                              <3> ; bb.asm
   121                              <3>  extern ..@bb_id_length, ..@bb_id_start, ..@bb_saved_linear
   122                              <3>  extern ..@bb_when_length, ..@bb_when_start, b_bplist.id
   123                              <3>  extern b_bplist.idbuffer.free
   124                              <3>  extern b_bplist.whenbuffer, b_bplist.whenbuffer.free
   125                              <3>  extern bootcmd, crlf, msg.all, msg.at
   126                              <3>  extern msg.bb_no_new, msg.bb_when, msg.boot, msg.bp, msg.bpaddress
   127                              <3>  extern msg.bpcontent, msg.bpcounter, msg.bpdisabled, msg.bpenabled
   128                              <3>  extern msg.bpnone, msg.bpnone_at, msg.bpunused, msg.counter
   129                              <3>  extern msg.existing, msg.id, msg.new, msg.notbu, msg.number
   130                              <3>  extern msg.offset, msg.when, prnquit
   131                              <3> 
   132                              <3> ; rr.asm
   133                              <3>  extern InDOS_or_BIOS_output, cmdline_buffer
   134                              <3>  extern cmdline_buffer.end, cmdline_buffer.position, disflags, ee0a
   135                              <3>  extern error_expr, flagbits_for_40, flagbits_for_80, flagsoff
   136                              <3>  extern flagsoff_style2, flagsoff_style3, flagson, flagson_style23
   137                              <3>  extern get_memref_index_bx, getline00, getline_reset_notatty
   138                              <3>  extern guard_rc, hexnyb.common, hhtype, hhvar, in_re
   139                              <3>  extern mask_4byte, masks, memrefs, memrefs.free, msg.3byte
   140                              <3>  extern msg.abort, msg.append, msg.byte, msg.count, msg.dword
   141                              <3>  extern msg.highlight, msg.internal_error_no_mmx, msg.readonly
   142                              <3>  extern msg.readonly_mem, msg.regs386, msg.regs386_off, msg.regs386_on
   143                              <3>  extern msg.replace, msg.rh, msg.rv_mode.before, msg.rv_mode_r86m
   144                              <3>  extern msg.rv_mode_v86m, msg.rvd, msg.rvd_deviceheader
   145                              <3>  extern msg.rvd_not_device, msg.rvd_size, msg.rvm, msg.rvp
   146                              <3>  extern msg.rvp_application, msg.rvp_boot, msg.rvp_device
   147                              <3>  extern msg.rvp_device_attached, msg.rvp_tsr, msg.rvv
   148                              <3>  extern msg.unexpected_auxbuff_guard, msg.unhighlight, msg.vm_auxseg
   149                              <3>  extern msg.vm_codeseg, msg.vm_dataseg, msg.vm_entryseg, msg.vm_hisseg
   150                              <3>  extern msg.vm_messageseg, msg.vp_dparent, msg.vp_dpra
   151                              <3>  extern msg.vp_dpspsegment, msg.vp_parent, msg.vp_pra
   152                              <3>  extern msg.vp_pspsegment, msg.word, operatorfunctions, psp_parent
   153                              <3>  extern psp_pra, puts_break_line_more, putsline_break_line, re_buffer
   154                              <3>  extern re_buffer.end, re_buffer.position, re_sp, regs_prior
   155                              <3>  extern regs_prior.size, retn_expr, rh_count_number
   156                              <3>  extern rh_display_with_count, shortflagbits, shortflagbits.amount
   157                              <3>  extern shortflagsoff, shortflagson, silence_dump.rh
   158                              <3>  extern silence_dump.rh.all, table_getline_prepare_ldebug
   159                              <3>  extern table_getline_prepare_ms_debug, terminate_silent_dump
   160                              <3>  extern terminate_silent_dump.if_nonnull
   161                              <3> 
   162                              <3> ; rr.asm
   163                              <3>  extern flagbits_for_shl, regs_prior.size_w
   164                              <3> 
   165                              <3> ; aa.asm
   166                              <3>  extern REP_LEN, SEGP_LEN, attach
   167                              <3>  extern ext_aa_after_getline_handler, ext_aa_before_getline_handler
   168                              <3>  extern ext_aa_inject_handler, immasm_length, immasm_rel1632_target
   169                              <3>  extern immasm_rel8_target, msg.aa_internal_error, msg.attach
   170                              <3>  extern prefixlist.after_segment, replist, segprfxtab, showmach
   171                              <3>  extern skipalpha, sm1
   172                              <3> 
   173                              <3> ; uu.asm
   174                              <3>  extern A32P_LEN, GROUP7, MN_DB, MN_LOCK, MN_LOOP
   175                              <3>  extern MN_LOOPNZ, MN_LOOPZ, MN_REP, MN_REPE, MN_REPNE
   176                              <3>  extern MN_SEG, MN_WAIT, N_LOCK, N_LTABA, N_LTABO
   177                              <3>  extern N_WTAB, O32P_AMOUNT, OPTYPES_BASE, REP_DIFF_LEN, REP_SAME_LEN
   178                              <3>  extern SFPGROUP3, SGROUP4, SPARSE_BASE, a32prfxtab, dismach
   179                              <3>  extern dmflags, has_87, immasm_far_target, immasm_imm16, locktab
   180                              <3>  extern ltaba1, ltabo1, mach_87, mnlist, mnlist_a_suffix_allowed
   181                              <3>  extern mnlist_o_suffix_allowed, mnlist_o_suffix_required
   182                              <3>  extern msg.condjump, msg.condnotjump, msg.memrefs_invalid_internal
   183                              <3>  extern msg.uninstall, msg.uu_internal_error, msg.uu_too_many_repeat
   184                              <3>  extern needsmath, needsmath_L, needsmsg, needsmsg.digit_6_ofs
   185                              <3>  extern needsmsg.digit_x_ofs, needsmsg_L, o32prfxtab, obsmach
   186                              <3>  extern obsolete, obsolete_L, opindex, opinfo, oplists
   187                              <3>  extern optypes, ppbytes.string, ppbytes.string_amount, reg_ebp
   188                              <3>  extern reg_ebx, reg_ecx, reg_edi, reg_esi, reg_fs
   189                              <3>  extern regmem, rgnam16, rgnam816, segrgnam, sibbyte
   190                              <3>  extern sqztab, tab_to, uninstall, unused, wtab1
   191                              <3> 
   192                              <3> ; uu.asm
   193                              <3>  extern reg_edx
   194                              <3> 
   195                              <3> ; uu.asm
   196                              <3>  extern MN_BSWAP, MN_O32
   197                              <3> 
   198                              <3> ; uu.asm
   199                              <3>  extern MN_A32
   200                              <3> 
   201                              <3> ; amis.asm
   202                              <3>  extern amisintr_offset, deviceshim_size, ext_amis_handler
   203                              <3> 
   204                              <3> ; boot.asm
   205                              <3>  extern boot_remember_seek_handle
   206                              <3>  extern boot_remember_seek_offset, chkeol_or_then, cmd_goto.yy_entry
   207                              <3>  extern display_y_or_ext, ext_cmdline, ext_finish.boot
   208                              <3>  extern if_exists_found_open, if_exists_not_found
   209                              <3>  extern if_exists_then_address, iseol?_or_then, loadoptiontable
   210                              <3>  extern loadoptiontable.incompatible, loadsettings
   211                              <3>  extern msdos7_message_table, msdos7_message_table.size
   212                              <3>  extern msg.boot_access_error, msg.boot_and, msg.boot_auxbuff_crossing
   213                              <3>  extern msg.boot_badchain, msg.boot_badclusters, msg.boot_badfat
   214                              <3>  extern msg.boot_bpb_load_overlap, msg.boot_bpb_too_low
   215                              <3>  extern msg.boot_cannot_set_both, msg.boot_dot_crlf
   216                              <3>  extern msg.boot_file_not_found, msg.boot_file_too_big_error
   217                              <3>  extern msg.boot_file_too_small_error, msg.boot_internal_error
   218                              <3>  extern msg.boot_invalid_filename, msg.boot_invalid_heads
   219                              <3>  extern msg.boot_invalid_sectors, msg.boot_out_of_memory_error
   220                              <3>  extern msg.boot_partition_cycle_error, msg.boot_partition_not_found
   221                              <3>  extern msg.boot_quit_fail, msg.boot_sector_not_power
   222                              <3>  extern msg.boot_sector_too_large, msg.boot_sector_too_small
   223                              <3>  extern msg.boot_segment_too_low, msg.boot_too_many_partitions_error
   224                              <3>  extern msg.bootfail, msg.bootfail_check_mismatch
   225                              <3>  extern msg.bootfail_check_mismatch.check_got
   226                              <3>  extern msg.bootfail_check_mismatch.check_offset
   227                              <3>  extern msg.bootfail_check_mismatch.check_value, msg.bootfail_code
   228                              <3>  extern msg.bootfail_read, msg.bootfail_read_errorcode
   229                              <3>  extern msg.bootfail_secsizediffer, msg.bootfail_sig
   230                              <3>  extern msg.bootfail_sig_parttable, msg.bootfail_stack_underflow
   231                              <3>  extern msg.bpb, msg.checkoffset, msg.checkvalue, msg.dir
   232                              <3>  extern msg.dirinsteadsize, msg.emptydirname, msg.entry
   233                              <3>  extern msg.guard_auxbuff_error, msg.hidden, msg.hiddenadd
   234                              <3>  extern msg.maxpara, msg.minpara, msg.protocol, msg.quit, msg.read
   235                              <3>  extern msg.sector, msg.sector_alt, msg.segment, msg.write
   236                              <3>  extern msg.yy_empty, msg.yy_filename_empty, msg.yy_no_file
   237                              <3>  extern msg.yy_requires_filename, msg.yy_too_large
   238                              <3>  extern msg.yy_too_many_handles, terminator_in_line_in.offset
   239                              <3>  extern terminator_in_line_in.value, throwret
   240                              <3>  extern yy_boot_attempt_open_pathname, yy_boot_attempt_open_stack
   241                              <3>  extern yy_is_script
   242                              <3> 
   243                              <3> ; cc.asm
   244                              <3>  extern count_var, hh.single, msg.clear, msg.clear_sequence
   245                              <3>  extern msg.range, parsecm
   246                              <3> 
   247                              <3> ; dd.asm
   248                              <3>  extern auxbuff_current_size_minus_24, charcounter
   249                              <3>  extern dstringaddr, dstringtype, firstmcb, firstumcb, intaddress
   250                              <3>  extern lastint, lastint_is_86m_and_mcb, msg.di_empty, msg.di_error
   251                              <3>  extern msg.di_freedos_reloc, msg.di_hidden, msg.di_hma, msg.di_iisp
   252                              <3>  extern msg.di_jmpfar, msg.di_jmpfarindirect, msg.di_multiplex.1
   253                              <3>  extern msg.di_multiplex.2, msg.di_multiplex.3, msg.di_nonstd_iisp
   254                              <3>  extern msg.di_system_low, msg.di_system_mcb, msg.di_system_upper
   255                              <3>  extern msg.di_testhook, msg.di_toomany, msg.di_uninst_iisp
   256                              <3>  extern msg.header, msg.header.length, msg.invmcbadr, msg.prefixes
   257                              <3>  extern msg.tableheader, msg.tableheadertop, msg.top, msg.trailer
   258                              <3>  extern msg.trailer.length, smcbmsg_unknown, smcbtypes
   259                              <3> 
   260                              <3> ; debug.asm
   261                              <3>  extern UnhookInterruptForce, UnhookInterruptForceSim, aa
   262                              <3>  extern adusetup, bb, boot_ebdaflag, boot_initcode
   263                              <3>  extern boot_new_memsizekib, boot_old_memsizekib, cc, code_start, ddd
   264                              <3>  extern device_initcode, driveno, dumpregs_extended.exit, ee
   265                              <3>  extern eld_linkcall.call_cmd3, end_of_ldebug_code, entry_int3_retf
   266                              <3>  extern errcarat, ff, get_86m_interrupt_handler_no_dos, get_columns
   267                              <3>  extern getline_close_file, getline_close_file.resetstuff, gg, hh
   268                              <3>  extern hh_depth, hh_depth_of_single_term, hhflag, ia_restore, ii
   269                              <3>  extern immasm, install_86m_interrupt_handler, int22, int2D, intr0
   270                              <3>  extern intr0C, intr0D, intr1, intr18, intr19
   271                              <3>  extern intr3, intr6, intr8, linkinfo, ll
   272                              <3>  extern ll3, ll_copy_cmdline_and_fcbs
   273                              <3>  extern ll_copy_cmdline_and_fcbs.have_cx
   274                              <3>  extern mm, msg.NULblank, msg.asmoptions_1, msg.boothelp
   275                              <3>  extern msg.build_array, msg.build_long_amount, msg.build_short_amount
   276                              <3>  extern msg.build_version_amount, msg.cannot_hook_2D.invalid
   277                              <3>  extern msg.cannot_hook_2D.nofree, msg.cannotbootquit_memsizes
   278                              <3>  extern msg.condhelp, msg.ensure_no_memory, msg.expressionhelp
   279                              <3>  extern msg.flaghelp, msg.flags_1, msg.guard_rc_error
   280                              <3>  extern msg.guard_re_error, msg.help_array, msg.help_array_amount
   281                              <3>  extern msg.help_re, msg.help_run, msg.help_source, msg.keep
   282                              <3>  extern msg.license, msg.line_out_overflow, msg.n_toolongname
   283                              <3>  extern msg.n_toolongtail, msg.nobootsupp, msg.options_array
   284                              <3>  extern msg.options_array_amount, msg.options_pages, msg.options_scan
   285                              <3>  extern msg.options_scan_amount, msg.qq_a_terminated
   286                              <3>  extern msg.qq_a_unterminated, msg.qq_device_no_c, msg.qq_device_no_d
   287                              <3>  extern msg.qq_device_none_selected, msg.qq_unterm
   288                              <3>  extern msg.rc_limit_reached, msg.re, msg.re_limit_reached
   289                              <3>  extern msg.reghelp, msg.rh_disabled, msg.rh_enabled, msg.run
   290                              <3>  extern msg.serial_cannot_hook, msg.serial_cannot_hook.new_int
   291                              <3>  extern msg.serial_cannot_hook.old_int, msg.serial_cannot_unhook
   292                              <3>  extern msg.serial_cannot_unhook.int, msg.serial_cannot_unhook.nowarn
   293                              <3>  extern msg.serial_late_unhook, msg.serial_late_unhook.int
   294                              <3>  extern msg.serial_no_keep_enter, msg.serial_no_keep_timer
   295                              <3>  extern msg.serial_request_keep, msg.source, msg.string_build
   296                              <3>  extern msg.string_options, msg.string_version
   297                              <3>  extern msg.tsr_cannot_terminate_attached, msg.varhelp, oo, ph_msg, pp
   298                              <3>  extern putrunint, putsz_exthelp, rr, run, section.DEVICESHIM.vstart
   299                              <3>  extern serial_clean_up, serial_clear_fifos, serial_eoi
   300                              <3>  extern serial_init_UART, serial_install_interrupt_handler
   301                              <3>  extern serial_interrupt_handler, serial_uninstall_interrupt_handler
   302                              <3>  extern set_irq, setscreen, sleep_delta_limit, sleep_highest_delta
   303                              <3>  extern sss, tpg_initialise_empty_auxbuff.reset
   304                              <3>  extern transfer_to_ext_puts_getline, tt, update_inttab_optional, uu
   305                              <3>  extern vv, vv_disable, vv_set, ww, yy
   306                              <3> 
   307                              <3> ; debug.asm
   308                              <3>  extern eld_linkcall
   309                              <3> 
   310                              <3> ; ee.asm
   311                              <3>  extern bufend, bufnext, fillbuf, fullbsout
   312                              <3>  extern getline_is_input_file?, line_in, linecounter, load_extension
   313                              <3>  extern msg.ext, notatty, prehak1, run2324
   314                              <3> 
   315                              <3> ; hh.asm
   316                              <3>  extern hh_div_active, hh_div_dividend, hh_div_divisor
   317                              <3>  extern msg.base, msg.group, msg.hh_div_remainder, msg.width
   318                              <3> 
   319                              <3> ; iioo.asm
   320                              <3>  extern if_exists_length, if_exists_si, if_exists_sp
   321                              <3>  extern install, msg.exists, msg.install, msg.not, msg.then
   322                              <3>  extern msg.y, resetrc, yy_or_ext_no_guard_re
   323                              <3> 
   324                              <3> ; immasm.asm
   325                              <3>  extern aa_ret, addrr, condmsg, error_mirror, index
   326                              <3>  extern msg.immasm_error_eip, presizeflags, reg32addr, segmnt
   327                              <3>  extern segrgaddr
   328                              <3> 
   329                              <3> ; msg.asm
   330                              <3>  extern ..@boot_scan_dir_return_fat16_root_entry
   331                              <3>  extern ..@boot_scan_dir_return_filenotfound
   332                              <3>  extern ..@boot_scan_dir_return_subdir_or_fat32_entry
   333                              <3>  extern alloc_size_not_reserved, asciitablenames, boot_init_foundname
   334                              <3>  extern configpath, configpath.dir_end, device_quittable_regs, dpmi32
   335                              <3>  extern execblk.cmdline, ext_command_handler, ext_finish.bp_is_set
   336                              <3>  extern ext_handle, ext_inject_handler, ext_preprocess_handler
   337                              <3>  extern ext_puts_copyoutput_handler, ext_puts_getline_handler
   338                              <3>  extern ext_puts_handler, ext_var, ext_var_amount, ext_var_format
   339                              <3>  extern ext_var_size, extcssel, extdssel, handle_scan_dir_entry
   340                              <3>  extern handle_scan_dir_not_found, history.first, history.last
   341                              <3>  extern indirect_array_errfix, init_executable_pathname
   342                              <3>  extern init_executable_pathname.end, internalflags4, internalflags5
   343                              <3>  extern internalflags7, isvariable_morebyte_nameheaders.ext
   344                              <3>  extern lastcmd_transfer_ext_address, lastcmd_transfer_ext_entry
   345                              <3>  extern line_in.end, linkcall_table, load_adr_dirbuf_segment
   346                              <3>  extern load_check_dir_attr, load_data_lowest, load_kernel_name
   347                              <3>  extern load_yy_direntry, load_yyname_input, load_yyname_next
   348                              <3>  extern near_transfer_ext_address, near_transfer_ext_entry
   349                              <3>  extern next_reserved_segment, options4, options5, options7
   350                              <3>  extern patcharea_intrtn, patcharea_intrtn.segment
   351                              <3>  extern patcharea_intrtn.size, patcharea_run, patcharea_run.segment
   352                              <3>  extern patcharea_run.size, pm_2_86m_0, promptlen, reserved_address
   353                              <3>  extern scriptspath, scriptspath.dir_end
   354                              <3>  extern sss_silent_count, sss_silent_count_used, stack_end, swch1
   355                              <3>  extern while_buffer.end
   356                              <3> 
   357                              <3> ; msg.asm
   358                              <3>  extern install_trying
   359                              <3> 
   360                              <3> ; init.asm
   361                              <3>  extern ..@init_behind, ..@init_first
   362                              <3>  extern ..@patch_no386_ds_6_DATA_ENTRY
   363                              <3>  extern ..@patch_no386_ds_code_or_entry
   364                              <3>  extern ..@patch_no386_iret_code_or_entry, behind_code_truncated
   365                              <3>  extern behind_init, behind_messagesegment_nobits
   366                              <3>  extern behind_messagesegment_nobits_truncated, debug22
   367                              <3>  extern device_header.next, devint23, devint24, entry_retf
   368                              <3>  extern execblk.fcb1, execblk.fcb2, ext_data_area, extcall_table.ret
   369                              <3>  extern extcall_table.segsel, fileext, hVdd, immasm_buffer, initcont
   370                              <3>  extern initcont.boot_entry, initcont.device, inttab, inttab.i06
   371                              <3>  extern inttab.i2D, inttab_number_variable, line_out_overflow
   372                              <3>  extern linkcall_table.code1, linkcall_table.entry
   373                              <3>  extern linkcall_table.init, oldmode, pInDOS, pSDA, regs.size
   374                              <3>  extern switchar, trim_overflow, var_addr_entries
   375                              <3>  extern var_addr_entries.amount
   376                              <3> 
   377                              <3> ; install.asm
   378                              <3>  extern installflags, msg.alreadydisabled
   379                              <3>  extern msg.alreadyenabled, msg.toggle, msg.trydisable, msg.tryenable
   380                              <3> 
   381                              <3> ; ints.asm
   382                              <3>  extern debuggeramissig, inttab_optional
   383                              <3> 
   384                              <3> ; lineio.asm
   385                              <3>  extern auxbuff_amount_silent, cmd3_set_options
   386                              <3>  extern determine_quiet_output, eldheader, getc_repeat_idle
   387                              <3>  extern getline_timer_func, handle_ctrl_c, if_exists_found_closed
   388                              <3>  extern if_exists_found_ext_open, indos_remember_seek_function
   389                              <3>  extern indos_remember_seek_handle, indos_remember_seek_offset
   390                              <3>  extern input_file_handles.to_close, msg.configkeyword
   391                              <3>  extern msg.eld_error_code, msg.eld_load_error, msg.emptykeyword
   392                              <3>  extern msg.eof, msg.executablekeyword, msg.ext_error_internal
   393                              <3>  extern msg.ext_error_invalid, msg.ext_error_io, msg.ext_error_oom
   394                              <3>  extern msg.freedos_ctrlc_workaround, msg.goto_empty
   395                              <3>  extern msg.goto_not_file, msg.goto_not_found.1, msg.goto_not_found.2
   396                              <3>  extern msg.history_internal_error, msg.more, msg.more_over
   397                              <3>  extern msg.more_over_size, msg.more_size, msg.rh_step.1
   398                              <3>  extern msg.rh_step.2, msg.scriptskeyword, msg.silent_error, msg.sof
   399                              <3>  extern msg.unexpected_noneol_rc, msg.unexpected_noneol_re
   400                              <3>  extern msg.yy_error_file_open, msg.yy_filename_missing_unquote
   401                              <3>  extern msg.yy_no_dos, qq, section.DATASTACK.vstart
   402                              <3>  extern serial_check_receive_char, serial_receive_char
   403                              <3>  extern serial_send_char, skip_rh, yy_boot
   404                              <3>  extern yy_boot_clear_remember_seek, yy_boot_close_file, yy_boot_read
   405                              <3>  extern yy_boot_remember_seek, yy_boot_seek_current
   406                              <3>  extern yy_boot_seek_start, yy_try_scriptspath
   407                              <3>  extern yy_try_scriptspath.didnotyettry
   408                              <3>  extern yy_try_scriptspath.nokeywordused
   409                              <3> 
   410                              <3> ; ll.asm
   411                              <3>  extern doserr8, ensuredebuggeeloaded, execblk, execblk.csip
   412                              <3>  extern execblk.sssp, msg.hexerror, msg.ll_unterm, msg.not_while_indos
   413                              <3>  extern msg.tsr_cannot_ll, parselw, reading
   414                              <3>  extern terminate_attached_process, ww1, ww15, zeroregs
   415                              <3> 
   416                              <3> ; mm.asm
   417                              <3>  extern has_287, has_copr, msg.c0, msg.cr, msg8088
   418                              <3>  extern msgx86, no_copr, parsecm_have_address
   419                              <3> 
   420                              <3> ; serialp.asm
   421                              <3>  extern baseport, msg.no_progress, rxfifo, rxhead
   422                              <3>  extern rxtail, serial_fcr_setting, serial_installed_intnum
   423                              <3>  extern serial_save_dl, serial_save_ier, serial_save_irq_mask
   424                              <3>  extern serial_save_irq_off, serial_save_lcr, serial_save_mcr, txfifo
   425                              <3>  extern txhead, txtail
   426                              <3> 
   427                              <3> ; ss.asm
   428                              <3>  extern msg.matches, msg.reverse, msg.seconds, msg.sleep
   429                              <3>  extern msg.ticks, sleep_repeat_idle
   430                              <3> 
   431                              <3> ; vv.asm
   432                              <3>  extern csrpos, msg.nokeep, msg.off, msg.on, msg.vv_disabled
   433                              <3>  extern msg.vv_enable_failure, xmsdrv, xmsmove
   434                              <3> 
   435                              <3> ; ww.asm
   436                              <3>  extern diskful, doserr11, doserr2, doserr3, doserr5
   437                              <3>  extern drive, drivenumber, dskerrs, not_while_indos, nowhexe
   438                              <3>  extern nownull, openerr, openerr1, writing, wwmsg1
   439                              <3>  extern wwmsg2
   440                              <3> 
   441                              <3> 
   442                              <3>  extern bCSAttr, lDEBUG_CODE_to_lDEBUG_CODE2_nearcall_helper
   443                              <3> 
   444                              <3>  extern hook2F.not_in_dos
   445                              <3> 
   446                              <3>  extern cmd4.int3, lDEBUG_CODE2_dualret_helper
   447                              <3>  extern lDEBUG_CODE2_to_lDEBUG_CODE_nearcall_helper
   448                              <3>  extern lDEBUG_CODE_to_lDEBUG_CODE2_dualcall_helper, msg.bu
   449                              <3>  extern msg.bu_relocated, msg.bu_relocated.sign
   450                              <3> 
   451                              <3>  extern nopmsupp
   452                              <3> 
   453                              <3>  extern bAddr32
   454                              <3> 
   455                              <3>  extern descriptor, descriptor.attrib, descriptor.base
   456                              <3>  extern descriptor.limit, gatewrong, msg.d.a_error, msg.d.a_error_code
   457                              <3>  extern msg.d.a_success, msg.d.a_success_sel, msg.d.b_error
   458                              <3>  extern msg.d.b_error_code, msg.d.b_success, msg.d.d_error
   459                              <3>  extern msg.d.d_error_code, msg.d.d_success, msg.d.l_error
   460                              <3>  extern msg.d.l_error_code, msg.d.l_success, msg.d.t_error
   461                              <3>  extern msg.d.t_error_code, msg.d.t_success, msg.deschelp, msg.ofs32
   462                              <3>  extern nodesc
   463                              <3> 
   464                              <3>  extern ..@patch_tsr_quit_run, areastruc_entry.qq_entry, cssel
   465                              <3>  extern ddebugareas.next, debug2F, dpmidisable, dpmientry, dpmihook
   466                              <3>  extern dpmihookamis, dpmihookcs, dpmiwatch, end_of_ldebug_code2
   467                              <3>  extern findinstalleddebugger, get_messagesegsel, handle_mode_changed
   468                              <3>  extern i23pm, msg.cannotpmquit, msg.desc, msg.dpmi_no_hook, msg.msdos
   469                              <3>  extern msg.qq_device_pm, msg.qq_still_pm, msg.qqlate_areas_error
   470                              <3>  extern msg.readonly_verifysegm, msg.readonly_verifysegm.selector
   471                              <3>  extern mydpmientry, nodosext, oldi2F, pm_reset_handlers, scratchsel
   472                              <3>  extern sr_state, switchmode, uninstall_areas.qq_entry
   473                              <3> 
   474                              <3>  extern i24pm
   475                              <3> 
   476                              <3>  extern auxbuff_switchbuffer_size, code2_seg, code2_sel, code2_size
   477                              <3>  extern code_sel, daresult, dssel, immsel
   478                              <3>  extern lDEBUG_CODE2_to_lDEBUG_CODE_dualcall_helper
   479                              <3>  extern lDEBUG_CODE_dualret_helper, messagesel, msg.desctype
   480                              <3>  extern msg.stack_overflow.desctype
   481                              <3> 
   482                              <3>  extern cmd3_mirror
   483                              <3> 
   484                              <3>  extern ..@patch_entry_seg, ..@patch_no386_ds_4, ..@patch_no386_ds_5
   485                              <3>  extern ..@patch_no386_ds_entry_pmint21_1
   486                              <3>  extern ..@patch_no386_ds_entry_pmint21_2, areas_fun, areas_sub
   487                              <3>  extern ddebugareas.prev, linkcall_table.code2
   488                              <3> 
   489                              <3>  extern areas_struc, msg.areasalreadyinstalled
   490                              <3>  extern msg.areasalreadyuninstalled, msg.areasinstalled
   491                              <3>  extern msg.areasnodebuggerfound, msg.areasnotinstalled
   492                              <3>  extern msg.areasnotinstalled.code, msg.areasnotsupported
   493                              <3>  extern msg.areasuninstalled, msg.areasuninstalled.code
   494                              <3> 
   495                              <3>  extern intcall_return_parameter_es_parameter_ds
   496                              <3>  extern lDEBUG_CODE_to_lDEBUG_CODE_dualcall_helper, pop_if, push_if
   497                              <3> 
   498                              <3>  extern isextenderavailable, msg.cannotpmload, nodosextinst
   499                              <3> 
   500                              <3>  extern install_areas, patcharea_pm_exc, patcharea_pm_exc.segment
   501                              <3>  extern patcharea_pm_exc.size
   502                              <3> 
   503                              <3>  extern pmint21
   504                              <3> 
   505                              <3>  extern debuggerexception, entry_to_code_sel, exc6msg, excCmsg
   506                              <3>  extern excDmsg, excEmsg, intrtn2_entry, pmintsave.int21
   507                              <3> 
   508                              <3>  extern convsegs, convsegs.amount_fixed, convsegs.end_fixed
   509                              <3>  extern dpmi_pm2rm, dpmi_pmsav, dpmi_rm2pm, dpmi_rmsav, endexctab
   510                              <3>  extern exc_first, exc_second, excsave, exctab, installdpmimsg
   511                              <3>  extern intrtn_entry.from_installdpmi, pmintsave, pminttab
   512                              <3>  extern pminttab.end, setrmaddr, silence_delete_one_string.internal
   513                              <3> 
   514                              <3>  extern msg.rv_mode_dpmi_16, msg.rv_mode_dpmi_32, msg.vm_code2seg
   515                              <3>  extern msg.vm_selector, msg.vp_dpspsel, msg.vp_pspsel, psp_selector
   516                              <3> 
   517                              <3>  extern ..@getcseipbyte_fault_skip_6_near_call
   518                              <3>  extern ..@hh_code1_indirection_memory_access_end
   519                              <3>  extern ..@hh_code1_indirection_memory_access_start
   520                              <3>  extern ..@readmem_fault_skip_2_near_call
   521                              <3>  extern ..@setcseipbyte_fault_skip_6_near_call
   522                              <3>  extern ..@writemem_fault_skip_2_near_call_a
   523                              <3>  extern ..@writemem_fault_skip_2_near_call_b, behind_code
   524                              <3>  extern behind_code2, convsegs.amount, ddebugareas
   525                              <3>  extern getline_extra_int22.cleartraceflag, msg.list_bp_cseip_32
   526                              <3> 
   527                              <3>  extern MN_O16
   528                              <3> 
   529                              <3>  extern MN_A16
   530                              <3> 
   531                              <3>  extern relocatedzero
   532                              <3> 
   533                              <3>  extern msg.bu_disabled
   534                              <3> 
   535                              <3>  extern reset_interrupts, set_interrupts
   536                              <3> 
   537                              <3>  extern startoptions6
   538                              <3> 
   539                              <3>  extern currentposition, msg.loader_bottom_not_allowed
   540                              <3>  extern msg.loader_too_low_load
   541                              <3> 
   542                              <3>  extern intr_loader_18, intr_loader_19, moveloader_hook_ints
   543                              <3> 
   544                              <3>  extern loader_query, loader_transfer_cmd3, loader_transfer_relocate
   545                              <3> 
   546                              <3>  extern cmd3_int_disable.set_bx_to_dx, cmd3_int_enable.set_bx_to_dx
   547                              <3>  extern ldebug_code_size, movesegrefstable, movetable
   548                              <3>  extern movetable.bottom, msg.isalready, msg.isnow, msg.loader_error
   549                              <3>  extern msg.move, msg.move_auxbuff_error, msg.move_auxdown
   550                              <3>  extern msg.move_auxup, msg.move_ebdanottop, msg.move_empty
   551                              <3>  extern msg.move_int_error, msg.move_int_panic
   552                              <3>  extern msg.move_must_be_bottom, msg.move_nottop, msg.move_oom
   553                              <3>  extern msg.move_rpl, msg.move_toolargeebda, msg.unsupportedmove
   554                              <3>  extern qq_int_unhook_sim.set_bx_to_dx
   555                              <3> 
   556                              <3>  extern moveloader.already, moveloader.bottom_to_hidden
   557                              <3>  extern moveloader.bottom_to_top, moveloader.hidden_to_bottom
   558                              <3>  extern moveloader.hidden_to_top, moveloader.top_to_bottom
   559                              <3>  extern moveloader.top_to_hidden
   560                              <3> 
   561                              <3>  extern moveloader.specificerror, moveloader_check_serial, msg.godebug
   562                              <3>  extern msg.loader_extra, msg.loader_flag, msg.loader_loadseg_low
   563                              <3>  extern msg.loader_must_be_hidden, msg.loader_sign, msg.loader_stack
   564                              <3>  extern msg.loadsupportsignature, msg.loadsupportsignature.size
   565                              <3> 
   566                              <3>  extern depack, hshrink_memory_source.offset
   567                              <3>  extern hshrink_memory_source.segment, indirect_hshrink_message_buffer
   568                              <3>  extern msg.hshrink_error, nontruncated_hshrink_message_buffer
   569                              <3> 
   570                              <3>  extern truncated_hshrink_message_buffer
   571                              <3> 
   572                              <3>  extern patch_boothelp_uncompressed
   573                              <3> 
   574                              <3>  extern msg.copybpb
   295                              <2> %endif
   710                              <1> %endif
   711                              <1> [list -]
   714                              <1> 
   715                              <1> %include "eld.mac"
     1                              <2> %if 0
     2                              <2> 
     3                              <2> Extensions for lDebug macros
     4                              <2> 
     5                              <2> Copyright (C) 2008-2025 E. C. Masloch
     6                              <2> 
     7                              <2> Usage of the works is permitted provided that this
     8                              <2> instrument is retained with the works, so that any entity
     9                              <2> that uses the works is notified of this instrument.
    10                              <2> 
    11                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <2> 
    13                              <2> %endif
    14                              <2> 
    15                              <2> %ifndef ELD_MAC
    16                              <2> %define ELD_MAC 1
    17                              <2> 
    18                              <2> %include "lmacros3.mac"
     1                              <3> [list -]
    19                              <2> 
    20                              <2> 		; ELD executable header
    21                              <2> 	struc ELD_HEADER
    22 00000000 ????????            <2> eldhSignature:		resb 4	; "ELD1"
    23 00000004 ??????              <2> 			resb 3	; reserved
    24 00000007 ??                  <2> 			resb 1	; 26 (Ctrl-Z)
    25 00000008 ????????            <2> eldhCodeOffset:		resd 1	; position displacement from eldhSignature
    26 0000000C ????                <2> eldhCodeImageLength:	resw 1	; amount bytes, at least 32
    27 0000000E ????                <2> eldhCodeAllocLength:	resw 1	; amount bytes, added to prior. sum < 64 KiB
    28 00000010 ????????            <2> eldhDataOffset:		resd 1
    29 00000014 ????                <2> eldhDataImageLength:	resw 1	; (zero allowed)
    30 00000016 ????                <2> eldhDataAllocLength:	resw 1	; (zero allowed)
    31 00000018 ????                <2> eldhCodeEntrypoint:	resw 1	; within code section, used as displacement
    32 0000001A ????????            <2> eldhReserved:		resb 4	; reserved
    33 0000001E ????                <2> eldhExtensionSize:	resw 1	; from eldhSignature, -> past eldhx fields in use
    34                              <2> 	endstruc
    35                              <2> 	endarea ELD_HEADER, 1
    36                              <2> 
    37                              <2> 	struc ELD_HEADERX
    38 00000000 <res 20h>           <2> eldhxHeader:		resb ELD_HEADER_size
    39 00000020 ????????            <2> eldhxDescriptionOffset:	resd 1	; zero if none, from eldhxHeader. <= 128 Bytes
    40 00000024 ????????            <2> eldhxHelpOffset:	resd 1	; zero if none, from eldhxHeader
    41 00000028 ????????            <2> eldhxLibTable:		resd 1	; zero if none, from eldhxHeader
    42 0000002C ????????            <2> eldhxDateTimeOffset:	resd 1	; zero if none, from eldhxHeader
    43                              <2> 	alignb 16
    44                              <2> 	endstruc
    45                              <2> 
    46                              <2> 	struc ELD_TRAILER_HEADER
    47 00000000 ????????????????    <2> eldthSignature:		resb 8	; "ELD1TAIL"
    48 00000008 ????????            <2> eldthHeaderOffset:	resd 1	; negative displacement from eldthSignature,
    49                              <2> 				;  add this dword to the seek offset
    50 0000000C ????                <2> eldthReserved:		resw 1	; reserved, must be initialised to zero
    51 0000000E ????                <2> eldthChecksum:		resw 1	; sum of all words in trailer header = 0
    52                              <2> 	endstruc
    53                              <2> 	endarea ELD_TRAILER_HEADER, 1
    54                              <2> 
    55                              <2> 	struc ELD_LIBTABLE
    56 00000000 ????                <2> eldltFormat:		resw 1
    57                              <2> 	; 0 = uncompressed
    58                              <2> 	; 2 = heatshrink compressed
    59                              <2> 	; 3 = lzexedat -4 compressed
    60                              <2> 	; 4 = lzexedat -4 -l compressed
    61 00000002 ????                <2> eldltAmount:		resw 1
    62 00000004 ????????            <2> eldltOffset:		resd 1	; from eldhxHeader
    63                              <2> eldltCompressedLength:		; (dword, only present if format 2, 3, or 4)
    64                              <2> 	endstruc
    65                              <2> 	endarea ELD_LIBTABLE, 1
    66                              <2> 
    67                              <2> 		; ELD instance header
    68                              <2> 	struc ELD_INSTANCE
    69 00000000 ????                <2> eldiStartCode:		resw 1	; -> this structure itself (para aligned)
    70 00000002 ????                <2> eldiEndCode:		resw 1	; -> behind memory used by instance (para aligned)
    71 00000004 ????                <2> eldiStartData:		resw 1	; -> data in data entry section (para aligned), or 0
    72 00000006 ????                <2> eldiEndData:		resw 1	; -> behind data (para aligned), or 0
    73 00000008 ????????????????    <2> eldiIdentifier:		resb 8	; blank-filled text
    74 00000010 ????                <2> eldiFlags:		resw 1	; flags
    75                              <2> eldiListing_size equ 14
    76 00000012 <res Eh>            <2> eldiListing:		resb eldiListing_size
    77                              <2> 				; ASCIZ listing file name
    78                              <2> 	endstruc
    79                              <2> 		; flags for eldiFlags:
    80                              <2> eldifResident:		equ 1
    81                              <2> 
    82                              <2> 		; ELD link info header
    83                              <2> 	struc ELD_LINKINFO
    84 00000000 ????                <2> eldlSignature:		resw 1	; 0E1D1h
    85 00000002 ????????            <2> eldlReserved:		resw 2
    86 00000006 ????                <2> eldlUseLinkHash:	resw 1
    87 00000008 ????                <2> eldlDataAmount:		resw 1
    88 0000000A ????                <2> eldlDataPrefixes:	resw 1
    89 0000000C ????                <2> eldlDataEntries:	resw 1
    90 0000000E ????                <2> eldlDataAddresses:	resw 1
    91 00000010 ????                <2> eldlCodeAmount:		resw 1
    92 00000012 ????                <2> eldlCodePrefixes:	resw 1
    93 00000014 ????                <2> eldlCodeEntries:	resw 1
    94 00000016 ????                <2> eldlCodeAddresses:	resw 1
    95                              <2> 	endstruc
    96                              <2> 
    97                              <2> 	numdef ELD_CODE_VSTART, 9001h
    98                              <2> 	numdef ELD_DATA_VSTART, 8000h
    99                              <2> 	numdef ELD_RELOC_VSTART, 8000h
   100                              <2> 
   101                              <2> 	numdef ELD_RECLAIM_HINT, 0
   102                              <2> 	strdef ELD_LISTING, ""
   103                              <2> 	numdef ELD_DATETIME, 0
   104                              <2> 
   105                              <2> %if _ELD_DATETIME
   106                              <2>  %define PUT_ELDHX_DATETIME_OFFSET at eldhxDateTimeOffset, dd DATAOFFSET + datetime - datastart
   107                              <2>  %macro PUT_ELD_DATETIME 0.nolist
   108                              <2> datetime:	asciz __UTC_DATE__,'T',__UTC_TIME__,'Z'
   109                              <2> 		asciz		; for future extension
   110                              <2>  %endmacro
   111                              <2> %else
   112                              <2>  %define PUT_ELDHX_DATETIME_OFFSET
   113                              <2>  %define PUT_ELD_DATETIME
   114                              <2> %endif
   115                              <2> 
   116                              <2> %endif
   716                              <1> 
   717                              <1> %include "install.mac"
     1                              <2> 
     2                              <2> %if 0
     3                              <2> 
     4                              <2> lDebug INSTALL command macros
     5                              <2> 
     6                              <2> Copyright (C) 2008-2023 E. C. Masloch
     7                              <2> 
     8                              <2> Usage of the works is permitted provided that this
     9                              <2> instrument is retained with the works, so that any entity
    10                              <2> that uses the works is notified of this instrument.
    11                              <2> 
    12                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    13                              <2> 
    14                              <2> %endif
    15                              <2> 
    16                              <2> 	struc INSTALLFLAG
    17 00000000 ????                <2> ifKeyword:	resw 1
    18 00000002 ????                <2> ifDescription:	resw 1
    19 00000004 ????                <2> ifOptions:	resw 1
    20 00000006 ????                <2> ifValue:	resw 1
    21 00000008 ????                <2> ifTrying:	resw 1
    22 0000000A ????                <2> ifReserved:	resw 1
    23                              <2> 	endstruc
    24                              <2> 
   718                              <1> 
   719                              <1> %if _SYMBOLIC
   720                              <1> 	defaulting 0			; disable defaulting
   721                              <1> %include "symbols.mac"
   722                              <1> [list -]
   723                              <1> 		; symbolic branch defines *without* defaulting!
   724                              <1> 	numdef ZZ_INSERT_TEMP, 1
   725                              <1> 	numdef XMS_SYMBOL_TABLE, 1
   726                              <1> 	numdef BUFFER_86MM_SLICE, 0
   727                              <1> 	numdef SECOND_SLICE, 0
   728                              <1> 
   729                              <1> 	defaulting 1			; re-enable defaulting
   730                              <1> 
   731                              <1> 		; symbolic branch defines
   732                              <1> 	numdef 86MM_SYMBOL_TABLE_MAX, 256, 256
   733                              <1> %endif
   734                              <1> 
   735                              <1> 	struc SEGADR
   736 00000000 ????????            <1> saOffset:	resd 1
   737 00000004 ????                <1> saSegSel:	resw 1
   738                              <1> %if _PM
   739 00000006 ????                <1> saSegment:	resw 1
   740 00000008 ????                <1> saSelector:	resw 1
   741                              <1> %endif
   742                              <1> 	endstruc
   743                              <1> 
   744                              <1> 	%macro segmentedaddress 0.nolist
   745                              <1> 	istruc SEGADR
   746                              <1> 	iend
   747                              <1> 	%endmacro
   748                              <1> 
   749                              <1> 	struc SEGOFS16ADR
   750 00000000 ????                <1> so16aOffset:	resw 1
   751 00000002 ????                <1> so16aSegSel:	resw 1
   752                              <1> %if _PM
   753 00000004 ????                <1> so16aSegment:	resw 1
   754 00000006 ????                <1> so16aSelector:	resw 1
   755                              <1> %endif
   756                              <1> 	endstruc
   757                              <1> 
   758                              <1> 	%macro segofs16address 0-1.nolist zero
   759                              <1> 	istruc SEGOFS16ADR
   760                              <1> %ifidni %1,zero
   761                              <1> %elifidni %1,minusone
   762                              <1> at so16aOffset,		dw -1
   763                              <1> at so16aSegSel,		dw -1
   764                              <1>  %if _PM
   765                              <1> at so16aSegment,	dw -1
   766                              <1> at so16aSelector,	dw -1
   767                              <1>  %endif
   768                              <1> %else
   769                              <1>  %error Unexpected initialiser keyword
   770                              <1> %endif
   771                              <1> 	iend
   772                              <1> 	%endmacro
   773                              <1> 
   774                              <1> 	struc SEGONLYADR
   775 00000000 ????                <1> soaSegSel:	resw 1
   776                              <1> %if _PM
   777 00000002 ????                <1> soaSegment:	resw 1
   778 00000004 ????                <1> soaSelector:	resw 1
   779                              <1> %endif
   780                              <1> 	endstruc
   781                              <1> 
   782                              <1> 	%macro segonlyaddress 0.nolist
   783                              <1> 	istruc SEGONLYADR
   784                              <1> 	iend
   785                              <1> 	%endmacro
   786                              <1> 
   787                              <1> 
   788                              <1> %if _LOADER
   789                              <1> 	struc MOVETABLEENTRY
   790                              <1> mteIdentifier:		resw 1
   791                              <1> mteArrayIndex:		resw 1
   792                              <1> mteStatusMessage:	resw 1
   793                              <1> mteFromArray:
   794                              <1> mteFromBottom:		resw 1
   795                              <1> mteFromTop:		resw 1
   796                              <1> mteFromHidden:		resw 1
   797                              <1> 	endstruc
   798                              <1> %endif
   799                              <1> 
   800                              <1> %if _BOOTLDR
   801                              <1>  %include "iniload.mac"
     1                              <2> %if 0
     2                              <2> 
     3                              <2> lDebug iniload/boot interfacing structs and macros
     4                              <2> 
     5                              <2> Copyright (C) 2008-2025 E. C. Masloch
     6                              <2> 
     7                              <2> Usage of the works is permitted provided that this
     8                              <2> instrument is retained with the works, so that any entity
     9                              <2> that uses the works is notified of this instrument.
    10                              <2> 
    11                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <2> 
    13                              <2> %endif
    14                              <2> 
    15                              <2> 
    16                              <2> 	struc BS
    17 00000000 ??????              <2> bsJump:	resb 3
    18 00000003 ????????????????    <2> bsOEM:	resb 8
    19                              <2> bsBPB:
    20                              <2> 	endstruc
    21                              <2> 
    22                              <2> 	struc EBPB		;        BPB sec
    23 00000000 ????                <2> bpbBytesPerSector:	resw 1	; offset 00h 0Bh
    24 00000002 ??                  <2> bpbSectorsPerCluster:	resb 1	; offset 02h 0Dh
    25 00000003 ????                <2> bpbReservedSectors:	resw 1	; offset 03h 0Eh
    26 00000005 ??                  <2> bpbNumFATs:		resb 1	; offset 05h 10h
    27 00000006 ????                <2> bpbNumRootDirEnts:	resw 1	; offset 06h 11h -- 0 for FAT32
    28 00000008 ????                <2> bpbTotalSectors:	resw 1	; offset 08h 13h
    29 0000000A ??                  <2> bpbMediaID:		resb 1	; offset 0Ah 15h
    30 0000000B ????                <2> bpbSectorsPerFAT:	resw 1	; offset 0Bh 16h -- 0 for FAT32
    31 0000000D ????                <2> bpbCHSSectors:		resw 1	; offset 0Dh 18h
    32 0000000F ????                <2> bpbCHSHeads:		resw 1	; offset 0Fh 1Ah
    33 00000011 ????????            <2> bpbHiddenSectors:	resd 1	; offset 11h 1Ch
    34 00000015 ????????            <2> bpbTotalSectorsLarge:	resd 1	; offset 15h 20h
    35                              <2> bpbNew:				; offset 19h 24h
    36                              <2> 
    37 00000019 ????????            <2> ebpbSectorsPerFATLarge:	resd 1	; offset 19h 24h
    38 0000001D ????                <2> ebpbFSFlags:		resw 1	; offset 1Dh 28h
    39 0000001F ????                <2> ebpbFSVersion:		resw 1	; offset 1Fh 2Ah
    40 00000021 ????????            <2> ebpbRootCluster:	resd 1	; offset 21h 2Ch
    41 00000025 ????                <2> ebpbFSINFOSector:	resw 1	; offset 25h 30h
    42 00000027 ????                <2> ebpbBackupSector:	resw 1	; offset 27h 32h
    43 00000029 <res Ch>            <2> ebpbReserved:		resb 12	; offset 29h 34h
    44                              <2> ebpbNew:			; offset 35h 40h
    45                              <2> 	endstruc
    46                              <2> 
    47                              <2> 	struc BPBN		; ofs B16 S16 B32 S32
    48 00000000 ??                  <2> bpbnBootUnit:		resb 1	; 00h 19h 24h 35h 40h
    49 00000001 ??                  <2> 			resb 1	; 01h 1Ah 25h 36h 41h
    50 00000002 ??                  <2> bpbnExtBPBSignature:	resb 1	; 02h 1Bh 26h 37h 42h -- 29h for valid BPBN
    51 00000003 ????????            <2> bpbnSerialNumber:	resd 1	; 03h 1Ch 27h 38h 43h
    52 00000007 <res Bh>            <2> bpbnVolumeLabel:	resb 11	; 07h 20h 2Bh 3Ch 47h
    53 00000012 ????????????????    <2> bpbnFilesystemID:	resb 8	; 12h 2Bh 36h 47h 52h
    54                              <2> 	endstruc		; 1Ah 33h 3Eh 4Fh 5Ah
    55                              <2> 
    56                              <2> 	struc DIRENTRY
    57 00000000 ????????????????    <2> deName:		resb 8
    58 00000008 ??????              <2> deExt:		resb 3
    59 0000000B ??                  <2> deAttrib:	resb 1
    60 0000000C ??                  <2> dePlusSize:	resb 1
    61 0000000D ??????????????      <2> 		resb 7
    62 00000014 ????                <2> deClusterHigh:	resw 1
    63 00000016 ????                <2> deTime:		resw 1
    64 00000018 ????                <2> deDate:		resw 1
    65 0000001A ????                <2> deClusterLow:	resw 1
    66 0000001C ????????            <2> deSize:		resd 1
    67                              <2> 	endstruc
    68                              <2> 
    69                              <2> ATTR_READONLY	equ 1
    70                              <2> ATTR_HIDDEN	equ 2
    71                              <2> ATTR_SYSTEM	equ 4
    72                              <2> ATTR_VOLLABEL	equ 8
    73                              <2> ATTR_DIRECTORY	equ 10h
    74                              <2> ATTR_ARCHIVE	equ 20h
    75                              <2> 
    76                              <2> lsvclSignature		equ "CL"
    77                              <2> lsvclBufferLength	equ 256
    78                              <2> 
    79                              <2> 	struc LOADSTACKVARS, -10h
    80 FFFFFFF0 ????????            <2> lsvFirstCluster:	resd 1
    81 FFFFFFF4 ????????            <2> lsvFATSector:		resd 1
    82 FFFFFFF8 ????                <2> lsvFATSeg:		resw 1
    83 FFFFFFFA ????                <2> lsvLoadSeg:		resw 1
    84 FFFFFFFC ????????            <2> lsvDataStart:		resd 1
    85                              <2> 	endstruc
    86                              <2> 
    87                              <2> 	struc LOADDATA, LOADSTACKVARS - 10h
    88 FFFFFFE0 ????                <2> ldMemoryTop:	resw 1
    89 FFFFFFE2 ????                <2> ldLoadTop:	resw 1
    90 FFFFFFE4 ????                <2> ldSectorSeg:	resw 1
    91 FFFFFFE6 ??                  <2> ldFATType:	resb 1
    92                              <2> ldFlags:
    93 FFFFFFE7 ??                  <2> ldHasLBA:	resb 1
    94 FFFFFFE8 ????                <2> ldClusterSize:	resw 1
    95 FFFFFFEA ????                <2> ldParaPerSector:resw 1
    96                              <2> ldDirCluster:			; dword
    97                              <2> ldLoadingSeg:		; word
    98                              <2> ldQueryPatchValue:	; word
    99                              <2> lsvCommandLine:		; word
   100                              <2> .start:		equ $ - lsvclBufferLength
   101 FFFFFFEC ????                <2> .signature:	resw 1
   102                              <2> ldLoadUntilSeg:		; word
   103                              <2> lsvExtra:		; word
   104 FFFFFFEE ??                  <2> .partition:	resb 1	; byte
   105 FFFFFFEF ??                  <2> .flags:		resb 1	; byte
   106                              <2> 	endstruc
   107                              <2> 
   108                              <2> ldhlfPreserveLoader	equ 4
   109                              <2> 
   110                              <2> lsvefNoDataStart	equ 1
   111                              <2> lsvefPartitionNumber	equ 2
   112                              <2> lsvefPreserveLoader	equ 4
   113                              <2> 
   114                              <2> %if lsvefPreserveLoader != ldhlfPreserveLoader
   115                              <2>  %error Unexpected flag values
   116                              <2> %endif
   117                              <2> 
   118                              <2> 	struc LOADCMDLINE, LOADDATA - lsvclBufferLength
   119                              <2> ldCommandLine:
   120 FFFFFEE0 <res 100h>          <2> .start:		resb lsvclBufferLength
   121                              <2> 	endstruc
   122                              <2> 
   123                              <2> ldfHasLBA:	equ 1
   124                              <2> ldfFATInvalid:	equ 2
   125                              <2> ldfFATBuffered:	equ 4
   126                              <2> ldfDataBuffered: equ 8
   127                              <2> 
   128                              <2> 	struc LOADDATA2, LOADDATA - 10h
   129 FFFFFFD0 ????????            <2> ldRootSector:		resd 1
   130 FFFFFFD4 ????                <2> ldEntriesPerSector:	resw 1
   131                              <2> ldDataSegment:		; word
   132 FFFFFFD6 ????                <2> ldLastAvailableSector:	resw 1
   133                              <2> ldDataSector:		; dword
   134 FFFFFFD8 ????                <2> ldParasLeft:		resw 1
   135 FFFFFFDA ????                <2> ldParasDone:		resw 1
   136                              <2> 	endstruc
   137                              <2> 
   138                              <2> 	struc LOADDATA3, LOADDATA2 - 10h
   139 FFFFFFC0 ????????            <2> ldMaxCluster:		resd 1
   140 FFFFFFC4 ????????            <2> ldFileSize:		resd 1
   141 FFFFFFC8 ????????            <2> ldCurrentCluster:	resd 1
   142 FFFFFFCC ????????            <2> ldCurrentSeek:		resd 1
   143                              <2> 	endstruc
   144                              <2> 
   145                              <2> 	struc LOADERIMAGEIDENT
   146 00000000 ????????            <2> liiSignature:		resb 4		; "NLDR"
   147 00000004 ????                <2> liiVersion:		resb 2		; "00"
   148 00000006 ????                <2> liiChecksum:		resw 1		; word sum of first 8 words = 0
   149 00000008 ????                <2> liiAmountParagraphs:	resw 1
   150 0000000A ????????????        <2> liiReserved:		resw 3
   151 00000010 ????                <2> liiEntryQuerySize:	resw 1		; 0 if not supported
   152                              <2> 		; INP:	cs => NLDR image ident
   153                              <2> 		;	ip = this word field content
   154                              <2> 		;	ax = 60h
   155                              <2> 		; OUT:	ax => behind memory requested (should be >= 60h)
   156                              <2> 		; CHG:	es, ds, di, si, bx, cx, dx
   157                              <2> 		; STT:	far called, UP, EI
   158 00000012 ????                <2> liiEntryRelocate:	resw 1		; 0 if not supported
   159                              <2> 		; INP:	cs => NLDR image ident
   160                              <2> 		;	ip = this word field content
   161                              <2> 		;	ax = 60h
   162                              <2> 		; OUT:	ax => relocated NLDR segment (usually 60h)
   163                              <2> 		; CHG:	es, ds, di, si, bx, cx, dx
   164                              <2> 		; STT:	far called, UP, EI
   165 00000014 ????                <2> liiEntryDebug:		resw 1		; 0 if not supported
   166                              <2> 		; INP:	es = ds = cs = ss => relocated NLDR
   167                              <2> 		;	ip = this word field content
   168                              <2> 		;	sp = next word field content
   169                              <2> 		; STT:	running as debuggee, UP, EI
   170 00000016 ????                <2> liiStackPointer:	resw 1
   171                              <2> 	endstruc
   172                              <2> 
   173                              <2> 	struc LBAPACKET
   174 00000000 ????                <2> lpSize:		resw 1
   175 00000002 ????                <2> lpCount:	resw 1
   176 00000004 ????????            <2> lpBuffer:	resd 1
   177 00000008 ????????????????    <2> lpSector:	resq 1
   178                              <2> 	endstruc
   179                              <2> 
   180                              <2> 	struc PARTINFO
   181 00000000 ??                  <2> piBoot:		resb 1
   182 00000001 ??????              <2> piStartCHS:	resb 3
   183 00000004 ??                  <2> piType:		resb 1
   184 00000005 ??????              <2> piEndCHS:	resb 3
   185 00000008 ????????            <2> piStart:	resd 1
   186 0000000C ????????            <2> piLength:	resd 1
   187                              <2> 	endstruc
   188                              <2> 
   189                              <2> ptEmpty:		equ 0
   190                              <2> ptFAT12:		equ 1
   191                              <2> ptFAT16_16BIT_CHS:	equ 4
   192                              <2> ptExtendedCHS:		equ 5
   193                              <2> ptFAT16_CHS:		equ 6
   194                              <2> ptFAT32_CHS:		equ 0Bh
   195                              <2> ptFAT32:		equ 0Ch
   196                              <2> ptFAT16:		equ 0Eh
   197                              <2> ptExtended:		equ 0Fh
   198                              <2> ptLinux:		equ 83h
   199                              <2> ptExtendedLinux:	equ 85h
   200                              <2> 
   201                              <2> 
   202                              <2> 		; Flags of load_unit_flags
   203                              <2> lufForceCHS:		equ 1
   204                              <2> lufForceLBA:		equ 2
   205                              <2> lufForceGeometry:	equ 4
   206                              <2> luf_mask_writable equ lufForceCHS | lufForceLBA | lufForceGeometry
   802                              <1> 
   803                              <1> LOAD_INPUT_FILE_SIZE equ fromparas(paras(-LOADDATA3 + bsBPB + ebpbNew + BPBN_size))
   804                              <1> 
   805                              <1> 	struc LOADSETTINGS
   806 00000000 ????                <1> lsKernelName:	resw 1	; -> kernel file default name
   807 00000002 ????                <1> lsAddName:	resw 1	; -> additional file default name, may be empty string
   808 00000004 ????                <1> lsMinPara:	resw 1	; how much to load at least, fail if file smaller
   809 00000006 ????                <1> lsMaxPara:	resw 1	; how much to load at most (will round up to sector size)
   810 00000008 ????                <1> lsOptions:	resw 1	; option flags
   811 0000000A ????                <1> lsSegment:	resw 1	; => where to load file
   812 0000000C ????????            <1> lsEntry:	resd 1	; relative segment for CS, value for IP
   813 00000010 ????????            <1> lsBPB:		resd 1	; segment for BPB (-1 auto-BPB), offset for BPB
   814 00000014 ????????            <1> lsCopyBPB:	resd 1	; if not all-zeroes, copy BPB to far pointer
   815 00000018 ????                <1> lsCheckOffset:	resw 1	; offset in file segment of word to check
   816 0000001A ????                <1> lsCheckValue:	resw 1	; value to check for word, 0 if unused
   817 0000001C ????????????????    <1> lsName:		resq 1	; ASCIZ load protocol name
   818                              <1> 	endstruc
   819                              <1> 
   820                              <1> 		numdef LUF_DEFAULT_DISKETTE, 0
   821                              <1> 		numdef LUF_DEFAULT_HARDDISK, 0
   822                              <1> %endif
   823                              <1> 
   824                              <1> 
   825                              <1> %include "mzheader.mac"
     1                              <2> 
     2                              <2> %if 0
     3                              <2> 
     4                              <2> lDebug MZ .EXE header macros
     5                              <2> 
     6                              <2> Copyright (C) 1995-2003 Paul Vojta
     7                              <2> Copyright (C) 2008-2023 E. C. Masloch
     8                              <2> 
     9                              <2> Usage of the works is permitted provided that this
    10                              <2> instrument is retained with the works, so that any entity
    11                              <2> that uses the works is notified of this instrument.
    12                              <2> 
    13                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    14                              <2> 
    15                              <2> %endif
    16                              <2> 
    17                              <2> 
    18                              <2> 	struc EXEHEADER
    19 00000000 ????                <2> exact_struc_at 00h, exeSignature:	resw 1
    20 00000002 ????                <2> exact_struc_at 02h, exeExtraBytes:	resw 1	; bytes in last page
    21 00000004 ????                <2> exact_struc_at 04h, exePages:		resw 1	; number of 512-byte pages. includes the header!
    22 00000006 ????                <2> exact_struc_at 06h, exeRelocItems:	resw 1	; number of relocation items
    23 00000008 ????                <2> exact_struc_at 08h, exeHeaderSize:	resw 1	; header size in 16-byte paragraphs
    24 0000000A ????                <2> exact_struc_at 0Ah, exeMinAlloc:	resw 1	; minimum (bss) allocation in paragraphs
    25 0000000C ????                <2> exact_struc_at 0Ch, exeMaxAlloc:	resw 1	; maximum (bss) allocation in paragraphs
    26 0000000E ????                <2> exact_struc_at 0Eh, exeInitSS:		resw 1	; init ss (is relocated)
    27 00000010 ????                <2> exact_struc_at 10h, exeInitSP:		resw 1	; init sp
    28 00000012 ????                <2> exact_struc_at 12h, exeChecksum:	resw 1
    29                              <2> exact_struc_at 14h, exeInitCSIP:
    30 00000014 ????                <2> exact_struc_at 14h, exeInitIP:		resw 1	; init ip
    31 00000016 ????                <2> exact_struc_at 16h, exeInitCS:		resw 1	; init cs (is relocated)
    32 00000018 ????                <2> exact_struc_at 18h, exeRelocTable:	resw 1	; byte offset of relocation table
    33                              <2> 		; Each relocation item is a word offset and a word segment.
    34                              <2> 		;  The segment of the item itself is relocated as well.
    35 0000001A ????                <2> exact_struc_at 1Ah, exeOverlayNum:	resw 1
    36                              <2> exact_struc_at 1Ch
    37                              <2> 	endstruc
   826                              <1> 
   827                              <1> 
   828                              <1> 	struc INPUTFILEHANDLE
   829 00000000 ????                <1> ifhHandle:	resw 1
   830 00000002 ????                <1> ifhFlags:	resw 1
   831 00000004 ????????            <1> ifhParentSeek:	resd 1
   832                              <1> 	endstruc
   833                              <1> 
   834                              <1> ifhfIsDup:		equ  100h	; before closing, seek it back
   835                              <1> 	; same value as LBA flag for boot load input files
   836                              <1> ifhfTestReserved1:	equ 1000h
   837                              <1> ifhfTestReserved2:	equ 2000h
   838                              <1> ifhfQuietInput:		equ 4000h	; do not display prompt and input
   839                              <1> ifhfQuietOutput:	equ 8000h	; do not display normal output
   840                              <1> 	; these four are valid for both input file handles and
   841                              <1> 	;  boot load input files.
   842                              <1> 
   843                              <1> 
   844                              <1> 	struc AREASTRUC
   845 00000000 <res 18h>           <1> areastrucEntry:		resb 24
   846 00000018 ????????            <1> areastrucNext:		resd 1
   847 0000001C ????????            <1> areastrucPrev:		resd 1
   848 00000020 ????                <1> areastrucSubAmount:	resw 1
   849 00000022 ????                <1> areastrucSubOffset:	resw 1
   850 00000024 ????                <1> areastrucFunAmount:	resw 1
   851 00000026 ????                <1> areastrucFunOffset:	resw 1
   852                              <1> 	endstruc
   853                              <1> 
   854                              <1> 	struc AREASTRUCSUB
   855 00000000 ????????            <1> areastrucsubLinear:	resd 1
   856 00000004 ????????            <1> areastrucsubLinearEnd:	resd 1
   857 00000008 ????                <1> areastrucsubListOffset:	resw 1
   858 0000000A ????                <1> areastrucsubListAmount:	resw 1
   859                              <1> 	endstruc
   860                              <1> 
   861                              <1> 	struc AREASTRUCFUN
   862 00000000 ????????            <1> areastrucfunLinear:	resd 1
   863 00000004 ????????            <1> areastrucfunLinearEnd:	resd 1
   864 00000008 ????                <1> areastrucfunListOffset:	resw 1
   865 0000000A ????                <1> areastrucfunListAmount:	resw 1
   866                              <1> 	endstruc
   867                              <1> 
   868                              <1> 	struc AREA
   869 00000000 ????                <1> areastart:		resw 1
   870 00000002 ????                <1> areaend:		resw 1
   871 00000004 ????                <1> areamessage:		resw 1
   872 00000006 ????                <1> 			resw 1
   873                              <1> 	endstruc
   874                              <1> 
   875                              <1> 
   876                              <1> %include "isvariab.mac"
     1                              <2> 
     2                              <2> %if 0
     3                              <2> 
     4                              <2> lDebug isvariable? function strutures and macros
     5                              <2> 
     6                              <2> Copyright (C) 2008-2025 E. C. Masloch
     7                              <2> 
     8                              <2> Usage of the works is permitted provided that this
     9                              <2> instrument is retained with the works, so that any entity
    10                              <2> that uses the works is notified of this instrument.
    11                              <2> 
    12                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    13                              <2> 
    14                              <2> %endif
    15                              <2> 
    16                              <2> 
    17                              <2> 	struc ISVARIABLESTRUC
    18 00000000 ????                <2> ivName:		resw 1		; -> name (up to 13 bytes, but actually only 11)
    19                              <2> 				;  (search for ivfNameLengthLimit for limit)
    20                              <2> 				;  (length given by ivFlags & ivfNameLengthMask)
    21                              <2> 	; The ivName pointer is only used for more-byte names. It actually
    22                              <2> 	;  contains the trailer of the name, excluding the prefix formed by
    23                              <2> 	;  the first two bytes. This suffix can be the empty string if the
    24                              <2> 	;  variable in question has a two-byte name.
    25                              <2> 	; (For one-byte names this field is unused and contains zero.)
    26 00000002 ????                <2> ivFlags:	resw 1
    27 00000004 ????                <2> ivAddress:	resw 1		; default -> variable
    28                              <2> 	; The ivAddress field is used by default_variable_setup as the base
    29                              <2> 	;  address for the variable(s). It is also used by var_ext_setup as
    30                              <2> 	;  the ELD code section offset to transfer control to. Otherwise, it
    31                              <2> 	;  is usually set to zero and unused.
    32 00000006 ????                <2> ivSetup:	resw 1		; -> set up code (in expr code section)
    33                              <2> 	; INP:	ax = array index (0-based)
    34                              <2> 	;	di = 0
    35                              <2> 	;	cl = default size of variable (1..4)
    36                              <2> 	;	ch = length of variable name
    37                              <2> 	;	bx -> ISVARIABLESTRUC structure
    38                              <2> 	; CHG:	ax, bx, cx, dx, si, di
    39                              <2> 	; OUT:	NC if valid,
    40                              <2> 	;	 bx -> var, di = 0 or di -> mask
    41                              <2> 	;	 cl = size of variable (1..4)
    42                              <2> 	;	 ch = length of variable name
    43 00000008 ??                  <2> ivArrayLast:	resb 1		; 0 if no array, FFh = 256 entries
    44                              <2> 	; The ivArrayLast field is used by the dispatcher to determine
    45                              <2> 	;  whether to support array index expressions. It is checked
    46                              <2> 	;  before decrementing the index if ivfArrayOneBased is set.
    47 00000009 ??                  <2> ivArrayBetween: resb 1		; how many bytes to skip for each index
    48                              <2> 	; The ivArrayBetween field is only used by default_variable_setup.
    49                              <2> 	endstruc
    50                              <2> 
    51                              <2> ivfNameLengthMask:	equ 15	; gives name trailer length, 0 to 11
    52                              <2> ivfNameLengthLimit:	equ 13
    53                              <2> ivfVarLengthShift:	equ 4
    54                              <2> ivfVarLengthMask:	equ 3 << ivfVarLengthShift
    55                              <2> 				; gives default variable size minus 1
    56                              <2> ivfReadOnly:		equ 80h	; variable cannot be written at all
    57                              <2> ivfArrayOneBased:	equ 100h; first array entry is 1 not 0 (ivArrayLast > 0)
    58                              <2> ivfArrayOptional:	equ 200h; array index expression is optional
    59                              <2> ivfSeparatorSpecial:	equ 400h; used for RIxxP/L/S/O
    60                              <2> 
    61                              <2> %define ISVARIABLESTRINGS db "",db ""
    62                              <2> %define IVS_ONEBYTE_NAMES ""
    63                              <2> %define IVS_MOREBYTE_NAMEHEADERS ""
    64                              <2> %assign IVS_HAVE_ONEBYTE 0
    65                              <2> %assign IVS_SINGLE_ONEBYTE 1
    66                              <2> 
    67                              <2> 		; %1 = name string
    68                              <2> 		; %2 = default variable length, 1 to 4
    69                              <2> 		; %3 = flags to set (except name length and var length)
    70                              <2> 		; %4 = ivAddress value
    71                              <2> 		; %5 = ivArrayLast, defaults to 0 (no array)
    72                              <2> 		; %6 = ivArrayBetween, defaults to 0 (immediately consecutive)
    73                              <2> 		; %7 = ivSetup, defaults to default_variable_setup
    74                              <2> 	%macro isvariablestruc 4-7.nolist 0, 0, default_variable_setup
    75                              <2> %push
    76                              <2> %strlen %$namelength %1
    77                              <2> %if %$namelength > ivfNameLengthLimit
    78                              <2>  %error Expected at most 13-byte name (or adjust isvariable? code)
    79                              <2> %endif
    80                              <2> %if IVS_ONEBYTE && %$namelength != 1
    81                              <2>  %error Expected a one-byte name
    82                              <2> %elif ! IVS_ONEBYTE && %$namelength < 2
    83                              <2>  %error Expected at least a two-byte name
    84                              <2> %endif
    85                              <2> %if IVS_ONEBYTE
    86                              <2>  %define IVS_SINGLE_ONEBYTE_NAME %1
    87                              <2>  %if IVS_HAVE_ONEBYTE
    88                              <2>   %assign IVS_SINGLE_ONEBYTE 0
    89                              <2>  %endif
    90                              <2>  %assign IVS_HAVE_ONEBYTE 1
    91                              <2>  %assign %$namelength 0
    92                              <2>  %xdefine IVS_ONEBYTE_NAMES IVS_ONEBYTE_NAMES, %1
    93                              <2>  %%name equ 0
    94                              <2> %else
    95                              <2>  %assign %$namelength %$namelength - 2
    96                              <2>  %substr %$nametrailer %1 3,-1
    97                              <2>  %substr %$nameheader %1 1,2
    98                              <2>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, %$nameheader
    99                              <2>  %xdefine ISVARIABLESTRINGS ISVARIABLESTRINGS, %%name:, {db %$nametrailer}
   100                              <2> %endif
   101                              <2> 
   102                              <2> %assign %$varlength %2 - 1	; 0 means one byte, 1 means two bytes,
   103                              <2> 				;  2 means three bytes, 3 means four bytes
   104                              <2> 	istruc ISVARIABLESTRUC
   105                              <2> at ivName,		dw %%name
   106                              <2>  IV_NAME_RELOCATION
   107                              <2> at ivFlags,		dw %$$namelength | (%$$varlength << ivfVarLengthShift) | %3
   108                              <2> at ivAddress,		dw %4
   109                              <2>  IV_ADDRESS_RELOCATION
   110                              <2> at ivSetup,		dw %7
   111                              <2>  IV_SETUP_RELOCATION
   112                              <2> at ivArrayLast,		db %5
   113                              <2> at ivArrayBetween,	db %6
   114                              <2> 	iend
   115                              <2> %pop
   116                              <2> %ifndef SECTION_OF_%7
   117                              <2>  %error Unknown target section for symbol %7
   118                              <2> %elifnidni %[SECTION_OF_%7], _EXPR_SECTION
   119                              <2>  %error Wrong section for symbol %7: section_of=SECTION_OF_%7, expr=_EXPR_SECTION
   120                              <2> %endif
   121                              <2> 	%endmacro
   122                              <2> 
   123                              <2> %define IV_NAME_RELOCATION
   124                              <2> %define IV_ADDRESS_RELOCATION
   125                              <2> %define IV_SETUP_RELOCATION
   126                              <2> 
   127                              <2> 	%macro isvariablestrings 2-*.nolist
   128                              <2> %rep %0
   129                              <2>  %1
   130                              <2>  %rotate 1
   131                              <2> %endrep
   132                              <2> 	%endmacro
   877                              <1> 
   878                              <1> 
   879                              <1> %include "386.mac"
     1                              <2> 
     2                              <2> %if 0
     3                              <2> 
     4                              <2> lDebug 386 patch macros
     5                              <2> 
     6                              <2> Copyright (C) 2008-2026 E. C. Masloch
     7                              <2> 
     8                              <2> Usage of the works is permitted provided that this
     9                              <2> instrument is retained with the works, so that any entity
    10                              <2> that uses the works is notified of this instrument.
    11                              <2> 
    12                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    13                              <2> 
    14                              <2> %endif
    15                              <2> 
    16                              <2> 	numdef LINK, 0
    17                              <2> 
    18                              <2> 	numdef WPT_LABELS, 0
    19                              <2> 		; This used to be required, because CODESECTIONFIXUP used
    20                              <2> 		;  ldebug_data_entry_size, which is not yet defined during
    21                              <2> 		;  assembling of (most) lDEBUG_CODE fragments.
    22                              <2> 		; However, assembling DebugX with this option selected
    23                              <2> 		;  took more than 2 minutes, so the non-label variant
    24                              <2> 		;  is clearly to be preferred when available.
    25                              <2> 		; Now that lDEBUG_CODE has vstart=0 we can use the
    26                              <2> 		;  CODESECTIONFIXUP again and thus disable this option.
    27                              <2> 
    28                              <2> %ifn _LINK
    29                              <2> %define PATCH_NO386_TABLE ""
    30                              <2> %define PATCH_386_TABLE ""
    31                              <2> %define PATCH_NO386_TABLE2 ""
    32                              <2> %define PATCH_386_TABLE2 ""
    33                              <2> %define PATCH_NO386_TABLEENTRY ""
    34                              <2> %define PATCH_386_TABLEENTRY ""
    35                              <2> %endif
    36                              <2> 
    37                              <2> %if _ONLY386
    38                              <2> 		; Default patch macros if only running on 386+.
    39                              <2> %define _386_o32 o32
    40                              <2> %define _386_a32 a32
    41                              <2> %define _386_jmps jmp short
    42                              <2> %define _386_jmpn jmp near
    43                              <2> %define _no386_jmps comment
    44                              <2> %define _no386_jmpn comment
    45                              <2> 	%macro _386 0-1+.nolist
    46                              <2> [cpu 386]			; change CPU type
    47                              <2> 		%1		; write instruction
    48                              <2> __CPU__				; reset CPU type
    49                              <2> 	%endmacro
    50                              <2> %define _no386 comment
    51                              <2> %elif _ONLYNON386
    52                              <2> 		; Default patch macros if only running on non-386.
    53                              <2> %define _386_o32
    54                              <2> %define _386_a32
    55                              <2> %define _386_jmps comment
    56                              <2> %define _386_jmpn comment
    57                              <2> %define _no386_jmps jmp short
    58                              <2> %define _no386_jmpn jmp near
    59                              <2> %define _386 comment
    60                              <2> %define _no386
    61                              <2> %else
    62                              <2> 
    63                              <2> ; These macros are to make DEBUG's 386 support as small as
    64                              <2> ; possible. To achieve this, two patch tables are created
    65                              <2> ; in the initialisation code. One of the tables is used if
    66                              <2> ; the CPU is a 386+, the other one if it isn't. The bytes
    67                              <2> ; pointed to in the used table are over-written with NOP
    68                              <2> ; instructions. (The patched bytes are usually address or
    69                              <2> ; operand size prefixes or jumps that branch to 386/non-386
    70                              <2> ; code.)
    71                              <2> 
    72                              <2> ; There are a few special patches that require the
    73                              <2> ; initialisation code to write specific bytes other than
    74                              <2> ; NOP instructions for lower resident memory usage.
    75                              <2> ; Two are in the run: code, three in pmentry.asm.
    76                              <2> 
    77                              <2> %if _LINK
    78                              <2> 
    79                              <2> %imacro wllist 1-3.nolist
    80                              <2> %ifnempty %3
    81                              <2>  %deftok %%filenametoken %3
    82                              <2> %else
    83                              <2>  %deftok %%filenametoken __FILE__
    84                              <2> %endif
    85                              <2>  global ..@wllist_%1?%[%%l]%[%%filenametoken]
    86                              <2> ..@wllist_%1?%[%%l]%[%%filenametoken]: %2
    87                              <2> %endmacro
    88                              <2> 
    89                              <2> 	%macro patch386 2-3.nolist 1
    90                              <2> %define %%repeat
    91                              <2> %if %3 != 1
    92                              <2>  %define %%repeat r%3_
    93                              <2> %endif
    94                              <2> %ifidn _CURRENT_SECTION, lDEBUG_CODE
    95                              <2>  wllist %[%%repeat]Lpatch_%{1}386_table, %2
    96                              <2> %elifidn _CURRENT_SECTION, lDEBUG_CODE2
    97                              <2>  wllist %[%%repeat]Lpatch_%{1}386_table2, %2
    98                              <2> %elifidn _CURRENT_SECTION, lDEBUG_DATA_ENTRY
    99                              <2>  wllist %[%%repeat]Lpatch_%{1}386_tableentry, %2
   100                              <2> %else
   101                              <2>  %error Wrong section
   102                              <2> %endif
   103                              <2> 	%endmacro
   104                              <2> 
   105                              <2> 		; Operand size 32-bit prefix if 386+ CPU
   106                              <2> 	%macro _386_o32 0-1+.nolist
   107                              <2> _386		o32
   108                              <2> 		%1
   109                              <2> 	%endmacro
   110                              <2> 
   111                              <2> 		; Address size 32-bit prefix if 386+ CPU
   112                              <2> 	%macro _386_a32 0-1+.nolist
   113                              <2> _386		a32
   114                              <2> 		%1
   115                              <2> 	%endmacro
   116                              <2> 
   117                              <2> 		; Short jump if 386+ CPU
   118                              <2> 	%macro _386_jmps 1.nolist
   119                              <2> _386		jmp short %1
   120                              <2> 	%endmacro
   121                              <2> 
   122                              <2> 		; Near jump if 386+ CPU
   123                              <2> 	%macro _386_jmpn 1.nolist
   124                              <2> _386		jmp near %1
   125                              <2> 	%endmacro
   126                              <2> 
   127                              <2> 		; Short jump if no 386+ CPU
   128                              <2> 	%macro _no386_jmps 1.nolist
   129                              <2> _no386		jmp short %1
   130                              <2> 	%endmacro
   131                              <2> 
   132                              <2> 		; Near jump if no 386+ CPU
   133                              <2> 	%macro _no386_jmpn 1.nolist
   134                              <2> _no386		jmp near %1
   135                              <2> 	%endmacro
   136                              <2> 
   137                              <2> 		; Instruction if 386+ CPU
   138                              <2> 	%macro _386 0-1+.nolist
   139                              <2> [cpu 386]			; change CPU type
   140                              <2> %%entry:
   141                              <2> 		%1		; write instruction
   142                              <2> __CPU__				; reset CPU type
   143                              <2> %assign %%length ($ - %%entry)
   144                              <2>  patch386 no, equ %%entry, %%length
   145                              <2> 	%endmacro
   146                              <2> 
   147                              <2> 		; Instruction if no 386+ CPU
   148                              <2> 	%macro _no386 0-1+.nolist
   149                              <2> %%entry:
   150                              <2> 		%1		; write instruction
   151                              <2> %assign %%length ($ - %%entry)
   152                              <2>  patch386 , equ %%entry, %%length
   153                              <2> 	%endmacro
   154                              <2> 
   155                              <2> %else
   156                              <2> 	%macro patch386 2+.nolist
   157                              <2> %ifidn _CURRENT_SECTION, lDEBUG_CODE
   158                              <2>  %define PATCH_%{1}386_TABLE %[PATCH_%{1}386_TABLE], %2
   159                              <2> %elifidn _CURRENT_SECTION, lDEBUG_CODE2
   160                              <2>  %define PATCH_%{1}386_TABLE2 %[PATCH_%{1}386_TABLE2], %2
   161                              <2> %elifidn _CURRENT_SECTION, lDEBUG_DATA_ENTRY
   162                              <2>  %define PATCH_%{1}386_TABLEENTRY %[PATCH_%{1}386_TABLEENTRY], %2
   163                              <2> %else
   164                              <2>  %error Wrong section
   165                              <2> %endif
   166                              <2> 	%endmacro
   167                              <2> 
   168                              <2> %if _WPT_LABELS
   169                              <2> 	; These forms provide verbose info by defining a
   170                              <2> 	; meaningful label for each patch. That fills up
   171                              <2> 	; the map file and might take longer though.
   172                              <2> 		; Operand size 32-bit prefix if 386+ CPU
   173                              <2> 	%macro _386_o32 0-1+.nolist
   174                              <2> %%386_o32:	o32
   175                              <2> patch386 NO, %%386_o32
   176                              <2> 		%1
   177                              <2> 	%endmacro
   178                              <2> 
   179                              <2> 		; Address size 32-bit prefix if 386+ CPU
   180                              <2> 	%macro _386_a32 0-1+.nolist
   181                              <2> %%386_a32:	a32
   182                              <2> patch386 NO, %%386_a32
   183                              <2> 		%1
   184                              <2> 	%endmacro
   185                              <2> 
   186                              <2> 		; Short jump if 386+ CPU
   187                              <2> 	%macro _386_jmps 1.nolist
   188                              <2> %%386_jmps:	jmp short %1
   189                              <2> patch386 NO, %%386_jmps,%%386_jmps+1
   190                              <2> 	%endmacro
   191                              <2> 
   192                              <2> 		; Near jump if 386+ CPU
   193                              <2> 	%macro _386_jmpn 1.nolist
   194                              <2> %%386_jmpn:	jmp near %1
   195                              <2> patch386 NO, %%386_jmpn,%%386_jmpn+1,%%386_jmpn+2
   196                              <2> 	%endmacro
   197                              <2> 
   198                              <2> 		; Short jump if no 386+ CPU
   199                              <2> 	%macro _no386_jmps 1.nolist
   200                              <2> %%no386_jmps:	jmp short %1
   201                              <2> patch386 , %%no386_jmps,%%no386_jmps+1
   202                              <2> 	%endmacro
   203                              <2> 
   204                              <2> 		; Near jump if no 386+ CPU
   205                              <2> 	%macro _no386_jmpn 1.nolist
   206                              <2> %%no386_jmpn:	jmp near %1
   207                              <2> patch386 , %%no386_jmpn,%%no386_jmpn+1,%%no386_jmpn+2
   208                              <2> 	%endmacro
   209                              <2> 
   210                              <2> 		; Instruction if 386+ CPU
   211                              <2> 	%macro _386 0-1+.nolist
   212                              <2> [cpu 386]			; change CPU type
   213                              <2> %%386_instr:	%1		; write instruction
   214                              <2> __CPU__				; reset CPU type
   215                              <2> 
   216                              <2> %assign %%INSTRCOUNT 0
   217                              <2> %rep $-%%386_instr		; count size of instruction
   218                              <2>  patch386 NO, %%386_instr+%[%%INSTRCOUNT]
   219                              <2> 				; write a patch for each byte
   220                              <2>  %assign %%INSTRCOUNT %%INSTRCOUNT+1
   221                              <2> %endrep
   222                              <2> %undef %%INSTRCOUNT
   223                              <2> 	%endmacro
   224                              <2> 
   225                              <2> 		; Instruction if no 386+ CPU
   226                              <2> 	%macro _no386 0-1+.nolist
   227                              <2> %%no386_instr:	%1		; write instruction
   228                              <2> 
   229                              <2> %assign %%INSTRCOUNT 0
   230                              <2> %rep $-%%no386_instr		; count size of instruction
   231                              <2>  patch386 , %%no386_instr+%[%%INSTRCOUNT]
   232                              <2> 				; write a patch for each byte
   233                              <2>  %assign %%INSTRCOUNT %%INSTRCOUNT+1
   234                              <2> %endrep
   235                              <2> %undef %%INSTRCOUNT
   236                              <2> 	%endmacro
   237                              <2> %else	; _WPT_LABELS
   238                              <2> 		; Operand size 32-bit prefix if 386+ CPU
   239                              <2> 	%macro _386_o32 0-1+.nolist
   240                              <2> _386		o32
   241                              <2> 		%1
   242                              <2> 	%endmacro
   243                              <2> 
   244                              <2> 		; Address size 32-bit prefix if 386+ CPU
   245                              <2> 	%macro _386_a32 0-1+.nolist
   246                              <2> _386		a32
   247                              <2> 		%1
   248                              <2> 	%endmacro
   249                              <2> 
   250                              <2> 		; Short jump if 386+ CPU
   251                              <2> 	%macro _386_jmps 1.nolist
   252                              <2> _386		jmp short %1
   253                              <2> 	%endmacro
   254                              <2> 
   255                              <2> 		; Near jump if 386+ CPU
   256                              <2> 	%macro _386_jmpn 1.nolist
   257                              <2> _386		jmp near %1
   258                              <2> 	%endmacro
   259                              <2> 
   260                              <2> 		; Short jump if no 386+ CPU
   261                              <2> 	%macro _no386_jmps 1.nolist
   262                              <2> _no386		jmp short %1
   263                              <2> 	%endmacro
   264                              <2> 
   265                              <2> 		; Near jump if no 386+ CPU
   266                              <2> 	%macro _no386_jmpn 1.nolist
   267                              <2> _no386		jmp near %1
   268                              <2> 	%endmacro
   269                              <2> 
   270                              <2> 		; Instruction if 386+ CPU
   271                              <2> 	%macro _386 0-1+.nolist
   272                              <2> %push
   273                              <2> [cpu 386]			; change CPU type
   274                              <2> %assign %$entry $ + _CURRENT_SECTION %+ FIXUP
   275                              <2> 		%1		; write instruction
   276                              <2> __CPU__				; reset CPU type
   277                              <2> 
   278                              <2> %rep ($ + _CURRENT_SECTION %+ FIXUP) - %$entry
   279                              <2> 				; count size of instruction
   280                              <2>  patch386 NO, %[%$entry]	; write a patch for each byte
   281                              <2>  %assign %$entry %$entry+1
   282                              <2> %endrep
   283                              <2> %pop
   284                              <2> 	%endmacro
   285                              <2> 
   286                              <2> 		; Instruction if no 386+ CPU
   287                              <2> 	%macro _no386 0-1+.nolist
   288                              <2> %push
   289                              <2> %assign %$entry $ + _CURRENT_SECTION %+ FIXUP
   290                              <2> 		%1		; write instruction
   291                              <2> 
   292                              <2> %rep ($ + _CURRENT_SECTION %+ FIXUP) - %$entry
   293                              <2> 				; count size of instruction
   294                              <2>  patch386 , %[%$entry]		; write a patch for each byte
   295                              <2>  %assign %$entry %$entry+1
   296                              <2> %endrep
   297                              <2> %pop
   298                              <2> 	%endmacro
   299                              <2> %endif	; _WPT_LABELS
   300                              <2> %endif	; _LINK
   301                              <2> 
   302                              <2> %endif
   303                              <2> 
   304                              <2> 		; Patch macros but for cases where the 386+
   305                              <2> 		; instructions should only be generated for
   306                              <2> 		; DEBUGX (i.e. for 32-bit DPMI addressing code).
   307                              <2> %if _PM
   308                              <2> %define _386_PM_o32	_386_o32
   309                              <2> %define _386_PM_a32	_386_a32
   310                              <2> %define _386_PM_jmps	_386_jmps
   311                              <2> %define _386_PM_jmpn	_386_jmpn
   312                              <2> %define _386_PM		_386
   313                              <2> %else
   314                              <2> %define _386_PM_o32
   315                              <2> %define _386_PM_a32
   316                              <2> %define _386_PM_jmps	comment
   317                              <2> %define _386_PM_jmpn	comment
   318                              <2> %define _386_PM		comment
   319                              <2> %endif
   320                              <2> 
   321                              <2> 
   322                              <2> %ifn _LINK
   323                              <2> %macro __writepatchtable2 0-*.nolist
   324                              <2> %if %0 & 1
   325                              <2>  %fatal Expected even number of arguments
   326                              <2> %endif
   327                              <2> %rep %0 >> 1
   328                              <2> 	%1 %2
   329                              <2> %rotate 2
   330                              <2> %endrep
   331                              <2> %endmacro
   332                              <2> 
   333                              <2> %macro __patchtable2_entry 0.nolist
   334                              <2>   ; only if this isn't the first (pseudo-)entry
   335                              <2>   %if %$lastcount != 0
   336                              <2>     %assign %$runscount %[%$runscount]+1
   337                              <2>    ; if the offset from %$previous is less than 255
   338                              <2>    %if (%$last-%$previous) < 255
   339                              <2>     %assign %$$method2tablesize %$$method2tablesize+1
   340                              <2>     ; then write a single byte (number of bytes not to patch between)
   341                              <2>     %xdefine %$$method2list %$$method2list,db,%$last-%$previous
   342                              <2>    %else
   343                              <2>     ; otherwise write a 255 ("reposition") and write the 16-bit address afterwards
   344                              <2>     %assign %$$method2tablesize %$$method2tablesize+3
   345                              <2>     %xdefine %$$method2list %$$method2list,db,255,dw,%$last
   346                              <2>     %assign %$reposcount %[%$reposcount]+1
   347                              <2>    %endif
   348                              <2>    %if %$lastcount == 1
   349                              <2>     %assign %$onecount %[%$onecount]+1
   350                              <2>    %endif
   351                              <2>    %assign %$$method2tablesize %$$method2tablesize+1
   352                              <2>    ; and write the number of bytes to be patched
   353                              <2>    %xdefine %$$method2list %$$method2list,db,%$lastcount
   354                              <2>    ; define %$previous for the next entry: it points to the next non-patched byte
   355                              <2>    %define %$previous (%[%$last]+%[%$lastcount])
   356                              <2>   %endif
   357                              <2> %endmacro
   358                              <2> 
   359                              <2> %macro writepatchtable 2-*.nolist
   360                              <2> 
   361                              <2> 	numdef %{1}_FORCE_METHOD, 0
   362                              <2> %push
   363                              <2> 		; Determine length of simple table:
   364                              <2> %assign %$method1tablesize (%0 - 2)*2
   365                              <2> 
   366                              <2> %if !_%{1}_FORCE_METHOD || _%{1}_FORCE_METHOD == 2
   367                              <2> 		; Determine length of complicated table:
   368                              <2> %assign %$method2tablesize 0
   369                              <2> %define %$method2list db,""
   370                              <2> %push
   371                              <2> %if _WPT_LABELS
   372                              <2>  %define %$previous code_start	; if list contains labels
   373                              <2> %else
   374                              <2>  %define %$previous 0
   375                              <2> %endif
   376                              <2> %define %$last %[%$previous]
   377                              <2> %assign %$lastcount 0
   378                              <2> %assign %$onecount 0
   379                              <2> %assign %$reposcount 0
   380                              <2> %assign %$bytescount %0 - 2
   381                              <2> %assign %$runscount 0
   382                              <2> %rotate 1
   383                              <2> %rep %0 - 2
   384                              <2>  %rotate 1
   385                              <2>  ;if  it continues the previous patch   and not too long   and this isn't the first
   386                              <2>  %if ((%$last+%$lastcount) == %1) && (%$lastcount < 255) && (%$lastcount != 0)
   387                              <2>   ; then do not write an entry, just increase the patch's size
   388                              <2>   %assign %$lastcount %[%$lastcount]+1
   389                              <2>  %else
   390                              <2>   ; otherwise write the last entry
   391                              <2>   __patchtable2_entry
   392                              <2>   ; define new %$last to this parameter, %$lastcount to one
   393                              <2>   %define %$last %1
   394                              <2>   %assign %$lastcount 1
   395                              <2>  %endif
   396                              <2> %endrep
   397                              <2> __patchtable2_entry
   398                              <2> 
   399                              <2> ; at the end, there's a patch with offset 0, size 0
   400                              <2> %assign %$$method2tablesize %$$method2tablesize+2
   401                              <2> %xdefine %$$method2list %$$method2list,db,0,db,0
   402                              <2> 
   403                              <2> %assign %$$onecount %$onecount
   404                              <2> %assign %$$reposcount %$reposcount
   405                              <2> %assign %$$bytescount %$bytescount
   406                              <2> %assign %$$runscount %$runscount
   407                              <2> %pop
   408                              <2> %rotate 1
   409                              <2> %endif
   410                              <2> 
   411                              <2> %if _%{1}_FORCE_METHOD == 2
   412                              <2>  %define __%{1}_method 2
   413                              <2> %elif _%{1}_FORCE_METHOD == 1
   414                              <2>  %define __%{1}_method 1
   415                              <2> %else
   416                              <2>  %if _%{1}_FORCE_METHOD
   417                              <2>   %fatal Invalid forced method selected: _%{1}_FORCE_METHOD
   418                              <2>  %endif
   419                              <2>  %if %$method1tablesize > (%$method2tablesize+20)
   420                              <2>   %define __%{1}_method 2
   421                              <2>  %else
   422                              <2>   %define __%{1}_method 1
   423                              <2>  %endif
   424                              <2> %endif
   425                              <2> 
   426                              <2> 
   427                              <2> %1:
   428                              <2> %if __%{1}_method == 2
   429                              <2> 	__writepatchtable2 %$method2list
   430                              <2> 	endarea %1
   431                              <2> %assign %$size %1_size
   432                              <2> %warning %1: %$size bytes (Method 2)
   433                              <2> %warning 1B=%$onecount repo=%$reposcount run=%$runscount byte=%$bytescount
   434                              <2> %else
   435                              <2> %rotate 1
   436                              <2> %rep %0 - 2
   437                              <2> %rotate 1
   438                              <2> 	dw %1
   439                              <2> %endrep
   440                              <2> %rotate 1
   441                              <2> 	endarea %1
   442                              <2> %assign %$size %1_size
   443                              <2> %warning %1: %$size bytes (Method 1)
   444                              <2> %1.amount equ %1_size_w
   445                              <2> %endif
   446                              <2> %pop
   447                              <2> %endmacro
   448                              <2> %endif
   880                              <1> 
   881                              <1> 
   882                              <1> %if _VDD
   883                              <1> ; standard BOPs for communication with DEBXXVDD on NT platforms
   884                              <1> %macro RegisterModule 0.nolist
   885                              <1> 	db 0C4h, 0C4h, 58h, 0
   886                              <1> 	nop
   887                              <1> %endmacro
   888                              <1> %macro UnRegisterModule 0.nolist
   889                              <1> 	db 0C4h, 0C4h, 58h, 1
   890                              <1> 	nop
   891                              <1> %endmacro
   892                              <1> %macro DispatchCall 0.nolist
   893                              <1> 	db 0C4h, 0C4h, 58h, 2
   894                              <1> 	nop
   895                              <1> %endmacro
   896                              <1> %endif
   897                              <1> 
   898                              <1> %assign CODE_INSURE_COUNT 0
   899                              <1> 
   900                              <1> 		; The entry_to_code_seg/_sel dispatcher in lDEBUG_DATA_ENTRY
   901                              <1> 		;  detects mistaken debugger breakpoints in its
   902                              <1> 		;  in-code-parameter by checking for a low-byte
   903                              <1> 		;  value equal to 0CCh (one-byte int3 opcode).
   904                              <1> 		; Therefore, we insure that all destinations jumped to
   905                              <1> 		;  via that dispatcher do not happen to be located
   906                              <1> 		;  on an offset that gives 0CCh in the low byte.
   907                              <1> 	%imacro code_insure_low_byte_not_0CCh 0.nolist
   908                              <1> %ifn _LINK
   909                              <1>  %if (($ - _CURRENT_SECTION %+ _start) & 0FFh) == 0CCh
   910                              <1> 	nop
   911                              <1>   %assign CODE_INSURE_COUNT 1 + CODE_INSURE_COUNT
   912                              <1>  %endif
   913                              <1> %endif
   914                              <1> 	%endmacro
   915                              <1> 
   916                              <1> 
   917                              <1> 		; dual code segments
   918                              <1> %if _DUALCODE && _PM
   919                              <1> 
   920                              <1> %if _DEBUG
   921                              <1> %idefine dualfunction comment
   922                              <1> %else
   923                              <1> %idefine dualfunction code_insure_low_byte_not_0CCh
   924                              <1> %endif
   925                              <1> 
   926                              <1> %idefine dualreturn call _CURRENT_SECTION %+ _dualret_helper
   927                              <1> %idefine dualdistance far
   928                              <1> 	%imacro dualcall 1.nolist
   929                              <1> %ifndef SECTION_OF_%1
   930                              <1>  %error Unknown target section for symbol %1
   931                              <1> %endif
   932                              <1> 	call _CURRENT_SECTION %+ _to_ %+ %[SECTION_OF_%1] %+ _dualcall_helper
   933                              <1>  %if _DEBUG
   934                              <1> 	jmp strict short %%skipdata
   935                              <1>  %endif
   936                              <1> 	dw %1
   937                              <1> %%skipdata:
   938                              <1> 	%endmacro
   939                              <1> 	%imacro nearcall 1.nolist
   940                              <1> %ifndef SECTION_OF_%1
   941                              <1>  %error Unknown target section for symbol %1
   942                              <1> %endif
   943                              <1> %ifidni %[SECTION_OF_%1], _CURRENT_SECTION
   944                              <1> 	call %1
   945                              <1> %else
   946                              <1> 	call _CURRENT_SECTION %+ _to_ %+ %[SECTION_OF_%1] %+ _nearcall_helper
   947                              <1>  %if _DEBUG
   948                              <1> 	jmp strict short %%skipdata
   949                              <1>  %endif
   950                              <1> 	dw %1
   951                              <1> %%skipdata:
   952                              <1> %endif
   953                              <1> 	%endmacro
   954                              <1> 
   955                              <1> %elif _DUALCODE && ! _PM
   956                              <1> 
   957                              <1> %idefine dualfunction comment
   958                              <1> %idefine dualreturn
   959                              <1> %idefine dualdistance far
   960                              <1> 
   961                              <1> %ifn _LINK
   962                              <1> %define PATCH_RELOCATE_FROM_lDEBUG_CODE ""
   963                              <1> %define PATCH_RELOCATE_FROM_lDEBUG_CODE2 ""
   964                              <1> 	%imacro dualcall 1.nolist
   965                              <1> %ifndef SECTION_OF_%1
   966                              <1>  %error Unknown target section for symbol %1
   967                              <1> %endif
   968                              <1> %ifidni %[SECTION_OF_%1], _CURRENT_SECTION
   969                              <1> 	push cs
   970                              <1> 	call %1
   971                              <1> %else
   972                              <1> 	call relocatedzero:%1
   973                              <1> %push
   974                              <1> %assign %$entry ($ + _CURRENT_SECTION %+ FIXUP) - 2
   975                              <1> 	relocatelist _CURRENT_SECTION, %$entry
   976                              <1> %pop
   977                              <1> %endif
   978                              <1> 	%endmacro
   979                              <1> 	%imacro relocatelist 2.nolist
   980                              <1>  %define PATCH_RELOCATE_FROM_%1 %[PATCH_RELOCATE_FROM_%1],%2
   981                              <1> 	%endmacro
   982                              <1> %else		; _LINK
   983                              <1> 	%idefine dualcall dualcall_with_filename __FILE__,
   984                              <1> 	%imacro dualcall_with_filename 2.nolist
   985                              <1> %ifndef SECTION_OF_%2
   986                              <1>  %error Unknown target section for symbol %2
   987                              <1> %endif
   988                              <1> %ifidni %[SECTION_OF_%2], _CURRENT_SECTION
   989                              <1> 	push cs
   990                              <1> 	call %2
   991                              <1> %else
   992                              <1> 	call relocatedzero:%2
   993                              <1> %ifidn _CURRENT_SECTION, lDEBUG_CODE
   994                              <1>  wllist Lrelocate_from_code, equ $ - 2, %1
   995                              <1> %elifidn _CURRENT_SECTION, lDEBUG_CODE2
   996                              <1>  wllist Lrelocate_from_code2, equ $ - 2, %1
   997                              <1> %else
   998                              <1>  %error Wrong section
   999                              <1> %endif
  1000                              <1> %endif
  1001                              <1> 	%endmacro
  1002                              <1> %endif		; _LINK
  1003                              <1>  %if _DUALCODENEARDUAL
  1004                              <1> 
  1005                              <1> %if _LINK
  1006                              <1> 	%idefine nearcall nearcall_with_filename __FILE__,
  1007                              <1> 	%imacro nearcall_with_filename 2
  1008                              <1> %ifndef SECTION_OF_%2
  1009                              <1>  %error Unknown target section for symbol %2
  1010                              <1> %endif
  1011                              <1> %ifidni %[SECTION_OF_%2], _CURRENT_SECTION
  1012                              <1> 	call %2
  1013                              <1> %else
  1014                              <1>  %push
  1015                              <1>  %xdefine %$originalsection _CURRENT_SECTION
  1016                              <1>  %xdefine %$targetsection SECTION_OF_%2
  1017                              <1>  %deftok %%filenametoken SOURCEFILENAME
  1018                              <1>   %ifndef NEARCALL_THUNK_TO_%2%[%%filenametoken]
  1019                              <1> 	hiddenusesection %$targetsection
  1020                              <1> %define NEARCALL_THUNK_TO_%2%[%%filenametoken] %%nearcall_thunk_to_%2%[%%filenametoken]
  1021                              <1> section_of %%nearcall_thunk_to_%2%[%%filenametoken]
  1022                              <1> dualfunction
  1023                              <1> %%nearcall_thunk_to_%2%[%%filenametoken]:
  1024                              <1> 	call %2
  1025                              <1> 	dualreturn
  1026                              <1> 	retf
  1027                              <1> 
  1028                              <1> 	hiddenusesection %$originalsection
  1029                              <1>   %endif
  1030                              <1>  %pop
  1031                              <1> 	dualcall_with_filename %1, NEARCALL_THUNK_TO_%2%[%%filenametoken]
  1032                              <1> %endif
  1033                              <1> 	%endmacro
  1034                              <1> %elif _LINK_COMPAT	; _LINK
  1035                              <1> 	%imacro nearcall 1
  1036                              <1> %ifndef SECTION_OF_%1
  1037                              <1>  %error Unknown target section for symbol %1
  1038                              <1> %endif
  1039                              <1> %ifidni %[SECTION_OF_%1], _CURRENT_SECTION
  1040                              <1> 	call %1
  1041                              <1> %else
  1042                              <1>  %push
  1043                              <1>  %xdefine %$originalsection _CURRENT_SECTION
  1044                              <1>  %xdefine %$targetsection SECTION_OF_%1
  1045                              <1>  %deftok %%filenametoken SOURCEFILENAME
  1046                              <1>   %ifndef NEARCALL_THUNK_TO_%1%[%%filenametoken]
  1047                              <1> 	hiddenusesection %$targetsection
  1048                              <1> %define NEARCALL_THUNK_TO_%1%[%%filenametoken] %%nearcall_thunk_to_%1%[%%filenametoken]
  1049                              <1> section_of %%nearcall_thunk_to_%1%[%%filenametoken]
  1050                              <1> dualfunction
  1051                              <1> %%nearcall_thunk_to_%1%[%%filenametoken]:
  1052                              <1> 	call %1
  1053                              <1> 	dualreturn
  1054                              <1> 	retf
  1055                              <1> 
  1056                              <1> 	hiddenusesection %$originalsection
  1057                              <1>   %endif
  1058                              <1>  %pop
  1059                              <1> 	dualcall NEARCALL_THUNK_TO_%1%[%%filenametoken]
  1060                              <1> %endif
  1061                              <1> 	%endmacro
  1062                              <1> %else		; _LINK, _LINK_COMPAT
  1063                              <1> 	%imacro nearcall 1
  1064                              <1> %ifndef SECTION_OF_%1
  1065                              <1>  %error Unknown target section for symbol %1
  1066                              <1> %endif
  1067                              <1> %ifidni %[SECTION_OF_%1], _CURRENT_SECTION
  1068                              <1> 	call %1
  1069                              <1> %else
  1070                              <1>  %push
  1071                              <1>  %xdefine %$originalsection _CURRENT_SECTION
  1072                              <1>  %xdefine %$targetsection SECTION_OF_%1
  1073                              <1>   %ifndef NEARCALL_THUNK_TO_%1
  1074                              <1> 	hiddenusesection %$targetsection
  1075                              <1> %define NEARCALL_THUNK_TO_%1 %%nearcall_thunk_to_%1
  1076                              <1> section_of %%nearcall_thunk_to_%1
  1077                              <1> dualfunction
  1078                              <1> %%nearcall_thunk_to_%1:
  1079                              <1> 	call %1
  1080                              <1> 	dualreturn
  1081                              <1> 	retf
  1082                              <1> 
  1083                              <1> 	hiddenusesection %$originalsection
  1084                              <1>   %endif
  1085                              <1>  %pop
  1086                              <1> 	dualcall NEARCALL_THUNK_TO_%1
  1087                              <1> %endif
  1088                              <1> 	%endmacro
  1089                              <1> %endif		; _LINK, _LINK_COMPAT
  1090                              <1>  %else
  1091                              <1> 	%imacro nearcall 1.nolist
  1092                              <1> %ifndef SECTION_OF_%1
  1093                              <1>  %error Unknown target section for symbol %1
  1094                              <1> %endif
  1095                              <1> %ifidni %[SECTION_OF_%1], _CURRENT_SECTION
  1096                              <1> 	call %1
  1097                              <1> %else
  1098                              <1> 	call _CURRENT_SECTION %+ _to_ %+ %[SECTION_OF_%1] %+ _nearcall_helper
  1099                              <1>  %if _DEBUG
  1100                              <1> 	jmp strict short %%skipdata
  1101                              <1>  %endif
  1102                              <1> 	dw %1
  1103                              <1> %%skipdata:
  1104                              <1> %endif
  1105                              <1> 	%endmacro
  1106                              <1>  %endif
  1107                              <1> %elif ! _DUALCODE
  1108                              <1> 
  1109                              <1> %idefine dualfunction comment
  1110                              <1> %idefine dualreturn
  1111                              <1> %idefine dualdistance near
  1112                              <1> 	%imacro dualcall 1.nolist
  1113                              <1> 	call %1
  1114                              <1> 	%endmacro
  1115                              <1> 	%imacro nearcall 1.nolist
  1116                              <1> 	call %1
  1117                              <1> 	%endmacro
  1118                              <1> %assign _SYMBOLICDUALCODE 0
  1119                              <1> %assign _SYMBOLASMDUALCODE 0
  1120                              <1> 
  1121                              <1> %else
  1122                              <1>  %error Unexpected defines
  1123                              <1> %endif
  1124                              <1> 
  1125                              <1> %ifn _SYMBOLICDUALCODE
  1126                              <1>  %assign _SYMBOLASMDUALCODE 0
  1127                              <1> %endif
  1128                              <1> 
  1129                              <1>  %if _SYMBOLIC && _DUALCODE && _SYMBOLASMDUALCODE
  1130                              <1> %idefine dual2function	dualfunction
  1131                              <1> %idefine dual2return	dualreturn
  1132                              <1> %idefine dual2distance	dualdistance
  1133                              <1> %idefine dual2call	dualcall
  1134                              <1>  %else
  1135                              <1> %idefine dual2function comment
  1136                              <1> %idefine dual2return
  1137                              <1> %idefine dual2distance near
  1138                              <1> 	%imacro dual2call 1.nolist
  1139                              <1> 	call %1
  1140                              <1> 	%endmacro
  1141                              <1>  %endif
  1142                              <1> 
  1143                              <1> 
  1144                              <1> 	numdef CHECKSECTION, 0
  1145                              <1> 	numdef CHECKCALLSECTION, _CHECKSECTION
  1146                              <1> 	numdef CHECKJMPSECTION, _CHECKSECTION
  1147                              <1> 	numdef CHECKJCCSECTION, _CHECKSECTION
  1148                              <1> 
  1149                              <1> %if _CHECKCALLSECTION
  1150                              <1> 	%imacro call 1.nolist
  1151                              <1> 	%? %1
  1152                              <1> checksection %1, %?, call
  1153                              <1> 	%endmacro
  1154                              <1> %endif
  1155                              <1> %if _CHECKJMPSECTION
  1156                              <1> 	%imacro jmp 1.nolist
  1157                              <1> 	%? %1
  1158                              <1> checksection %1, %?, jmp
  1159                              <1> 	%endmacro
  1160                              <1> %endif
  1161                              <1> %if _CHECKJCCSECTION
  1162                              <1> 	%imacro je 1.nolist
  1163                              <1> 	%? %1
  1164                              <1> checksection %1, %?, jcc
  1165                              <1> 	%endmacro
  1166                              <1> 	%imacro jne 1.nolist
  1167                              <1> 	%? %1
  1168                              <1> checksection %1, %?, jcc
  1169                              <1> 	%endmacro
  1170                              <1> 	%imacro jz 1.nolist
  1171                              <1> 	%? %1
  1172                              <1> checksection %1, %?, jcc
  1173                              <1> 	%endmacro
  1174                              <1> 	%imacro jnz 1.nolist
  1175                              <1> 	%? %1
  1176                              <1> checksection %1, %?, jcc
  1177                              <1> 	%endmacro
  1178                              <1> 
  1179                              <1> 	%imacro jb 1.nolist
  1180                              <1> 	%? %1
  1181                              <1> checksection %1, %?, jcc
  1182                              <1> 	%endmacro
  1183                              <1> 	%imacro jnb 1.nolist
  1184                              <1> 	%? %1
  1185                              <1> checksection %1, %?, jcc
  1186                              <1> 	%endmacro
  1187                              <1> 	%imacro jbe 1.nolist
  1188                              <1> 	%? %1
  1189                              <1> checksection %1, %?, jcc
  1190                              <1> 	%endmacro
  1191                              <1> 	%imacro jnbe 1.nolist
  1192                              <1> 	%? %1
  1193                              <1> checksection %1, %?, jcc
  1194                              <1> 	%endmacro
  1195                              <1> 	%imacro jc 1.nolist
  1196                              <1> 	%? %1
  1197                              <1> checksection %1, %?, jcc
  1198                              <1> 	%endmacro
  1199                              <1> 	%imacro jnc 1.nolist
  1200                              <1> 	%? %1
  1201                              <1> checksection %1, %?, jcc
  1202                              <1> 	%endmacro
  1203                              <1> 	%imacro ja 1.nolist
  1204                              <1> 	%? %1
  1205                              <1> checksection %1, %?, jcc
  1206                              <1> 	%endmacro
  1207                              <1> 	%imacro jna 1.nolist
  1208                              <1> 	%? %1
  1209                              <1> checksection %1, %?, jcc
  1210                              <1> 	%endmacro
  1211                              <1> 	%imacro jae 1.nolist
  1212                              <1> 	%? %1
  1213                              <1> checksection %1, %?, jcc
  1214                              <1> 	%endmacro
  1215                              <1> 	%imacro jnae 1.nolist
  1216                              <1> 	%? %1
  1217                              <1> checksection %1, %?, jcc
  1218                              <1> 	%endmacro
  1219                              <1> 
  1220                              <1> 	%imacro jl 1.nolist
  1221                              <1> 	%? %1
  1222                              <1> checksection %1, %?, jcc
  1223                              <1> 	%endmacro
  1224                              <1> 	%imacro jnl 1.nolist
  1225                              <1> 	%? %1
  1226                              <1> checksection %1, %?, jcc
  1227                              <1> 	%endmacro
  1228                              <1> 	%imacro jle 1.nolist
  1229                              <1> 	%? %1
  1230                              <1> checksection %1, %?, jcc
  1231                              <1> 	%endmacro
  1232                              <1> 	%imacro jnle 1.nolist
  1233                              <1> 	%? %1
  1234                              <1> checksection %1, %?, jcc
  1235                              <1> 	%endmacro
  1236                              <1> 	%imacro jg 1.nolist
  1237                              <1> 	%? %1
  1238                              <1> checksection %1, %?, jcc
  1239                              <1> 	%endmacro
  1240                              <1> 	%imacro jng 1.nolist
  1241                              <1> 	%? %1
  1242                              <1> checksection %1, %?, jcc
  1243                              <1> 	%endmacro
  1244                              <1> 	%imacro jge 1.nolist
  1245                              <1> 	%? %1
  1246                              <1> checksection %1, %?, jcc
  1247                              <1> 	%endmacro
  1248                              <1> 	%imacro jnge 1.nolist
  1249                              <1> 	%? %1
  1250                              <1> checksection %1, %?, jcc
  1251                              <1> 	%endmacro
  1252                              <1> 
  1253                              <1> 	%imacro jo 1.nolist
  1254                              <1> 	%? %1
  1255                              <1> checksection %1, %?, jcc
  1256                              <1> 	%endmacro
  1257                              <1> 	%imacro jno 1.nolist
  1258                              <1> 	%? %1
  1259                              <1> checksection %1, %?, jcc
  1260                              <1> 	%endmacro
  1261                              <1> 	%imacro jp 1.nolist
  1262                              <1> 	%? %1
  1263                              <1> checksection %1, %?, jcc
  1264                              <1> 	%endmacro
  1265                              <1> 	%imacro jnp 1.nolist
  1266                              <1> 	%? %1
  1267                              <1> checksection %1, %?, jcc
  1268                              <1> 	%endmacro
  1269                              <1> 	%imacro jpe 1.nolist
  1270                              <1> 	%? %1
  1271                              <1> checksection %1, %?, jcc
  1272                              <1> 	%endmacro
  1273                              <1> 	%imacro jnpe 1.nolist
  1274                              <1> 	%? %1
  1275                              <1> checksection %1, %?, jcc
  1276                              <1> 	%endmacro
  1277                              <1> 	%imacro jpo 1.nolist
  1278                              <1> 	%? %1
  1279                              <1> checksection %1, %?, jcc
  1280                              <1> 	%endmacro
  1281                              <1> 	%imacro jnpo 1.nolist
  1282                              <1> 	%? %1
  1283                              <1> checksection %1, %?, jcc
  1284                              <1> 	%endmacro
  1285                              <1> 	%imacro js 1.nolist
  1286                              <1> 	%? %1
  1287                              <1> checksection %1, %?, jcc
  1288                              <1> 	%endmacro
  1289                              <1> 	%imacro jns 1.nolist
  1290                              <1> 	%? %1
  1291                              <1> checksection %1, %?, jcc
  1292                              <1> 	%endmacro
  1293                              <1> 
  1294                              <1> 	%imacro jcxz 1.nolist
  1295                              <1> 	%? %1
  1296                              <1> checksection %1, %?, jcc
  1297                              <1> 	%endmacro
  1298                              <1> 	%imacro jecxz 1.nolist
  1299                              <1> 	%? %1
  1300                              <1> checksection %1, %?, jcc
  1301                              <1> 	%endmacro
  1302                              <1> 	%imacro loop 1.nolist
  1303                              <1> 	%? %1
  1304                              <1> checksection %1, %?, jcc
  1305                              <1> 	%endmacro
  1306                              <1> 	%imacro loopz 1.nolist
  1307                              <1> 	%? %1
  1308                              <1> checksection %1, %?, jcc
  1309                              <1> 	%endmacro
  1310                              <1> 	%imacro loopnz 1.nolist
  1311                              <1> 	%? %1
  1312                              <1> checksection %1, %?, jcc
  1313                              <1> 	%endmacro
  1314                              <1> 	%imacro loope 1.nolist
  1315                              <1> 	%? %1
  1316                              <1> checksection %1, %?, jcc
  1317                              <1> 	%endmacro
  1318                              <1> 	%imacro loopne 1.nolist
  1319                              <1> 	%? %1
  1320                              <1> checksection %1, %?, jcc
  1321                              <1> 	%endmacro
  1322                              <1> %endif
  1323                              <1> 
  1324                              <1> 	%imacro checksection 3.nolist
  1325                              <1> %push
  1326                              <1>  %defstr %$string %1
  1327                              <1>  %substr %$shortword %$string 1, 5
  1328                              <1>  %substr %$shortsep %$string 6, 1
  1329                              <1>  %substr %$nearword %$string 1, 4
  1330                              <1>  %substr %$nearsep %$string 5, 1
  1331                              <1>  %substr %$farword %$string 1, 3
  1332                              <1>  %substr %$farsep %$string 4, 1
  1333                              <1>  %assign %$isshort 0
  1334                              <1>  %ifidni %$shortword, "short"
  1335                              <1>   %if %$shortsep == 32 || %$shortsep == 9
  1336                              <1>    %assign %$isshort 1
  1337                              <1>    %substr %$string %$string 7, -1
  1338                              <1>   %elif %$shortsep == '['
  1339                              <1>    %assign %$isshort 1
  1340                              <1>    %substr %$string %$string 6, -1
  1341                              <1>   %endif
  1342                              <1>  %endif
  1343                              <1>  %assign %$isnear 0
  1344                              <1>  %ifidni %$nearword, "near"
  1345                              <1>   %if %$nearsep == 32 || %$nearsep == 9
  1346                              <1>    %assign %$isnear 1
  1347                              <1>    %substr %$string %$string 6, -1
  1348                              <1>   %elif %$nearsep == '['
  1349                              <1>    %assign %$isnear 1
  1350                              <1>    %substr %$string %$string 5, -1
  1351                              <1>   %endif
  1352                              <1>  %endif
  1353                              <1>  %assign %$isfar 0
  1354                              <1>  %ifidni %$farword, "far"
  1355                              <1>   %if %$farsep == 32 || %$farsep == 9
  1356                              <1>    %assign %$isfar 1
  1357                              <1>    %substr %$string %$string 5, -1
  1358                              <1>   %elif %$farsep == '['
  1359                              <1>    %assign %$isfar 1
  1360                              <1>    %substr %$string %$string 4, -1
  1361                              <1>   %endif
  1362                              <1>  %endif
  1363                              <1> 
  1364                              <1>  %deftok %$token %$string
  1365                              <1> 
  1366                              <1>  %assign %$size 2
  1367                              <1>  %assign %$isreg 0
  1368                              <1>  %assign %$exit 0
  1369                              <1>  %rep 2
  1370                              <1>   %ifn %$exit
  1371                              <1>    %if %$size == 2
  1372                              <1>     %define %$regnames "ax  cx  dx  bx  sp  bp  si  di  "
  1373                              <1>    %elif %$size == 4
  1374                              <1>     %define %$regnames "eax ecx edx ebx esp ebp esi edi "
  1375                              <1>    %endif
  1376                              <1>    %assign %$index 0
  1377                              <1>    %rep 8
  1378                              <1>     %ifn %$exit
  1379                              <1>      %substr %$reg %$regnames %$index * 4 + 1, 4
  1380                              <1>      %deftok %$reg %$reg
  1381                              <1>      %ifnempty %$reg
  1382                              <1>       %ifidni %$reg, %$token
  1383                              <1>        %assign %$isreg %$size
  1384                              <1>        %assign %$exit 1
  1385                              <1>        %exitrep
  1386                              <1>       %endif
  1387                              <1>      %endif
  1388                              <1>     %endif
  1389                              <1>     %assign %$index %$index + 1
  1390                              <1>    %endrep
  1391                              <1>    %if %$exit
  1392                              <1>     %exitrep
  1393                              <1>    %endif
  1394                              <1>    %assign %$size %$size * 2
  1395                              <1>   %endif
  1396                              <1>  %endrep
  1397                              <1> 
  1398                              <1>  %assign %$ismulti 0
  1399                              <1>  %assign %$ismem 0
  1400                              <1>  %strlen %$length %$string
  1401                              <1>  %assign %$ii 0
  1402                              <1>  %rep %$length
  1403                              <1>   %substr %$point %$string %$ii + 1, 1
  1404                              <1>   %if %$point == 32 || %$point == 9
  1405                              <1>    %assign %$ismulti 1
  1406                              <1>   %endif
  1407                              <1>   %ifidn %$point, '['
  1408                              <1>    %assign %$ismem 1
  1409                              <1>   %endif
  1410                              <1>   %assign %$ii %$ii + 1
  1411                              <1>  %endrep
  1412                              <1> 
  1413                              <1>  %assign %$islocal 0
  1414                              <1>  %substr %$point %$string 1, 1
  1415                              <1>  %substr %$prefix %$string 1, 3
  1416                              <1>  %ifidn %$point, '.'
  1417                              <1>   %ifnidn %$prefix, '..@'
  1418                              <1>    %assign %$islocal 1
  1419                              <1>   %endif
  1420                              <1>  %endif
  1421                              <1> 
  1422                              <1>  %if %$isreg
  1423                              <1>   %if %$isreg == 4
  1424                              <1>    %warning 32-bit reg %3: %2 %1
  1425                              <1>   %else
  1426                              <1>    %warning 16-bit reg %3: %2 %1
  1427                              <1>   %endif
  1428                              <1>  %elif %$ismulti || %$ismem
  1429                              <1>   %warning not single %3: %2 %1
  1430                              <1>  %elif %$islocal
  1431                              <1>   %ifidni %3, call
  1432                              <1>    %warning local %3: %2 %1
  1433                              <1>   %endif
  1434                              <1>  %elifdef SECTION_OF_%[%$token]
  1435                              <1>   %ifnidni SECTION_OF_%[%$token], _CURRENT_SECTION
  1436                              <1>    %error Symbol %$token called wrongly: section_of=SECTION_OF_%[%$token], current=_CURRENT_SECTION
  1437                              <1>   %endif
  1438                              <1>  %endif
  1439                              <1> %pop
  1440                              <1> 	%endmacro
  1441                              <1> 
  1442                              <1> 
  1443                              <1> 	struc MEMREF
  1444 00000000 ????????            <1> mrLinear:		resd 1
  1445 00000004 ????????            <1> mrOffset:		resd 1
  1446 00000008 ????                <1> mrSegmentSelector:	resw 1
  1447 0000000A ????                <1> mrFlags:		resw 1
  1448 0000000C ????????            <1> mrLength:		resd 1
  1449                              <1> 	endstruc
  1450                              <1> 
  1451                              <1> 		; Currently only direct branches are allowed when
  1452                              <1> 		;  disassembling from the U command. (That is,
  1453                              <1> 		;  [disflags] & DIS_F_SHOW is clear.) All other
  1454                              <1> 		;  types of references depend on segment registers
  1455                              <1> 		;  and sometimes base and index registers, which are
  1456                              <1> 		;  not known ahead of time. They are only known for
  1457                              <1> 		;  the R command's disassembly. (DIS_F_SHOW set.)
  1458                              <1> 		; (When a mov ss or pop to ss will change ss, a
  1459                              <1> 		;  subsequent instruction using ss will not be
  1460                              <1> 		;  disassembled with the correct ss value.
  1461                              <1> 		;  This should be rare though. We may at a later
  1462                              <1> 		;  point detect this condition and not display
  1463                              <1> 		;  references with ss then.)
  1464                              <1> mrfBranchDirect:	equ    1
  1465                              <1> mrfMem:			equ    2
  1466                              <1> mrfMemSource:		equ    4
  1467                              <1> mrfMemDest:		equ    8
  1468                              <1> mrfA32:			equ   10h
  1469                              <1> mrfString:		equ   20h
  1470                              <1> mrfStringSource:	equ   40h
  1471                              <1> mrfStringDest:		equ   80h
  1472                              <1> mrfUsesSS:		equ  100h
  1473                              <1> mrfBranchIndirect:	equ  200h
  1474                              <1> 
  1475                              <1> 
  1476                              <1> %if _VXCHG && ! _VXCHGBIOS
  1477                              <1> 	struc XMSM
  1478 00000000 ????????            <1> .size_:		resd 1
  1479 00000004 ????                <1> .srchdl:	resw 1
  1480 00000006 ????????            <1> .srcadr:	resd 1
  1481 0000000A ????                <1> .dsthdl:	resw 1
  1482 0000000C ????????            <1> .dstadr:	resd 1
  1483                              <1> 	endstruc
  1484                              <1> %endif
  1485                              <1> 
  1486                              <1> 
  1487                              <1> 	; doscall is used by symbols.asm and run.asm and in
  1488                              <1> 	;  cmd3_close_handle, so define it prior
  1489                              <1> %if _PM && _NOEXTENDER
  1490                              <1> %macro doscall 0
  1491                              <1> 	nearcall _doscall
  1492                              <1> %endmacro
  1493                              <1> %else
  1494                              <1> 		; When we don't support non-extended DPMI all Int21 calls
  1495                              <1> 		; are either in Real Mode or extended (all are real Int21
  1496                              <1> 		; instructions).
  1497                              <1> %macro doscall 0
  1498                              <1> 	int 21h
  1499                              <1> %endmacro
  1500                              <1> %endif
  1501                              <1> 
  1502                              <1> 
  1503                              <1> %if _LINK
  1504                              <1> %imacro wlcalc 1-2.nolist
  1505                              <1> %deftok %%filenametoken __FILE__
  1506                              <1>  global wlcalc_%1?%[%%l]%[%%filenametoken]
  1507                              <1> wlcalc_%1?%[%%l]%[%%filenametoken]: %2
  1508                              <1> %endmacro
  1509                              <1> %endif
  1510                              <1> 
  1511                              <1> %if _BOOTLDR && _LINK
  1512                              <1> %macro lot_equate 2.nolist
  1513                              <1> LOAD_%2 equ %1
  1514                              <1> %endmacro
  1515                              <1> 
  1516                              <1> 	lot_equate    1, SET_DL_UNIT
  1517                              <1> 	lot_equate    2, SET_BL_UNIT
  1518                              <1> 	lot_equate    4, SET_SIDI_CLUSTER
  1519                              <1> 	lot_equate  10h, SET_DSSI_DPT
  1520                              <1> 	lot_equate  20h, PUSH_DPT
  1521                              <1> 	lot_equate  40h, DATASTART_HIDDEN
  1522                              <1> 	lot_equate  80h, SET_AXBX_DATASTART
  1523                              <1> 	lot_equate 100h, SET_DSBP_BPB
  1524                              <1> 	lot_equate 200h, LBA_SET_TYPE
  1525                              <1> 	lot_equate 400h, MESSAGE_TABLE
  1526                              <1> 	lot_equate 800h, SET_AXBX_ROOT_HIDDEN
  1527                              <1> 	lot_equate 1000h, CMDLINE
  1528                              <1> 	lot_equate 2000h, NO_BPB
  1529                              <1> 	lot_equate 4000h, SET_DSSI_PARTINFO
  1530                              <1> %endif
  1531                              <1> 
  1532                              <1> %if _HELP_COMPRESSED
  1533                              <1>  %assign NONCOMPRESSEDFLAG 1
  1534                              <1> %else
  1535                              <1>  %assign NONCOMPRESSEDFLAG 0
  1536                              <1> %endif
  1537                              <1> 
  1538                              <1> [list +]
  1539                              <1> 
  1540                              <1> %if _LINK
  1541                              <1>  %if _ONLY386
  1542                              <1> 	cpu 386
  1543                              <1>  %else
  1544                              <1> 	cpu 8086
  1545                              <1>  %endif
  1546                              <1> 
  1547                              <1> auxbuff_size: equ (_AUXBUFFSIZE+15) & ~15
  1548                              <1> 	endarea auxbuff, 1
  1549                              <1> 
  1550                              <1> auxbuff_max_size: equ (_AUXBUFFMAXSIZE+15) & ~15
  1551                              <1> 	endarea auxbuff_max, 1
  1552                              <1> 
  1553                              <1> %if _INIT_MAX
  1554                              <1>  auxbuff_init_size: equ (_AUXBUFFMAXSIZE+15) & ~15
  1555                              <1> %else
  1556                              <1>  auxbuff_init_size: equ (_AUXBUFFSIZE+15) & ~15
  1557                              <1> %endif
  1558                              <1> 	endarea auxbuff_init, 1
  1559                              <1> 
  1560                              <1>  %include "options.mac"
     1                              <2> 
     2                              <2> %if 0
     3                              <2> 
     4                              <2> lDebug options and internal flags
     5                              <2> 
     6                              <2> Copyright (C) 2008-2025 E. C. Masloch
     7                              <2> 
     8                              <2> Usage of the works is permitted provided that this
     9                              <2> instrument is retained with the works, so that any entity
    10                              <2> that uses the works is notified of this instrument.
    11                              <2> 
    12                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    13                              <2> 
    14                              <2> %endif
    15                              <2> 
    16                              <2> 
    17                              <2> dispregs32	equ	  1	; RX: 32-bit register display (R, T/P/G)
    18                              <2> traceints	equ	  2	; TM: trace into interrupts (T)
    19                              <2> cpdepchars	equ	  4	; allow dumping of CP-dependent characters (D, DX)
    20                              <2> fakeindos	equ	  8	; always assume InDOS flag non-zero (all)
    21                              <2> nonpagingdevice	equ	 10h	; disallow paged output with [more] prompt (all exc. P, T)
    22                              <2> 	; This option was never used anywhere:
    23                              <2> ; pagingdevice	equ	 20h	; allow paged output with [more] prompt (all exc. P, T)
    24                              <2> 				; paged output is by default on if the output device is StdOut, else off
    25                              <2> hexrn		equ	 40h	; display raw hexadecimal content of FPU registers (RN)
    26                              <2> ;novdd		equ	 80h	; don't use a registered NTVDM VDD (L, W)
    27                              <2> nondospaging	equ	100h	; paging: don't use DOS for input when waiting for a key
    28                              <2> opt1_86mnohlt	equ	200h	; (86 Mode:) HLT doesn't work, don't use it
    29                              <2> biosidles	equ	400h	; don't idle with HLT or Int2F.1680, only call BIOS Int16.00
    30                              <2> opt_usegetinput	equ	800h	; use getinput for int 21h interactive input
    31                              <2> use_si_units	equ    1000h	; in disp_*_size use SI units (kB = 1000, etc)
    32                              <2> use_jedec_units	equ    2000h	; in disp_*_size use JEDEC units (kB = 1024)
    33                              <2> enable_serial	equ    4000h	; enable serial I/O (preferred over DOS or BIOS terminal)
    34                              <2> int8_disable_serial equ	   8000h	; disable serial I/O when breaking due to intr8
    35                              <2> gg_do_not_skip_bp equ	 1_0000h	; gg: do not skip a breakpoint (bb or gg)
    36                              <2> gg_no_autorepeat equ	 2_0000h	; gg: do not auto-repeat
    37                              <2> tp_do_not_skip_bp equ	 4_0000h	; T/TP/P: do not skip a (bb) breakpoint
    38                              <2> gg_bb_hit_no_repeat equ	 8_0000h	; gg: do not auto-repeat after bb hit
    39                              <2> tp_bb_hit_no_repeat equ	10_0000h	; T/TP/P: do not auto-repeat after bb hit
    40                              <2> gg_unexpected_no_repeat equ 20_0000h	; gg: do not auto-repeat after unexpectedinterrupt
    41                              <2> tp_unexpected_no_repeat equ 40_0000h	; T/TP/P
    42                              <2> ss_no_dump:		equ 80_0000h
    43                              <2> %if _SYMBOLIC
    44                              <2> dd_no_blanks_sym:	equ 100_0000h
    45                              <2> zz_no_pm_xms:		equ 200_0000h
    46                              <2> %endif
    47                              <2> rr_disasm_no_rept:	equ 1000_0000h
    48                              <2> rr_disasm_no_show:	equ 2000_0000h
    49                              <2> opt_cmdline_quiet_input:equ 4000_0000h
    50                              <2> opt_cmdline_quiet_output:equ 8000_0000h
    51                              <2> %if _SYMBOLIC
    52                              <2> DEFAULTOPTIONS	equ zz_no_pm_xms
    53                              <2> %else
    54                              <2> DEFAULTOPTIONS	equ 0
    55                              <2> %endif
    56                              <2> 
    57                              <2> 
    58                              <2> opt2_db_header:		equ 1
    59                              <2> opt2_db_trailer:	equ 2
    60                              <2> opt2_dw_header:		equ 10h
    61                              <2> opt2_dw_trailer:	equ 20h
    62                              <2> opt2_dd_header:		equ 100h
    63                              <2> opt2_dd_trailer:	equ 200h
    64                              <2> opt2_getinput_dpmi:	equ 800h
    65                              <2> opt2_hh_compat:		equ 1000h
    66                              <2> opt2_getc_idle:		equ 2000h
    67                              <2> opt2_getc_idle_dpmi:	equ 4000h
    68                              <2> opt2_re_cancel_tpg:	equ 8000h
    69                              <2> opt2_nn_compat:		equ 1_0000h
    70                              <2> opt2_nn_capitalise:	equ 2_0000h
    71                              <2> %if _MS_0RANGE_COMPAT
    72                              <2> opt2_0range_compat:	equ 4_0000h
    73                              <2> %endif
    74                              <2> opt2_rr16_compat:	equ 8_0000h
    75                              <2> opt2_r_prompt_compat:	equ 10_0000h
    76                              <2> opt2_r_separate:	equ 20_0000h
    77                              <2> opt2_r_linebreak_always:equ 40_0000h
    78                              <2> opt2_dpminohlt:		equ 8000_0000h	; DPMI doesn't like hlt
    79                              <2> DEFAULTOPTIONS2	equ opt2_dw_header | opt2_dd_header | opt2_getc_idle_dpmi | opt2_dpminohlt
    80                              <2> 
    81                              <2> 
    82                              <2> opt3_tt_no_paging:	equ 1
    83                              <2> opt3_tp_no_paging:	equ 2
    84                              <2> opt3_pp_no_paging:	equ 4
    85                              <2> opt3_gg_no_paging:	equ 8
    86                              <2> opt3_silence_paging_set:equ 100h
    87                              <2> opt3_silence_paging_on:	equ 200h
    88                              <2> opt3_paging_rc:		equ 1000h
    89                              <2> opt3_paging_yy:		equ 2000h
    90                              <2> opt3_paging_re:		equ 4000h
    91                              <2> opt3_r_highlight_diff:	equ 10000h
    92                              <2> opt3_r_highlight_dumb:	equ 20000h
    93                              <2> opt3_r_highlight_full:	equ 40000h
    94                              <2> opt3_r_highlight_eip:	equ 80000h
    95                              <2> %if _PM
    96                              <2> opt3_ss_b_bit_set:	equ   10_0000h
    97                              <2>  %if _BREAK_INSTALLDPMI
    98                              <2> opt3_break_installdpmi:	equ   20_0000h
    99                              <2>  %endif
   100                              <2> %endif
   101                              <2> %if _DHIGHLIGHT
   102                              <2> opt3_d_highlight:	equ   80_0000h
   103                              <2> %endif
   104                              <2> %if _GETLINEHIGHLIGHT
   105                              <2> opt3_getline_highlight:	equ  100_0000h
   106                              <2> %endif
   107                              <2> opt3_no_idle_2F:	equ  200_0000h
   108                              <2> %if _DELAY_BEFORE_BP
   109                              <2> opt3_delay_before_bp:	equ  400_0000h
   110                              <2> %endif
   111                              <2> opt3_no_call_amis:	equ  800_0000h
   112                              <2> opt3_disable_autorepeat:equ 1000_0000h
   113                              <2> opt3_check_ctrlc_keyb:	equ 2000_0000h
   114                              <2> opt3_check_ctrlc_0bh:	equ 4000_0000h
   115                              <2> opt3_tsr_quit_leave_tf:	equ 8000_0000h
   116                              <2> DEFAULTOPTIONS3	equ opt3_tt_no_paging | opt3_tp_no_paging 		| opt3_pp_no_paging | opt3_gg_no_paging 		| opt3_check_ctrlc_keyb | opt3_check_ctrlc_0bh
   119                              <2> 
   120                              <2> 
   121                              <2> opt4_int_2F_hook:	equ 2
   122                              <2> opt4_int_08_hook:	equ 4
   123                              <2> opt4_int_2D_hook:	equ 8
   124                              <2> %if _CATCHINTFAULTCOND
   125                              <2> opt4_int_fault_hook:	equ 10h
   126                              <2> %endif
   127                              <2> opt4_int_serial_force:	equ 1_0000h
   128                              <2> opt4_int_2F_force:	equ 2_0000h
   129                              <2> opt4_int_08_force:	equ 4_0000h
   130                              <2> opt4_int_2D_force:	equ 8_0000h
   131                              <2> %if _CATCHINT0D
   132                              <2> opt4_int_0D_force:	equ   10_0000h
   133                              <2> %endif
   134                              <2> %if _CATCHINT0C
   135                              <2> opt4_int_0C_force:	equ   20_0000h
   136                              <2> %endif
   137                              <2> opt4_int_00_force:	equ  100_0000h
   138                              <2> opt4_int_01_force:	equ  200_0000h
   139                              <2> opt4_int_03_force:	equ  400_0000h
   140                              <2> opt4_int_06_force:	equ  800_0000h
   141                              <2> opt4_int_18_force:	equ 1000_0000h
   142                              <2> opt4_int_19_force:	equ 2000_0000h
   143                              <2> opt4_int_09_force:	equ 4000_0000h	; not used at the same time as 15h
   144                              <2> opt4_int_15_force:	equ 4000_0000h	; not used at the same time as 09h
   145                              <2> opt4_int_07_force:	equ 8000_0000h
   146                              <2> DEFAULTOPTIONS4 equ opt4_int_2F_hook
   147                              <2> 
   148                              <2> 
   149                              <2> %if _VXCHG
   150                              <2> opt6_vv_mode:		equ 1
   151                              <2> opt6_vv_keep:		equ 2
   152                              <2> opt6_vv_int16:		equ 10h
   153                              <2>  %if _VXCHG_DEFAULT_ON
   154                              <2> DEFAULTOPTIONS6 equ opt6_share_serial_irq | opt6_vv_mode
   155                              <2>  %else
   156                              <2> DEFAULTOPTIONS6 equ opt6_share_serial_irq
   157                              <2>  %endif
   158                              <2> %else
   159                              <2> DEFAULTOPTIONS6 equ opt6_share_serial_irq
   160                              <2> %endif
   161                              <2> %if _DEBUG
   162                              <2> opt6_debug_exception_late:	equ  20h
   163                              <2> opt6_debug_exception_early:	equ  40h
   164                              <2>  %if _DEBUG_COND
   165                              <2> opt6_debug_exception:	equ  80h
   166                              <2> opt6_debug_mode:	equ 100h
   167                              <2>  %endif
   168                              <2> %endif
   169                              <2> opt6_bios_output:	equ 200h
   170                              <2> opt6_flat_binary:	equ 400h
   171                              <2> opt6_big_stack:		equ 800h
   172                              <2> opt6_40_columns:	equ 1000h
   173                              <2> opt6_40_indent_odd:	equ 2000h
   174                              <2> opt6_40_dash:		equ 4000h
   175                              <2> opt6_share_serial_irq:	equ 1_0000h
   176                              <2> opt6_serial_EOI_call:	equ 2_0000h
   177                              <2> %if _RH
   178                              <2> opt6_rh_mode:		equ 10_0000h
   179                              <2> %endif
   180                              <2> %if _DEBUG
   181                              <2> opt6_debug_putrunint_early:	equ  40_0000h
   182                              <2>  %if _DEBUG_COND
   183                              <2> opt6_debug_putrunint:		equ  80_0000h
   184                              <2>  %endif
   185                              <2> %endif
   186                              <2> opt6_bios_io:		equ 100_0000h
   187                              <2> opt6_immasm_display_uu:	equ 200_0000h
   188                              <2> opt6_immasm_debug:	equ 400_0000h
   189                              <2> opt6_immasm_flag:	equ 800_0000h
   190                              <2> opt6_immasm_nobranch:	equ 1000_0000h
   191                              <2> opt6_r_flags_style2:	equ 2000_0000h
   192                              <2> opt6_r_flags_style3:	equ 4000_0000h
   193                              <2> opt6_r_linebreak_conditional:	equ 8000_0000h
   194                              <2> 
   195                              <2> 
   196                              <2> DEFAULTOPTIONS7 equ opt7_no_tsr_ll
   197                              <2> opt7_no_free_oneshot_eld:	equ 1
   198                              <2> opt7_debug_optional_link:	equ 2
   199                              <2> opt7_quiet_install:		equ 4
   200                              <2> opt7_quick_run:			equ 8
   201                              <2> opt7_houdini:			equ 100h
   202                              <2> opt7_debug_run:			equ 200h
   203                              <2> opt7_no_ensure:			equ 1000h
   204                              <2> opt7_no_tsr_ll:			equ 2000h
   205                              <2> 
   206                              <2> 
   207                              <2> oldpacket	equ	  1	; Int25/Int26 packet method available (L, W)
   208                              <2> newpacket	equ	  2	; Int21.7305 packet method available (L, W)
   209                              <2> ntpacket	equ	  4	; VDD registered and usable (L, W)
   210                              <2> pagedcommand	equ	  8	; allows paging in puts
   211                              <2> notstdinput	equ	 10h	; DEBUG's StdIn isn't a device with StdIn bit (is file or other device)
   212                              <2> inputfile	equ	 20h	; DEBUG's StdIn is a file, notstdinput also set
   213                              <2> notstdoutput	equ	 40h	; DEBUG's StdOut isn't a device with StdOut bit (is file or other device)
   214                              <2> outputfile	equ	  80h	; DEBUG's StdOut is a file, notstdoutput also set
   215                              <2> hooked2F	equ	 100h	; Int2F hooked
   216                              <2> nohook2F	equ	 200h	; don't hook Int2F.1687 (required for Win9x, DosEmu?)
   217                              <2> unused_dif1_dpminohlt equ 400h	; DPMI doesn't like hlt
   218                              <2> protectedmode	equ	 800h	; in (DPMI) protected mode
   219                              <2> debuggeeA20	equ	1000h	; state of debuggee's A20
   220                              <2> debuggerA20	equ	2000h	; state of debugger's A20 (will be on if possible)
   221                              <2> nodosloaded	equ	4000h	; No DOS loaded currently (Boot loader mode)
   222                              <2> has386		equ	8000h	; CPU is a 386
   223                              <2> usecharcounter	equ    1_0000h	; don't reset charcounter between calls to puts
   224                              <2> runningnt	equ    2_0000h	; running in NTVDM
   225                              <2> canswitchmode	equ    4_0000h	; can switch modes (auxbuff large enough, DPMI mode switch set up)
   226                              <2> modeswitched	equ    8_0000h	; switched mode (now in the mode that we weren't entered in)
   227                              <2> promptwaiting	equ   10_0000h	; puts: any more output needs to display a prompt first
   228                              <2> switchbuffer	equ   20_0000h	; mode switch needs a buffer (auxbuff)
   229                              <2> tsrmode		equ   40_0000h	; in TSR mode; DPI and DPP not valid
   230                              <2> attachedterm	equ   80_0000h	; the attached process terminated
   231                              <2> runningdosemu	equ  100_0000h	; running in dosemu
   232                              <2> ; load_is_ldp	equ  200_0000h	; boot load: partition specified as "ldp"
   233                              <2> tt_while:	equ  400_0000h	; tt: while condition specified
   234                              <2> tt_p:		equ  800_0000h	; tt: proceed past repeated string instructions
   235                              <2> tt_silent_mode:	equ 1000_0000h	; tt: run should be silent (dump at end)
   236                              <2> tt_silence:	equ 2000_0000h	; tt: silent writing (write to auxbuff instead)
   237                              <2> tt_no_bb:	equ 4000_0000h	; tt: do not use bb breakpoints
   238                              <2> tt_no_bb_first:	equ 8000_0000h	; tt: do not use bb breakpoints at first
   239                              <2> 
   240                              <2> 
   241                              <2> dif2_gg_is_first:	equ   1
   242                              <2> dif2_gg_skip_non_cseip:	equ   2
   243                              <2> dif2_gg_skip_cseip:	equ   4
   244                              <2> dif2_gg_is_gg:		equ   8
   245                              <2> dif2_gg_first_detected:	equ  10h
   246                              <2> dif2_gg_again:		equ  20h
   247                              <2> dif2_tpg_proceed_bp_set:equ  40h
   248                              <2> dif2_tpg_keep_proceed_bp: equ 80h
   249                              <2> dif2_tpg_have_bp:	equ 100h
   250                              <2> dif2_tpg_adjusted_cseip:equ 200h
   251                              <2> dif2_tpg_do_not_adjust:	equ 400h
   252                              <2> dif2_bp_failure:	equ 800h
   253                              <2> dif2_is_pp:		equ 1000h
   254                              <2> %if _SYMBOLIC
   255                              <2> dif2_createdprocess:	equ 800_0000h	; created empty debuggee process
   256                              <2> dif2_sym_req_xms:	equ 2000h
   257                              <2> dif2_sym_req_86mm:	equ 4000h
   258                              <2> dif2_sym_req_mask equ dif2_sym_req_86mm | dif2_sym_req_xms
   259                              <2> dif2_no_pm_xms:		equ 1_0000h
   260                              <2> dif2_xms_detection_done:equ 2_0000h
   261                              <2> %endif
   262                              <2> %if _INPUT_FILE_HANDLES
   263                              <2> dif2_input_file:	equ 10_0000h
   264                              <2> dif2_closed_input_file:	equ 20_0000h
   265                              <2> %endif
   266                              <2> dif2_did_getline_file:	equ 40_0000h
   267                              <2> %if _SYMBOLIC
   268                              <2> dif2_poison:		equ 80_0000h
   269                              <2> %endif
   270                              <2> dif2_boot_loaded_kernel:equ 100_0000h
   271                              <2> %if _INPUT_FILE_BOOT
   272                              <2> dif2_input_file_boot:	equ 200_0000h
   273                              <2> dif2_closed_input_file_boot:	equ 400_0000h
   274                              <2> %endif
   275                              <2> dif2_in_silence_dump:	equ 1000_0000h
   276                              <2> dif2_int31_segment:	equ 2000_0000h
   277                              <2> dif2_nn_compat:		equ 4000_0000h
   278                              <2> dif2_nn_capitalise:	equ 8000_0000h
   279                              <2> 
   280                              <2> 
   281                              <2> dif3_load_is_ldp:	equ 1	; boot load: partition specified as "ldp"
   282                              <2> dif3_load_is_sdp:	equ 2	; boot load: partition specified as "sdp"
   283                              <2> dif3_load_is_ydp:	equ 4	; boot load: partition specified as "ydp"
   284                              <2> dif3_load_is_dp:	equ dif3_load_is_ldp 				| dif3_load_is_sdp 				| dif3_load_is_ydp
   287                              <2> dif3_load_dir_dir:	equ 8
   288                              <2> dif3_input_terminal_override:	equ 10h
   289                              <2> dif3_input_serial_override:	equ 20h
   290                              <2> dif3_if_not:		equ 40h
   291                              <2> dif3_partition_changed:	equ 80h
   292                              <2> ;
   293                              <2> dif3_input_cmdline:	equ 100h; input reading from cmdline_buffer
   294                              <2> dif3_input_cmdline_closed: equ 200h
   295                              <2> dif3_at_line_end:	equ 400h
   296                              <2> dif3_quiet_input_single:equ 800h
   297                              <2> dif3_quiet_output:	equ 1000h
   298                              <2> dif3_unquiet_error:	equ 2000h
   299                              <2> dif3_unquiet_prompt:	equ 4000h
   300                              <2> dif3_unquiet:		equ dif3_unquiet_error | dif3_unquiet_prompt
   301                              <2> dif3_return_eof:	equ 8000h
   302                              <2> dif3_highlighting:	equ 1_0000h
   303                              <2> dif3_do_not_highlight:	equ 2_0000h
   304                              <2> dif3_int10_highlight:	equ 2_0000h
   305                              <2> dif3_nosymbols_1:	equ 4_0000h
   306                              <2> dif3_nosymbols_2:	equ 8_0000h
   307                              <2> %if _PM
   308                              <2> dif3_ss_b_bit_set:	equ  10_0000h
   309                              <2> %endif
   310                              <2> dif3_gotint19:		equ  20_0000h
   311                              <2> dif3_prior_pm:		equ  40_0000h
   312                              <2> %if _DELAY_BEFORE_BP
   313                              <2> dif3_delayed		equ  80_0000h
   314                              <2> %endif
   315                              <2> dif3_input_re:		equ 100_0000h	; input reading from re_buffer
   316                              <2> dif3_input_re_closed:	equ 200_0000h
   317                              <2> dif3_accept_getrange_0:	equ 400_0000h
   318                              <2> %if _INPUT_FILE_HANDLES || _INPUT_FILE_BOOT
   319                              <2> dif3_in_if:		equ 800_0000h
   320                              <2> %endif
   321                              <2> dif3_auxbuff_guarded_1:	equ 1000_0000h
   322                              <2> dif3_auxbuff_guarded_2:	equ 2000_0000h
   323                              <2> dif3_auxbuff_guarded_3:	equ 4000_0000h
   324                              <2> dif3_sss_is_reverse:	equ 8000_0000h
   325                              <2> 
   326                              <2> 
   327                              <2> dif4_int_serial_hooked:	equ 1
   328                              <2> dif4_int_2F_hooked:	equ 2
   329                              <2> dif4_int_08_hooked:	equ 4
   330                              <2> dif4_int_2D_hooked:	equ 8
   331                              <2> %if _CATCHINTFAULTCOND && _CATCHINT0D
   332                              <2> dif4_int_0D_hooked:	equ 10h
   333                              <2> %endif
   334                              <2> %if _CATCHINTFAULTCOND && _CATCHINT0C
   335                              <2> dif4_int_0C_hooked:	equ 20h
   336                              <2> %endif
   337                              <2> %if _LOADER
   338                              <2> dif4_int_18_hooked:	equ 1000h
   339                              <2> dif4_int_19_hooked:	equ 2000h
   340                              <2> %endif
   341                              <2> 
   342                              <2> 
   343                              <2> %if _VXCHG
   344                              <2> dif6_vv_mode:		equ 1
   345                              <2> %endif
   346                              <2> dif6_in_hook2F:		equ 2
   347                              <2> dif6_in_amis_hook2F:	equ 4
   348                              <2> dif6_debug_mode:	equ 100h
   349                              <2> dif6_locked:		equ 200h
   350                              <2> dif6_mcp:		equ 400h
   351                              <2> %if _RH
   352                              <2> dif6_rh_mode_was:	equ  8_0000h
   353                              <2> dif6_rh_mode:		equ 10_0000h
   354                              <2> dif6_rh_mode_2:		equ 20_0000h
   355                              <2> %endif
   356                              <2> dif6_device_mode:	equ 40_0000h
   357                              <2> dif6_cpdepchars:	equ 80_0000h
   358                              <2> %if _IMMASM
   359                              <2> dif6_immasm_no_output:	equ 100_0000h
   360                              <2> dif6_immasm:		equ 200_0000h
   361                              <2> dif6_immasm_rel8:	equ 400_0000h
   362                              <2> %endif
   363                              <2> 
   364                              <2> 
   365                              <2> disasm_lowercase	equ 1
   366                              <2> disasm_commablank	equ 2
   367                              <2> disasm_nasm		equ 4
   368                              <2> disasm_lowercase_refmem:equ 8
   369                              <2> disasm_show_short:	equ 10h
   370                              <2> disasm_show_near:	equ 20h
   371                              <2> disasm_show_far:	equ 40h
   372                              <2> disasm_nec:		equ 80h
   373                              <2> disasm_40_columns:	equ 100h
   374                              <2> disasm_no_indent:	equ 200h
   375                              <2> disasm_msdebug_mnemonofs: equ 400h
   376                              <2> disasm_a16_memref:	equ 1000h
   377                              <2> disasm_a32_memref:	equ 2000h
   378                              <2> disasm_a16_string:	equ 4000h
   379                              <2> disasm_a32_string:	equ 8000h
   380                              <2> disasm_hide_modrm:	equ 10000h
   381                              <2> disasm_asize_loop_nasm:	equ 20000h
   382                              <2> disasm_modrm_always:	equ 40000h
   383                              <2> DEFAULTASMOPTIONS equ disasm_lowercase|disasm_commablank|disasm_nasm 	| disasm_a16_memref | disasm_a32_memref 	| disasm_a16_string | disasm_a32_string
   386                              <2> 
   387                              <2> 	; serial_flags values
   388                              <2> sf_init_done:	equ 1
   389                              <2> sf_ctrl_c:	equ 2
   390                              <2> sf_double_ctrl_c:	equ 4
   391                              <2> sf_built_in_fifo:	equ 8
   392                              <2> sf_use_serial:		equ 10h
  1561                              <1> %endif
    20                                  %endif
    21                                  
    22                                  %if _LINK_COMPAT
    23                                  	usesection lDEBUG_DATA_ENTRY
    23          ------------------       note: usesection lDEBUG_DATA_ENTRY
    24                                  	align 4, db 0
    25                                  %endif
    26                                  
    27                                  
    28                                  %if _EXPRDUALCODE && _DUALCODE
    29                                  	usesection lDEBUG_CODE2
    29          ------------------       note: usesection lDEBUG_CODE2
    30                                  
    31 00000000 E8(0000)EB02[0000]      error_expr:	nearcall error
    32                                  
    33                                   %if _DEBUG4 || _DEBUG5
    34                                    %define _DEB_ASM_PREFIX expr_
    35                                    %include "deb.asm"
    36                                   %endif
    37                                  
    38                                  %else
    39                                  	usesection lDEBUG_CODE
    40                                  
    41                                  %ifn _LINK
    42                                  error_expr: equ error
    43                                  %endif
    44                                  
    45                                   %if _DEBUG4 || _DEBUG5
    46                                  expr_d4message equ d4message
    47                                   %endif
    48                                  %endif
    49                                  
    50                                  %xdefine _EXPR_SECTION _CURRENT_SECTION
    51                                  
    52                                  
    53                                  ;--- get a valid offset for segment in BX
    54                                  
    55                                  		; INP:	bx = segment
    56                                  		;	al = first character, si -> next character
    57                                  		;	ah = 1 if might be a segment or pointer
    58                                  		;	ah = 0 if must be an offset
    59                                  		; OUT:	CY if pointer type return, bx:dx = pointer
    60                                  		;	DebugX on a 386:
    61                                  		;	 edx = offset (even if 16-bit PM/86M segment)
    62                                  		;	 ah = 1 if a 32-bit segment, 0 if a 16-bit segment
    63                                  		;	DebugX otherwise:
    64                                  		;	 dx = offset
    65                                  		;	 ah = 0
    66                                  		;	Debug:
    67                                  		;	 dx = offset
    68                                  		;	al, si refer to next part of command line
    69                                  		; CHG:	Debug: ah, DebugX: -
    70                                  		; REM:	The byte [bAddr32] is no longer changed by this
    71                                  		;	 function. The caller has to use the status that
    72                                  		;	 is returned in ah, if desired.
    73                                  		; REM:	It is expected that INP:bx is a selector in PM,
    74                                  		;	 however it may be a segment or arbitrary value
    75                                  		;	 as well. In this case a 32-bit offset input may
    76                                  		;	 be rejected or accepted by this function.
    77                                  getofsforbx: section_of_function
    78 00000007 51                      	push cx			; preserve
    79 00000008 53                      	push bx			; preserve
    80 00000009 88E5                    	mov ch, ah		; ch = 0 if must be an offset
    81                                  %if _PM
    82 0000000B 6631D2                  _386	xor edx, edx		; properly initialize high word
    83 0000000E E8(0000)EB02[0000]      	nearcall test_high_limit
    84 00000015 740E                    	jz .16			; 16-bit segment -->
    85                                  [cpu 386]
    86 00000017 E8310F                  	nearcall getdword
    87 0000001A 53                      	 push bx
    88 0000001B 52                      	 push dx
    89 0000001C 665A                    	 pop edx		; edx = 32-bit offset
    90 0000001E E81300                  	nearcall checkpointer
    91 00000021 B401                    	mov ah, 1		; return 32-bit offset flag
    92 00000023 EB0B                    	jmp .ret_pop_NC
    93                                  __CPU__
    94                                  %endif
    95                                  
    96                                  .16:
    97 00000025 E8230F                  	nearcall getexpression
    98 00000028 E80900                  	nearcall checkpointer
    99 0000002B E80B15                  	nearcall getword.checksignificantbits
   100                                  %if _PM
   101 0000002E B400                    	mov ah, 0		; return 16-bit offset flag
   102                                  %endif
   103                                  .ret_pop_NC:
   104 00000030 5B                      	pop bx
   105 00000031 59                      	pop cx			; restore
   106 00000032 F8                      	clc			; NC: not a pointer type
   107 00000033 C3                      	retn
   108                                  
   109                                  		; Internal function for getofsforbx
   110                                  		;
   111                                  		; INP:	ah = return from getexpression
   112                                  		;	 (flag 80h = pointer type expression)
   113                                  		;	ch = 0 if must be an offset, 1 if may be pointer/segment
   114                                  		;	bx:dx = return from getexpression
   115                                  		;	ss:sp -> near return address (checkpointer),
   116                                  		;		bx restore,
   117                                  		;		cx restore,
   118                                  		;		near return address (getofsforbx)
   119                                  		; OUT:	returns near if not a pointer type expression
   120                                  		;	returns to caller of getofsforbx if pointer type expr,
   121                                  		;	 CY
   122                                  		;	 bx:dx = expression
   123                                  		;	 DebugX on a 386: edxh = 0
   124                                  		;	 DebugX: ah = 0
   125                                  		;	 cx = restored from stack
   126                                  checkpointer: section_of_function
   127 00000034 84E4                    	test ah, ah		; pointer type ?
   128 00000036 790E                    	jns .ret		; no -->
   129 00000038 84ED                    	test ch, ch		; can be a pointer or segment ?
   130 0000003A 7436                    	jz errorj10		; no -->
   131 0000003C 59                      	pop cx			; discard a near return address
   132 0000003D 59                      	pop cx			; discard bx
   133 0000003E 59                      	pop cx			; restore cx
   134                                  %if _PM
   135 0000003F 660FB7D2                _386	movzx edx, dx		; edx = dx
   136 00000043 B400                    	mov ah, 0		; always treat as 16-bit offset
   137                                  %endif
   138 00000045 F9                      	stc			; return a pointer type
   139                                  .ret:
   140                                  retn_expr:
   141 00000046 C3                      	retn
   142                                  
   143                                  
   144                                  ;	GETRANGE - Get address range from input line.
   145                                  ;    a range consists of either start and end address
   146                                  ;    or a start address, a 'L' and a length.
   147                                  ;	Entry	AL	First character of range
   148                                  ;		SI	Address of next character
   149                                  ;		BX	Default segment to use
   150                                  ;		CX	Default length to use (or 0 if not allowed)
   151                                  ;		di	Default length in lines if nonzero
   152                                  ;			 (only used for getrange.lines entrypoint
   153                                  ;			  and with word getrange_lines & 8000h set)
   154                                  ;			 must be <= 7FFFh
   155                                  ;	Exit	AL	First character beyond range
   156                                  ;		SI	Address of the character after that
   157                                  ;		BX:(E)DX	First address in range
   158                                  ;		BX:(E)CX	Last address in range
   159                                  ;	Uses	AH
   160                                  
   161                                  %if _PM
   162                                  getrangeX: section_of_function
   163 00000047 8326[0000]00            	and word [getrange_lines], 0
   164                                  .lines: section_of_function getrangeX
   165                                   %if _MS_0RANGE_COMPAT
   166                                  %if !_LOADER
   167 0000004C C606[0000]00            	mov byte [getrange_is_uu], 0
   168                                  %endif
   169                                  .lines_and_uu: section_of_function getrangeX
   170                                   %endif
   171 00000051 8026[0300]FB            	clropt [internalflags3], dif3_accept_getrange_0
   172 00000056 660FB7C9                _386	movzx ecx, cx
   173                                  .ecx_and_0_valid: section_of_function getrangeX
   174 0000005A 66                      	_386_PM_o32
   175 0000005B 51                      	push cx
   176 0000005C E82C01                  	nearcall getaddrX
   177 0000005F EB2B                    	jmp short getrange.common
   178                                  %else
   179                                  check_section_of getrangeX
   180                                  check_section_of getrangeX.lines
   181                                   %if _MS_0RANGE_COMPAT
   182                                  check_section_of getrangeX.lines_and_uu
   183                                   %endif
   184                                  check_section_of getrangeX.ecx_and_0_valid
   185                                  getrangeX: equ getrange
   186                                  getrangeX.lines: equ getrange.lines
   187                                   %if _MS_0RANGE_COMPAT
   188                                  getrangeX.lines_and_uu: equ getrange.lines_and_uu
   189                                   %endif
   190                                  getrangeX.ecx_and_0_valid: equ getrange.ecx_and_0_valid
   191                                  %endif
   192                                  
   193                                  getrangeX_have_address_need_length: section_of_function
   194 00000061 8326[0000]00            	and word [getrange_lines], 0
   195 00000066 8026[0300]FB            	clropt [internalflags3], dif3_accept_getrange_0
   196 0000006B 66                      	_386_PM_o32
   197 0000006C 31C9                    	xor cx, cx
   198 0000006E 66                      	_386_PM_o32
   199 0000006F 51                      	push cx			; save the default length
   200 00000070 EB1A                    	jmp getrange.common
   201                                  
   202                                  
   203 00000072 EB8C                    errorj10: jmp error_expr
   204                                  
   205                                  getrange: section_of_function
   206 00000074 8326[0000]00            	and word [getrange_lines], 0
   207                                  .lines: section_of_function getrange
   208                                  %if _MS_0RANGE_COMPAT
   209                                  %if !_LOADER
   210 00000079 C606[0000]00            	mov byte [getrange_is_uu], 0
   211                                  %endif
   212                                  .lines_and_uu: section_of_function getrange
   213                                  %endif
   214 0000007E 8026[0300]FB            	clropt [internalflags3], dif3_accept_getrange_0
   215 00000083 660FB7C9                _386_PM	movzx ecx, cx
   216                                  .ecx_and_0_valid: section_of_function getrange
   217 00000087 66                      	_386_PM_o32
   218 00000088 51                      	push cx			; save the default length
   219 00000089 E8F400                  	nearcall getaddr	; get address into bx:(e)dx (sets bAddr32) (returns edx)
   220                                  .common:
   221 0000008C 66                      	_386_PM_o32
   222 0000008D 59                      	pop cx
   223 0000008E E8(0000)EB02[0000]      	nearcall skipcomm0
   224 00000095 E8(0000)EB02[0000]      	nearcall iseol?
   225 0000009C 7560                    	jne getrange_not_eol
   226                                  
   227 0000009E F606[0100]80            	testopt [getrange_lines], 8000h
   228 000000A3 740E                    	jz @F			; if lines length not supported -->
   229 000000A5 85FF                    	test di, di		; default lines given ?
   230 000000A7 740A                    	jz @F			; no -->
   231 000000A9 78C7                    	js short errorj10	; error if sign bit set -->
   232 000000AB 893E[0000]              	mov word [getrange_lines], di
   233                                  				; return lines (PL)
   234 000000AF 66                      	_386_PM_o32
   235 000000B0 31C9                    	xor cx, cx		; (e)cx = 0
   236 000000B2 41                      	inc cx			; placeholder length = 1
   237                                  @@:
   238                                  
   239 000000B3 B402                    	mov ah, 2		; do not allow past boundary if F RANGE
   240 000000B5 F606[0300]04            	testopt [internalflags3], dif3_accept_getrange_0
   241                                  				; F RANGE special case ?
   242 000000BA 7505                    	jnz @F			; yes -->
   243 000000BC 67                      	_386_PM_a32
   244 000000BD E3B3                    	jcxz errorj10		; if a range is mandatory
   245 000000BF 30E4                    	xor ah, ah		; default range, allow clamping to boundary
   246                                  @@:
   247                                  getrange_length.addcheck:
   248 000000C1 803E[0000]00            _386_PM	cmp byte [bAddr32], 0
   249 000000C6 740D                    _386_PM	je .16
   250 000000C8 6649                    _386_PM	dec ecx
   251 000000CA 6601D1                  _386_PM	add ecx, edx
   252 000000CD 7356                    _386_PM	jnc getrange_retn	; if no wraparound
   253 000000CF 6683C9FF                _386_PM	or ecx, byte -1		; go to end of segment
   254 000000D3 EB22                    _386_PM	jmp short .checkclamped	; check if clamping allowed -->
   255                                  .16:
   256 000000D5 F6C402                  _386_PM	test ah, 2		; F RANGE with implicit length ?
   257 000000D8 7409                    _386_PM	jz @F			; no -->
   258 000000DA 6681F900000100          _386_PM	cmp ecx, 1_0000h	; yes, is it a 32-bit length > 64 KiB ?
   259 000000E1 778F                    _386_PM	ja short errorj10	; error if so (don't try to clamp) -->
   260                                  @@:
   261 000000E3 6681F9FFFF0000          _386_PM	cmp ecx, 0FFFFh		; was high ?
   262 000000EA 7603                    _386_PM	jbe @F			; no --> (ecxh = 0)
   263 000000EC 6631C9                  _386_PM	xor ecx, ecx		; ecxh = 0 and prepare so as to
   264                                  				;  result in cx = FFFFh after dec
   265                                  @@:
   266 000000EF 49                      	dec cx
   267 000000F0 01D1                    	add cx, dx
   268 000000F2 7331                    	jnc getrange_retn	; if no wraparound
   269 000000F4 B9FFFF                  	mov cx, -1		; go to end of segment
   270                                  				; next, check if clamping allowed
   271                                  .checkclamped:		; checks if clamping allowed
   272 000000F7 84E4                    	test ah, ah		; clamping allowed ?
   273 000000F9 742A                    	jz getrange_retn
   274 000000FB E974FF                  	jmp errorj10		; (no) if a specified length wrapped -->
   275                                  
   276                                  getrange_not_eol:
   277 000000FE E8(0000)EB02[0000]      	nearcall capitalise
   278 00000105 3C4C                    	cmp al, 'L'
   279 00000107 741D                    	je getrange_length	; if a range with length is given
   280 00000109 66                      	_386_PM_o32	; xchg ecx, edx
   281 0000010A 87CA                    	xchg cx, dx		; ecx = start offset, edx clobbered
   282 0000010C BA[0000]                	mov dx, msg.end		; dx clobbered
   283 0000010F 4E                      	dec si			; -> nonblank
   284 00000110 E8(0000)EB02[0000]      	nearcall isstring?	; (advance si if match)
   285 00000117 AC                      	lodsb			; load separator byte or initial nonblank
   286 00000118 B400                    	mov ah, 0		; must be offset
   287 0000011A E8FE00                  	nearcall getofsforbx_remember_bitness
   288                                  				; (DebugX: returns edx no matter what)
   289 0000011D 66                      	_386_PM_o32	; xchg ecx, edx
   290 0000011E 87CA                    	xchg cx, dx		; ecx = end offset, edx = start offset
   291 00000120 66                      	_386_PM_o32	; cmp edx, ecx
   292 00000121 39CA                    	cmp dx, cx
   293 00000123 7758                    	ja short errorj2b	; if empty range -->
   294                                  getrange_retn:
   295 00000125 C3                      	retn
   296                                  
   297                                  getrange_length:
   298 00000126 4E                      	dec si			; -> at 'L'
   299 00000127 52                      	push dx
   300 00000128 BA[0000]                	mov dx, msg.length
   301 0000012B E8(0000)EB02[0000]      	nearcall isstring?	; if match: ZR, NC, else: NZ, CY
   302 00000132 5A                      	pop dx
   303                                  %if 0
   304                                  	jne .notlength
   305                                  	db __TEST_IMM8		; (skip inc, si -> terminator after "LENGTH")
   306                                  .notlength:
   307                                  	inc si			; -> behind 'L'
   308                                  %else
   309 00000133 83D600                  	adc si, 0		; -> behind 'L' if mismatch,
   310                                  				;  stay at -> behind "LENGTH" else
   311                                  %endif
   312 00000136 E8(0000)EB02[0000]      	nearcall skipcomma	; discard the 'L'
   313                                  ;--- a range is entered with the L/ength argument
   314                                  ;--- get a valid length for segment in BX
   315 0000013D 52                      	push dx
   316 0000013E 53                      	push bx
   317 0000013F E8(0000)EB02[0000]      _386_PM	nearcall test_high_limit
   318 00000146 9C                      _386_PM	pushf
   319 00000147 8B0E[0000]              	mov cx, word [getrange_lines]
   320                                  				; cx from getrange_not_eol clobbered
   321 0000014B E85102                  	nearcall get_length.lines
   322 0000014E 9D                      _386_PM	popf
   323 0000014F 750B                    _386_PM	jnz .not16_64kib	; don't check for <= 64 KiB
   324 00000151 83FB01                  	cmp bx, byte 1
   325 00000154 7206                    	jb .not16_64kib		; < 64 KiB in 16-bit segment -->
   326 00000156 7525                    	jne short errorj2b	; 16-bit segment, above 64 KiB -->
   327 00000158 85D2                    	test dx, dx
   328 0000015A 7521                    	jnz short errorj2b	; 16-bit segment, above 64 KiB -->
   329                                  .not16_64kib:
   330                                  @@:
   331                                  %if _PM
   332 0000015C 53                      _386	push bx			; (only push high word on 386+)
   333 0000015D 52                      	push dx
   334 0000015E 66                      	_386_o32	; pop ecx	; mov ecx, bxdx
   335 0000015F 59                      	pop cx			; mov cx, dx
   336                                  %else
   337                                  	mov cx, dx
   338                                  %endif
   339 00000160 09D3                    	or bx, dx		; zero ?
   340 00000162 7407                    	jz short explicit0range	; yes, error -->
   341 00000164 5B                      	pop bx
   342 00000165 5A                      	pop dx
   343 00000166 B401                    	mov ah, 1		; disallow clamping / overflow
   344 00000168 E956FF                  	jmp .addcheck		; check for overflow
   345                                  
   346                                  explicit0range:
   347                                  %if _MS_0RANGE_COMPAT
   348 0000016B F606[0200]04            	testopt [options2], opt2_0range_compat
   349 00000170 740B                    	jz errorj2b
   350 00000172 43                      	inc bx			; bx:dx = 10000h (64 KiB)
   351                                  %if !_LOADER
   352 00000173 D006[0000]              	rol byte [getrange_is_uu], 1
   353 00000177 73E3                    	jnc @B			; if not uu -->
   354 00000179 87DA                    	xchg bx, dx		; bx:dx = 1
   355                                  %endif
   356 0000017B EBDF                    	jmp @B
   357                                  %endif
   358                                  errorj2b:
   359 0000017D E980FE                  	jmp	error_expr
   360                                  
   361                                  
   362                                  ;	GETADDR - Get address from input line.
   363                                  ;	Entry	AL	First character of address
   364                                  ;		SI	Address of next character
   365                                  ;		BX	Default segment to use
   366                                  ;	Exit	AL	First character beyond address
   367                                  ;		SI	Address of the character after that
   368                                  ;		BX:(E)DX	Address found
   369                                  ;	Uses	AH,CX
   370                                  ;	REM:	mm expects that numeric expressions evaluating
   371                                  ;		 to numbers in the range 0 to C3h are always
   372                                  ;		 allowed here regardless the default segment's
   373                                  ;		 D/B bit and limit. This is needed for its mc
   374                                  ;		 command detection.
   375                                  
   376                                  getaddr: section_of_function
   377                                  %if _PM
   378 00000180 E80800                  	nearcall getaddrX
   379                                  %if _EXPRDUALCODE && _DUALCODE
   380 00000183 E8(0000)EB02[0000]      	nearcall verifysegm_or_error	; make BX a writeable segment
   381 0000018A C3                      	retn
   382                                  %else
   383                                  	jmp verifysegm_or_error	; make BX a writeable segment
   384                                  %endif
   385                                  
   386                                  ; getaddrX differs from getaddr in that BX is not ensured
   387                                  ; to be writeable in PM.
   388                                  ;
   389                                  ; For DEBUG without PM support, getaddr is getaddrX. Both don't return CF.
   390                                  
   391                                  getaddrX: section_of_function
   392 0000018B C606[0000]00            	mov byte [bAddr32], 0
   393 00000190 31C9                    	xor cx, cx
   394 00000192 3C24                    	cmp al, '$'		; a real-mode segment?
   395 00000194 7541                    	jne getaddr_no_dollar
   396 00000196 AC                      	lodsb
   397                                  %if _DOUBLEDOLLAR
   398                                  	cmp al, '$'
   399                                  	jne @F
   400                                  	lodsb
   401                                  	dec cx			; indicate double dollar sign (0FFFFh)
   402                                  @@:
   403                                  %endif
   404                                  
   405 00000197 6631D2                  _386	xor edx, edx		; edxh = 0
   406 0000019A E8AE0D                  	nearcall getexpression
   407 0000019D 84E4                    	test ah, ah		; pointer type ?
   408 0000019F 7915                    	jns @F
   409                                  
   410 000001A1 E8(0000)EB02[0000]      	nearcall ispm		; need to translate ?
   411 000001A8 750B                    	jnz .ret		; no -->
   412                                  				; bx = segment
   413                                  		; after falling through we get bx:(e)dx = segmented address
   414                                  
   415                                  check_section_of seg_bx_to_sel
   416                                  seg_bx_to_sel: equ $		; (no base for local labels)
   417 000001AA 50                      	push ax
   418 000001AB B80200                  	mov ax, 0002h
   419 000001AE CD31                    	int 31h
   420 000001B0 7222                    	jc short errorj2
   421 000001B2 89C3                    	mov bx, ax		; bx = segment
   422                                  %if _DOUBLEDOLLAR
   423                                  	 push dx
   424                                  	push cx
   425                                  	xor cx, cx
   426                                  	mov dx, -1
   427                                  	mov ax, 0008h
   428                                  	int 31h			; set segment limit 0FFFFh
   429                                  	pop cx
   430                                  	jcxz .no_double_dollar
   431                                  	mov dx, cx		; cx = dx = 0FFFFh
   432                                  	mov ax, 0008h
   433                                  	int 31h			; set segment limit 0FFFF_FFFFh
   434                                  .no_double_dollar:
   435                                  	 pop dx
   436                                  %endif
   437 000001B4 58                      	pop ax
   438                                  .ret:
   439 000001B5 C3                      	retn
   440                                  
   441                                  @@:
   442 000001B6 E88013                  	nearcall getword.checksignificantbits
   443 000001B9 E8(0000)EB02[0000]      	nearcall ispm		; need to translate ?
   444 000001C0 7507                    	jnz .checkseg		; no -->
   445 000001C2 89D3                    	mov bx, dx
   446 000001C4 E8E3FF                  	nearcall seg_bx_to_sel
   447 000001C7 89DA                    	mov dx, bx
   448                                  .checkseg:
   449 000001C9 E8(0000)EB02[0000]      	nearcall skipwh0
   450 000001D0 3C3A                    	cmp al, ':'		; was a segment at all?
   451 000001D2 743C                    	je getaddr_segment	; yes -->
   452                                  errorj2:
   453 000001D4 E929FE                  	jmp error_expr
   454                                  %else
   455                                  getaddrX: section_of_function
   456                                  	cmp al, '$'
   457                                  	jne getaddr_no_dollar
   458                                  	lodsb
   459                                  %if _DOUBLEDOLLAR
   460                                  	cmp al, '$'
   461                                  	jne @F
   462                                  	lodsb
   463                                  @@:
   464                                  %endif
   465                                  	nearcall getexpression
   466                                  	test ah, ah		; pointer type ?
   467                                  	js .ret			; return bx:dx = segmented address
   468                                  	nearcall getword.checksignificantbits
   469                                  	nearcall skipwh0
   470                                  	cmp al, ':'
   471                                  	je getaddr_segment
   472                                  	jmp error_expr
   473                                  
   474                                  .ret:
   475                                  	retn
   476                                  %endif
   477                                  
   478                                  
   479                                  %if !_LOADER
   480                                  	usesection lDEBUG_DATA_ENTRY
   480          ------------------       note: usesection lDEBUG_DATA_ENTRY
   481                                  
   482                                  	align 2, db 0
   483                                  getaddr_taken_table:
   484 00000000 [0000]0100              	dw msg.t, 1
   485 00000004 [0000]0100              	dw msg.taken, 1
   486 00000008 [0000]0000              	dw msg.nt, 0
   487 0000000C [0000]0000              	dw msg.nottaken, 0
   488 00000010 0000                    	dw 0			; end of table
   489                                  %endif
   490                                  
   491                                  %if _EXPRDUALCODE && _DUALCODE
   492                                  	usesection lDEBUG_CODE2
   492          ------------------       note: usesection lDEBUG_CODE2
   493                                  %else
   494                                  	usesection lDEBUG_CODE
   495                                  %endif
   496                                  getaddr_no_dollar:
   497 000001D7 4E                      	dec si			; si -> text
   498                                  %if !_LOADER
   499 000001D8 57                      	push di
   500 000001D9 BF[FEFF]                	mov di, getaddr_taken_table - 2
   501                                  				; -> table minus 2
   502                                  @@:
   503 000001DC AF                      	scasw			; di += 2, -> -> string to compare
   504 000001DD 8B15                    	mov dx, [di]		; -> string to compare (0 if end of table)
   505 000001DF AF                      	scasw			; di += 2, -> taken status (1 = taken)
   506 000001E0 85D2                    	test dx, dx		; end of table ?
   507 000001E2 740D                    	jz @F			; if end of table -->
   508 000001E4 E8(0000)EB02[0000]      	nearcall isstring?	; is it this keyword ?
   509 000001EB 75EF                    	jne @B			; no, loop -->
   510 000001ED 8B05                    	mov ax, [di]		; get taken status
   511 000001EF EB32                    	jmp getaddr_taken	; branch to taken handling, di on stack
   512                                  
   513                                  @@:
   514 000001F1 5F                      	pop di			; restore di
   515                                  %endif
   516 000001F2 AC                      	lodsb			; reload al = text, si -> after
   517 000001F3 B401                    	mov ah, 1		; might be a pointer type
   518 000001F5 E80FFE                  	nearcall getofsforbx
   519 000001F8 720B                    	jc .ret			; if pointer type then return -->
   520 000001FA E8(0000)EB02[0000]      	nearcall skipwh0
   521 00000201 3C3A                    	cmp al, ':'
   522 00000203 7402                    	je getaddr_segment_check_high
   523                                  				; if this is a segment/selector -->
   524                                  .ret:
   525                                  %if _PM
   526 00000205 EB17                    	jmp short remember_bitness
   527                                  				; remember 32-bitness (only if no segment)
   528                                  %else
   529                                  	retn
   530                                  %endif
   531                                  
   532                                  getaddr_segment_check_high:
   533 00000207 6681FA00000100          _386_PM cmp edx, 0001_0000h	; segment/selector fits in word ?
   534 0000020E 73C4                    _386_PM jae short errorj2	; no -->
   535                                  getaddr_segment:
   536                                  		; al = colon ':'
   537                                  		; si -> text after colon
   538 00000210 89D3                    	mov bx, dx		; mov segment into BX
   539 00000212 E8(0000)EB02[0000]      	nearcall skipwhite	; skip to next word
   540 00000219 B400                    	mov ah, 0		; must be an offset
   541                                  %if _PM
   542                                  getofsforbx_remember_bitness: section_of_function
   543 0000021B E8E9FD                  	nearcall getofsforbx
   544                                  remember_bitness: section_of_function
   545 0000021E 0826[0000]              	or byte [bAddr32], ah	; remember 32-bitness
   546 00000222 C3                      	retn
   547                                  %else
   548                                  	jmp getofsforbx
   549                                  
   550                                  check_section_of getofsforbx_remember_bitness
   551                                  getofsforbx_remember_bitness: equ getofsforbx
   552                                  %endif
   553                                  
   554                                  
   555                                  %if !_LOADER
   556                                  		; INP:	ax = 1 if taken, 0 if nottaken
   557                                  		;	ss:sp -> di value
   558                                  getaddr_taken: section_of_function
   559 00000223 66                      	_386_PM_o32	; (push esi)
   560 00000224 56                      	push si
   561 00000225 66                      	_386_PM_o32	; (push eax)
   562 00000226 50                      	push ax			; ! must be the LAST word in this stack frame
   563                                  
   564 00000227 BA0F00                  	mov dx, 15		; DL = number of bytes to go, DH = prefix flags
   565 0000022A 8B1E[0000]              	mov bx, word [reg_cs]
   566 0000022E 66                      	_386_PM_o32	; mov esi, dword [reg_eip]
   567 0000022F 8B36[0000]              	mov si, word [reg_eip]
   568                                  .pp2:
   569 00000233 E8(0000)EB02[0000]      	nearcall pp16		; get next instruction byte into AL
   570 0000023A BF[0000]                	mov di, ppbytes
   571 0000023D B9[0000]                	mov cx, PPLEN_ONLY_PREFIXES
   572 00000240 F2AE                    	repne scasb		; asize, osize, seg prefixes (ie, hints) ?
   573 00000242 7513                    	jne @F			; no -->
   574                                  %if _LINK_COMPAT
   575 00000244 8A85[FFFF]              	mov al,byte [word di+PPLEN-1]; get corresponding byte in ppinfo
   576                                  %else
   577                                  	mov al,byte [di+PPLEN-1]; get corresponding byte in ppinfo
   578                                  %endif
   579                                  	; test al, PP_PREFIX	; prefix ?
   580                                  	; jz pp3		; no -->
   581                                  		; (Always set in getaddr_taken.)
   582 00000248 08C6                    	or dh, al		; set the OSIZE or ASIZE flags if either of these
   583                                  			; Note:	Multiple OSIZE in a 16-bit cs do not toggle
   584                                  			;	between decoding as O32 and O16, they're always
   585                                  			;	decoded as O32. The same is true for A32, and
   586                                  			;	in a 32-bit cs for O16 and A16.
   587                                  .next:
   588 0000024A FECA                    	dec dl
   589 0000024C 75E5                    	jnz .pp2		; if not out of bytes -->
   590                                  .pp5:				; unknown, error out on the (NOT)TAKEN keyword
   591 0000024E 66                      	_386_PM_o32	; (pop eax)
   592 0000024F 58                      	pop ax
   593 00000250 66                      	_386_PM_o32	; (pop esi)
   594 00000251 5E                      	pop si			; restore si so error will be behind keyword
   595 00000252 5F                      	pop di
   596 00000253 46                      	inc si
   597 00000254 E99F00                  	jmp errorj2a
   598                                  
   599                                  @@:
   600 00000257 3C70                    	cmp al, 70h		; jcc rel8 ?
   601 00000259 7204                    	jb @F			; no -->
   602 0000025B 3C7F                    	cmp al, 7Fh
   603 0000025D 7655                    	jbe .rel_8		; yes -->
   604                                  @@:
   605 0000025F 3CE0                    	cmp al, 0E0h		; loop* / j(e)cxz rel8 ?
   606 00000261 7204                    	jb @F			; no -->
   607 00000263 3CE3                    	cmp al, 0E3h
   608 00000265 764D                    	jbe .rel_8		; yes -->
   609                                  @@:
   610 00000267 3C0F                    	cmp al, 0Fh		; prefix byte ?
   611 00000269 75E3                    	jne .pp5		; no, no valid conditional branch (error) -->
   612 0000026B E8(0000)EB02[0000]      	nearcall pp16
   613 00000272 3C80                    	cmp al, 80h		; jcc rel16/rel32 ?
   614 00000274 72D8                    	jb .pp5
   615 00000276 3C8F                    	cmp al, 8Fh
   616 00000278 77D4                    	ja .pp5			; no, error -->
   617                                  .rel_16_32:
   618 0000027A E8(0000)EB02[0000]      _386_PM	nearcall pp_fix32bitflags
   619 00000281 E8(0000)EB02[0000]      	nearcall pp16
   620 00000288 86C4                    	xchg al, ah
   621 0000028A E8(0000)EB02[0000]      	nearcall pp16
   622 00000291 86C4                    	xchg al, ah		; ax = rel16
   623 00000293 F6C602                  _386_PM	test dh, PP_OPSIZ
   624 00000296 7424                    _386_PM	jz @F			; have 16-bit displacement -->
   625 00000298 66C1C010                _386_PM	rol eax, 16		; preserve low 16 bits in high 16 bits
   626 0000029C E8(0000)EB02[0000]      _386_PM	nearcall pp16
   627 000002A3 66C1C808                _386_PM	ror eax, 8
   628 000002A7 E8(0000)EB02[0000]      _386_PM	nearcall pp16
   629 000002AE 66C1C808                _386_PM	ror eax, 8		; magic swap to put high 16 bits where they belong
   630 000002B2 EB0A                    	jmp @FF			; have 32-bit displacement -->
   631                                  		; (When _PM=0 build or no 386, this branch will do the
   632                                  		;  same thing as taking it as a 16-bit displacement.)
   633                                  
   634                                  .rel_8:
   635 000002B4 E8(0000)EB02[0000]      	nearcall pp16		; get 8-bit displacement
   636 000002BB 98                      	cbw			; 8 to 16 bits
   637                                  @@:
   638 000002BC 6698                    _386_PM	cwde			; 16 to 32 bits
   639                                  @@:
   640 000002BE 5A                      	pop dx			; get ax from stack
   641 000002BF 52                      	push dx			; restore it to the stack
   642 000002C0 84D2                    	test dl, dl		; 1 if taken, 0 if nottaken
   643 000002C2 7403                    	jz @F			; nottaken, esi has eip value after inst -->
   644 000002C4 66                      	_386_PM_o32	; (add esi, eax)
   645 000002C5 01C6                    	add si, ax		; taken: apply displacement to esi
   646                                  @@:
   647 000002C7 66                      	_386_PM_o32
   648 000002C8 89F2                    	mov dx, si		; get into (e)dx, bx already has seg/sel
   649 000002CA E8(0000)EB02[0000]      _386_PM	nearcall test_d_b_bit
   650 000002D1 7504                    _386_PM	jnz @F			; if 32-bit cs -->
   651 000002D3 660FB7D2                _386_PM	movzx edx, dx		; clear high 16 bits
   652                                  @@:
   653 000002D7 66                      	_386_PM_o32	; (pop eax)
   654 000002D8 58                      	pop ax
   655 000002D9 66                      	_386_PM_o32	; (pop esi)
   656 000002DA 5E                      	pop si
   657 000002DB 5F                      	pop di
   658 000002DC B400                    _386_PM	mov ah, 0		; do not remember bitness (is 16 bit)
   659 000002DE 7402                    _386_PM	jz @F			; if 16-bit cs -->
   660 000002E0 FEC4                    _386_PM	inc ah			; remember bitness as 1 (is 32 bit)
   661                                  @@:
   662 000002E2 E839FF                  _386_PM	nearcall remember_bitness
   663                                  %if _EXPRDUALCODE && _DUALCODE
   664 000002E5 E8(0000)EB02[0000]      	nearcall skipwhite
   665 000002EC C3                      	retn
   666                                  %else
   667                                  	jmp skipwhite
   668                                  %endif
   669                                  %endif
   670                                  
   671                                  %if _STRNUM
   672                                  getstr_check_limit:
   673 000002ED 3BBF[1E00]              	cmp di, word [getstr_dispatch_table.limit + bx]
   674 000002F1 7703E98000              	jbe getstr_retn
   675                                  %endif
   676                                  errorj2a:
   677 000002F6 E907FD                  	jmp error_expr
   678                                  
   679                                  
   680                                  ;	GETSTR - Get string of bytes.  Put the answer in line_out.
   681                                  ;		Entry	AL	first character
   682                                  ;			SI	address of next character
   683                                  ;		Exit	[line_out] first byte of string
   684                                  ;			DI	address of last+1 byte of string
   685                                  ;		Uses	AX, cx, dx,SI
   686                                  
   687                                  getstr: section_of_function
   688                                  %if _STRNUM
   689 000002F9 53                      	push bx
   690 000002FA 31DB                    	xor bx, bx		; 0 = byte size as default
   691                                  %endif
   692 000002FC BF[0000]                	mov di, line_out
   693 000002FF E8(0000)EB02[0000]      	nearcall iseol?
   694 00000306 74EE                    	je short errorj2a	; we don't allow empty byte strings
   695                                  getstr_loop:
   696                                  %if _STRNUM
   697 00000308 E8(0000)EB02[0000]      	nearcall skipcomm0
   698 0000030F 4E                      	dec si			; -> nonblank
   699 00000310 BA[0000]                	mov dx, msg.as		; "AS" keyword ?
   700 00000313 E8(0000)EB02[0000]      	nearcall isstring?
   701 0000031A AC                      	lodsb
   702 0000031B 7519                    	jne .notas		; no -->
   703 0000031D E8(0000)EB02[0000]      	nearcall skipcomm0
   704 00000324 4E                      	dec si			; -> nonblank
   705 00000325 E8C800                  	nearcall get_length_keyword
   706 00000328 75CC                    	jnz errorj2a
   707 0000032A 80F902                  	cmp cl, 2		; 0 = bytes, 1 = words, 2 = dwords
   708                                  				; (ch is always zero)
   709 0000032D 77C7                    	ja errorj2a		; higher is invalid -->
   710 0000032F 89CB                    	mov bx, cx
   711 00000331 01DB                    	add bx, bx		; make a table offset
   712 00000333 AC                      	lodsb
   713 00000334 EB2F                    	jmp getstr_next
   714                                  
   715                                  .notas:
   716                                  %endif
   717 00000336 3C27                    	cmp al, "'"
   718 00000338 740D                    	je getstr_start_quote	; if string
   719 0000033A 3C22                    	cmp al, '"'
   720 0000033C 7409                    	je getstr_start_quote	; ditto
   721                                  
   722                                  %if _STRNUM
   723 0000033E E8ACFF                  	call getstr_check_limit
   724 00000341 FF97[1200]              	call near [getstr_dispatch_table.numeric + bx]
   725                                  %else
   726                                  	nearcall getbyte	; byte in DL
   727                                  	mov byte [di], dl	; store the byte
   728                                  	inc di
   729                                  %endif
   730 00000345 EB1E                    	jmp short getstr_next
   731                                  
   732                                  getstr_start_quote:
   733 00000347 88C4                    	mov ah, al		; save quote character
   734                                  getstr_loop_quoted:
   735 00000349 AC                      	lodsb
   736 0000034A 38E0                    	cmp al, ah
   737 0000034C 7412                    	je getstr_quote_quoted	; if possible end of string
   738 0000034E E8(0000)EB02[0000]      	nearcall iseol?.notsemicolon
   739 00000355 749F                    	je short errorj2a	; if end of line
   740                                  getstr_store_quoted:
   741                                  %if _STRNUM
   742 00000357 E893FF                  	call getstr_check_limit
   743 0000035A FF97[1800]              	call near [getstr_dispatch_table.string + bx]
   744                                  %else
   745                                  	stosb			; save character and continue
   746                                  %endif
   747 0000035E EBE9                    	jmp short getstr_loop_quoted
   748                                  
   749                                  getstr_quote_quoted:
   750 00000360 AC                      	lodsb
   751 00000361 38E0                    	cmp al, ah
   752 00000363 74F2                    	je getstr_store_quoted	; if doubled quote character
   753                                  getstr_next:
   754 00000365 E8(0000)EB02[0000]      	nearcall skipcomm0	; go back for more
   755 0000036C E8(0000)EB02[0000]      	nearcall iseol?
   756 00000373 7593                    	jne getstr_loop			; if not done yet
   757                                  %if _STRNUM
   758 00000375 5B                      	pop bx
   759                                  getstr_retn:
   760                                  %endif
   761 00000376 C3                      	retn
   762                                  
   763                                  
   764                                  %if _STRNUM
   765                                  getstr_numeric_byte:
   766 00000377 E8C811                  	nearcall getbyte	; byte in DL
   767 0000037A 8815                    	mov byte [di], dl	; store the byte
   768 0000037C 47                      	inc di
   769 0000037D C3                      	retn
   770                                  
   771                                  getstr_numeric_word:
   772 0000037E E8B311                  	nearcall getword	; dx
   773 00000381 8915                    	mov word [di], dx	; store
   774 00000383 AF                      	scasw			; di += 2
   775 00000384 C3                      	retn
   776                                  
   777                                  getstr_numeric_dword:
   778 00000385 53                      	push bx
   779 00000386 E8C20B                  	nearcall getdword	; bx:dx
   780 00000389 8915                    	mov word [di], dx	; store
   781 0000038B AF                      	scasw			; di += 2
   782 0000038C 891D                    	mov word [di], bx	; store
   783 0000038E AF                      	scasw			; di += 2
   784 0000038F 5B                      	pop bx
   785 00000390 C3                      	retn
   786                                  
   787                                  
   788                                  getstr_string_word:
   789 00000391 AA                      	stosb			; save character and continue
   790 00000392 B000                    	mov al, 0
   791 00000394 AA                      	stosb
   792 00000395 C3                      	retn
   793                                  
   794                                  getstr_string_dword:
   795 00000396 AA                      	stosb			; save character and continue
   796 00000397 B000                    	mov al, 0
   797 00000399 AA                      	stosb
   798 0000039A AA                      	stosb
   799                                  getstr_string_byte:
   800 0000039B AA                      	stosb
   801 0000039C C3                      	retn
   802                                  
   803                                  
   804                                  	usesection lDEBUG_DATA_ENTRY
   804          ------------------       note: usesection lDEBUG_DATA_ENTRY
   805                                  
   806                                  		; REM:	Dispatch table in section lDEBUG_CODE or lDEBUG_CODE2
   807                                  	align 2, db 0
   808                                  getstr_dispatch_table:
   809 00000012 [7703]                  .numeric:	dw getstr_numeric_byte
   810 00000014 [7E03]                  		dw getstr_numeric_word
   811 00000016 [8503]                  		dw getstr_numeric_dword
   812 00000018 [9B03]                  .string:	dw getstr_string_byte
   813 0000001A [9103]                  		dw getstr_string_word
   814 0000001C [9603]                  		dw getstr_string_dword
   815 0000001E [FFFF]                  .limit:		dw line_out_end - 1
   816 00000020 [FEFF]                  		dw line_out_end - 2
   817 00000022 [FCFF]                  		dw line_out_end - 4
   818                                  
   819                                  %if _EXPRDUALCODE && _DUALCODE
   820                                  	usesection lDEBUG_CODE2
   820          ------------------       note: usesection lDEBUG_CODE2
   821                                  %else
   822                                  	usesection lDEBUG_CODE
   823                                  %endif
   824                                  
   825                                  %endif	; _STRNUM
   826                                  
   827                                  
   828                                  		; INP:	al =, si -> input
   829                                  		;	cx = getrange lines flag (8000h if LINES allowed)
   830                                  		; OUT:	al =, si -> after number / keyword
   831                                  		;	If not LINES,
   832                                  		;	 word [getrange_lines] unchanged
   833                                  		;	 bx:dx = size
   834                                  		;	If LINES,
   835                                  		;	 word [getrange_lines] = number of lines
   836                                  		;		(must be >= 1 and <= 7FFFh)
   837                                  		;	 bx:dx = 1, as a placeholder value
   838                                  		; CHG:	ah, cx
   839                                  		; REM:	jumps to error on invalid input
   840                                  get_length: section_of_function
   841 0000039D 31C9                    	xor cx, cx		; do not allow LINES
   842                                  .lines: section_of_function get_length
   843                                  
   844 0000039F E8A90B                  	nearcall getdword
   845 000003A2 4E                      	dec si
   846 000003A3 56                      	push si			; -> before comma
   847 000003A4 E8(0000)EB02[0000]      	nearcall skipcomma
   848                                  
   849 000003AB 52                      	 push dx		; = low word of number
   850 000003AC 4E                      	dec si
   851                                  
   852 000003AD 85C9                    	test cx, cx		; LINES allowed ?
   853 000003AF 7923                    	jns @F			; no -->
   854                                  
   855 000003B1 BA[0000]                	mov dx, msg.lines
   856 000003B4 E8(0000)EB02[0000]      	nearcall isstring?	; LINES specified ?
   857 000003BB 7517                    	jne @F			; no -->
   858                                  
   859 000003BD 5A                      	 pop dx			; restore = low word of number
   860 000003BE 85DB                    	test bx, bx		; lines must be <= 7FFFh
   861 000003C0 750F                    	jnz .error		; if > FFFFh -->
   862 000003C2 85D2                    	test dx, dx
   863 000003C4 740B                    	jz .error		; lines mustn't be zero -->
   864 000003C6 7809                    	js .error		; if >= 8000h -->
   865 000003C8 8916[0000]              	mov word [getrange_lines], dx
   866                                  				; save lines specified
   867 000003CC BA0100                  	mov dx, 1		; return a placeholder size in bx:dx
   868 000003CF EB13                    	jmp .done
   869                                  
   870                                  .error:
   871 000003D1 E92CFC                  	jmp error_expr
   872                                  
   873                                  @@:
   874 000003D4 E81900                  	nearcall get_length_keyword
   875                                  				; si -> terminator after length unit
   876                                  				;  (or -> after expression if no unit)
   877 000003D7 5A                      	 pop dx			; restore = low word of number
   878 000003D8 7513                    	jnz .nokeyword		; no unit given, reset to -> before comma -->
   879 000003DA E308                    	jcxz .noshift		; "BYTES" given -->
   880                                  .shiftloop:
   881 000003DC D1E2                    	shl dx, 1
   882 000003DE D1D3                    	rcl bx, 1
   883 000003E0 72EF                    	jc short .error		; too large -->
   884 000003E2 E2F8                    	loop .shiftloop		; loop shifting (if it was shift count > 1)
   885                                  .noshift:
   886                                  .done:
   887 000003E4 59                      	pop cx			; discard -> before comma
   888 000003E5 E8(0000)EB02[0000]      	nearcall skipwhite	; al = next character, si -> after that
   889 000003EC C3                      	retn
   890                                  
   891                                  .nokeyword:
   892 000003ED 5E                      	pop si			; restore -> before comma
   893 000003EE AC                      	lodsb			; al = comma or other nonblank, si -> after
   894 000003EF C3                      	retn
   895                                  
   896                                  
   897                                  		; INP:	si -> potential keyword
   898                                  		; OUT:	NZ if no keyword,
   899                                  		;	 si unchanged
   900                                  		;	 cx = 0 (default length shift like BYTES)
   901                                  		;	ZR if keyword found,
   902                                  		;	 si -> separator behind keyword
   903                                  		;	 cx = length shift (< 256)
   904                                  		; CHG:	dx, al
   905                                  get_length_keyword: section_of_function
   906 000003F0 57                      	push di
   907 000003F1 BF[0000]                	mov di, table_length_keywords
   908 000003F4 A9                      	db __TEST_IMM16		; (skip jcxz in first iteration)
   909                                  @@:
   910 000003F5 E30F                    	jcxz .gotsize		; prior was the last entry --> (NZ)
   911                                  		; This branch cannot be taken in the first iteration.
   912                                  		;  If it is taken then the flags are always NZ here.
   913 000003F7 8B0D                    	mov cx, word [di]	; = shift count (0 if last entry of table)
   914 000003F9 AF                      	scasw			; di += 2
   915 000003FA 8B15                    	mov dx, word [di]	; -> keyword in allcaps ASCIZ
   916 000003FC AF                      	scasw			; di += 2
   917 000003FD E8(0000)EB02[0000]      	nearcall isstring?	; this keyword matches ?
   918 00000404 75EF                    	jne @B			; no, loop --> (NZ, si unchanged)
   919                                  		; matched, si is advanced -> past the keyword
   920                                  		; ZR
   921                                  
   922                                  .gotsize:
   923 00000406 5F                      	pop di
   924 00000407 C3                      	retn
   925                                  
   926                                  
   927                                  isbracketorunaryoperator?: section_of_function
   928 00000408 E80900                  	nearcall isunaryoperator?
   929 0000040B 7406                    	je .yes
   930                                  %if _INDIRECTION
   931 0000040D 3C5B                    	cmp al, '['
   932 0000040F 7402                    	je .yes
   933                                  %endif
   934 00000411 3C28                    	cmp al, '('
   935                                  .yes:
   936 00000413 C3                      	retn
   937                                  
   938                                  
   939                                  		; Is al one of the simple unary operators?
   940                                  		; OUT:	NZ if not
   941                                  		;	ZR if so,
   942                                  		;	 NC
   943                                  		;	 cx = index into unaryoperators
   944                                  isunaryoperator?: section_of_function
   945 00000414 57                      	push di
   946 00000415 BF[5800]                	mov di, unaryoperators	; -> countedw
   947 00000418 EB04                    	jmp short isoperator?.common
   948                                  
   949                                  		; See previous description.
   950                                  isoperator?: section_of_function
   951 0000041A 57                      	push di
   952 0000041B BF[4000]                	mov di, operators	; -> countedw
   953                                  .common:
   954 0000041E 8B0D                    	mov cx, word [di]	; get amount of scan byte entries
   955 00000420 51                      	push cx
   956 00000421 AF                      	scasw			; skip amount
   957 00000422 F2AE                    	repne scasb		; scan, cx = remainder of entries
   958 00000424 5F                      	pop di			; = amount
   959 00000425 7506                    	jne .no			; --> (NZ)
   960                                  		; neg cx = not cx \ inc cx
   961                                  		; therefore not cx = neg cx \ dec cx
   962 00000427 F7D1                    	not cx			; minus remainder minus 1
   963 00000429 01F9                    	add cx, di		; amount minus remainder minus 1
   964                                  		; if last matches, remainder = 0
   965                                  		; if second to last matches, remainder = 1
   966                                  		; therefore amount - remainder - 1 = 0-based index
   967 0000042B 38C0                    	cmp al, al		; NC, ZR
   968                                  .no:
   969 0000042D 5F                      	pop di
   970 0000042E C3                      	retn
   971                                  
   972                                  
   973                                  		; INP:	al = character
   974                                  		; OUT:	al = capitalised character
   975                                  		;	ZR, NC if a separator
   976                                  		;	NZ if no separator
   977                                  isseparator?: section_of_function
   978                                  .:
   979 0000042F E8(0000)EB02[0000]      	nearcall capitalise
   980 00000436 51                      	push cx
   981                                  %if _EXPRESSIONS
   982 00000437 3C41                    	cmp al, 'A'
   983 00000439 7204                    	jb @F
   984 0000043B 3C5A                    	cmp al, 'Z'
   985 0000043D 7605                    	jbe @FF
   986                                  @@:
   987 0000043F E8D8FF                  	nearcall isoperator?	; normal operators are separators (also handles equality sign)
   988 00000442 740A                    	je .yes			; if match --> (ZR, NC)
   989                                  @@:
   990                                  %endif
   991 00000444 57                      	push di
   992 00000445 BF[800C]                	mov di, separators
   993 00000448 8B0D                    	mov cx, word [di]	; = amount of scan byte entries
   994 0000044A AF                      	scasw			; skip amount
   995 0000044B F2AE                    	repne scasb		; ZR, NC on match, NZ else
   996 0000044D 5F                      	pop di
   997                                  .yes:
   998 0000044E 59                      	pop cx
   999 0000044F C3                      	retn
  1000                                  
  1001                                  		; INP:	al = character
  1002                                  		; OUT:	al = capitalised character
  1003                                  		;	ZR, NC if a separator (not L or dot)
  1004                                  		;	NZ if no separator (including L or dot)
  1005                                  .except_L_or_dot: section_of_function isseparator?
  1006 00000450 E8(0000)EB02[0000]      	nearcall capitalise
  1007 00000457 3C2E                    	cmp al, '.'
  1008 00000459 7404                    	je .ret_NZ
  1009 0000045B 3C4C                    	cmp al, 'L'
  1010 0000045D 75D0                    	jne .
  1011                                  .ret_NZ:
  1012 0000045F 84C0                    	test al, al
  1013 00000461 C3                      	retn
  1014                                  
  1015                                  
  1016                                  		; Does one of the type operators start in input?
  1017                                  		;
  1018                                  		; INP:	al = first character
  1019                                  		;	si-> next character
  1020                                  		; OUT:	Iff NC,
  1021                                  		;	 bx>>1 = offset into typebitmasks and typehandlers tables
  1022                                  		;	 bx&1 = set iff signed type
  1023                                  		;	 di-> behind the type operator
  1024                                  		; CHG:	bx, cx, di
  1025                                  		;
  1026                                  		; Note:	Signed types are specified by an S prefix to
  1027                                  		;	 the type names. Only non-address types can
  1028                                  		;	 be signed (that is, offset, segment, and
  1029                                  		;	 pointer cannot be signed).
  1030                                  		;	Types can be specified with abbreviated names,
  1031                                  		;	 except where that would clash with numeric
  1032                                  		;	 input or a register name or ambiguity would
  1033                                  		;	 be caused. These cases are:
  1034                                  		;	SS, S (short, seg, signed, ss)
  1035                                  		;	B (byte, numeric 0Bh)
  1036                                  		;	C (char, numeric 0Ch)
  1037                                  		;	D (dword, numeric 0Dh)
  1038                                  		;	3 (3byte, numeric 3)
  1039                                  		;	3B (3byte, numeric 3Bh)
  1040                                  		;	CH (char, register ch)
  1041                                  istype?: section_of_function
  1042                                  %if maxtypesize & 1
  1043 00000462 B90800                  	mov cx, maxtypesize+1		; = maximum count + 1
  1044                                  %else
  1045                                  	mov cx, maxtypesize		; = maximum count
  1046                                  %endif
  1047                                  				; cx is even here!
  1048 00000465 52                      	push dx
  1049 00000466 50                      	push ax
  1050 00000467 56                      	push si
  1051                                  
  1052 00000468 29CC                    	sub sp, cx			; allocate name buffer
  1053 0000046A 89E7                    	mov di, sp			; -> name buffer
  1054 0000046C 57                      	 push di
  1055 0000046D 31DB                    	xor bx, bx			; initialise count
  1056                                  %ifn maxtypesize & 1
  1057                                  	inc cx				; = maximum count + 1
  1058                                  %endif
  1059                                  				; The +1 does not represent an off-by-one
  1060                                  				;  because the below loop stores to the
  1061                                  				;  buffer at the beginning of subsequent
  1062                                  				;  iterations, after checking cx.
  1063                                  
  1064 0000046F A9                      	db __TEST_IMM16			; (skip stosb and lodsb)
  1065                                  .storename:
  1066 00000470 AA                      	stosb				; store in name buffer
  1067 00000471 AC                      	lodsb				; get next character to check
  1068 00000472 E8(0000)EB02[0000]      	nearcall capitalise
  1069 00000479 51                      	push cx
  1070 0000047A E88BFF                  	nearcall isbracketorunaryoperator?; terminator ?
  1071 0000047D 59                      	pop cx
  1072 0000047E 741B                    	je .endname
  1073 00000480 E8(0000)EB02[0000]      	nearcall iseol?
  1074 00000487 7412                    	je .endname
  1075 00000489 3C20                    	cmp al, 32
  1076 0000048B 740E                    	je .endname
  1077 0000048D 3C09                    	cmp al, 9
  1078 0000048F 740A                    	je .endname
  1079 00000491 3C2C                    	cmp al, ','
  1080 00000493 7406                    	je .endname			; yes -->
  1081                                  				; We don't check for digits here.
  1082                                  				;  Immediate values and variables
  1083                                  				;  must leave a space inbetween.
  1084 00000495 43                      	inc bx				; count characters
  1085 00000496 E2D8                    	loop .storename			; count remaining buffer space
  1086                                  				; Here, the potential name was too
  1087                                  				;  long for a valid type name.
  1088 00000498 F9                      	stc
  1089 00000499 EB23                    	jmp short .done			; -->
  1090                                  
  1091                                  .endname:
  1092 0000049B E8(0000)EB02[0000]      	nearcall skipwh0		; skip to next field
  1093 000004A2 4E                      	dec si				; -> behind potential name
  1094 000004A3 5F                      	 pop di				; -> name buffer
  1095 000004A4 89D9                    	mov cx, bx			; cx = length
  1096 000004A6 56                      	 push si			; save position in input line
  1097 000004A7 89FE                    	mov si, di			; si-> name buffer
  1098 000004A9 53                      	push bx
  1099 000004AA 57                      	push di
  1100 000004AB F8                      	clc				; indicate unsigned check
  1101 000004AC E81900                  	nearcall isunsignedtype?	; matches an unsigned type ?
  1102 000004AF 5E                      	pop si
  1103 000004B0 59                      	pop cx
  1104 000004B1 730B                    	jnc .done			; yes -->
  1105                                  
  1106 000004B3 AC                      	lodsb				; al = first, si-> second character
  1107 000004B4 49                      	dec cx				; cx = length less one
  1108 000004B5 3C53                    	cmp al, 'S'			; first character an "S" ?
  1109 000004B7 F9                      	stc				; (indicate signed check, or: no type)
  1110 000004B8 7504                    	jne .done			; no, not signed either -->
  1111 000004BA E80B00                  	nearcall isunsignedtype?	; matches an unsigned type now ?
  1112 000004BD 43                      	inc bx				; if NC, set to indicate signed type
  1113                                  .done:
  1114 000004BE 9F                      	lahf
  1115 000004BF 5F                      	 pop di				; if NC, -> behind matched type name
  1116 000004C0 83C408                  	add sp, (maxtypesize+1) & ~1	; discard name buffer
  1117 000004C3 5E                      	pop si
  1118 000004C4 9E                      	sahf
  1119 000004C5 58                      	pop ax
  1120 000004C6 5A                      	pop dx
  1121 000004C7 C3                      	retn
  1122                                  
  1123                                  		; Does one of the unsigned type operators start in buffer?
  1124                                  		;
  1125                                  		; INP:	si-> name buffer with capitalised potential name
  1126                                  		;	cx = length of potential name
  1127                                  		;	CY iff looking for signed type
  1128                                  		; OUT:	Iff NC,
  1129                                  		;	 bx>>1 = offset into typebitmasks and typehandlers tables
  1130                                  		;	 bx&1 = 0
  1131                                  		; CHG:	ax, bx, cx, dx, si, di
  1132                                  isunsignedtype?: section_of_function
  1133 000004C8 BF[0000]                	mov di, types
  1134 000004CB 19D2                    	 sbb dx, dx			; 0FFFFh if signed check else 0
  1135 000004CD E352                    	jcxz .notype			; if zero characters -->
  1136 000004CF 83F902                  	cmp cx, 2
  1137 000004D2 750C                    	jne @F
  1138 000004D4 813C4348                	cmp word [si], "CH"
  1139 000004D8 7447                    	je .notype
  1140 000004DA 813C3342                	cmp word [si], "3B"
  1141 000004DE 7441                    	je .notype
  1142                                  @@:
  1143 000004E0 E214                    	loop .single_character_checked	; if not single character -->
  1144                                  
  1145 000004E2 AC                      	lodsb				; get that character
  1146 000004E3 3C53                    	cmp al, 'S'			; specified "S" or "SS" ?
  1147 000004E5 743A                    	je .notype			; yes, not allowed -->
  1148 000004E7 08D0                    	or al, dl			; iff signed check, al |= 0FFh
  1149 000004E9 4E                      	dec si				; (restore)
  1150 000004EA 3C33                    	cmp al, '3'
  1151 000004EC 7433                    	je .notype
  1152 000004EE 3C41                    	cmp al, 'A'			; specified only a valid digit ?
  1153 000004F0 7204                    	jb .single_character_checked
  1154 000004F2 3C47                    	cmp al, 'F'+1
  1155 000004F4 722B                    	jb .notype			; yes, not allowed -->
  1156                                  
  1157                                  .single_character_checked:
  1158 000004F6 41                      	inc cx				; (restore)
  1159                                  %if _LINK_COMPAT
  1160 000004F7 81E2[0000]              	 and dx, strict word types.addresses_minus_end	; = 0 iff unsigned check
  1161                                  %else
  1162                                  	 and dx, types.addresses_minus_end	; = 0 iff unsigned check
  1163                                  %endif
  1164 000004FB 31C0                    	xor ax, ax			; initialise ah, and ax = 0 first
  1165 000004FD 31DB                    	xor bx, bx
  1166 000004FF 87FE                    	xchg di, si
  1167 00000501 81C2[0000]              	 add dx, types.end		; = .addresses for signed check,
  1168                                  	 				;  = .end for unsigned check
  1169                                  
  1170                                  		; Before each iteration,
  1171                                  		;  si-> byte-counted next name to check
  1172                                  		;  di-> potential name (in name buffer)
  1173                                  		;  cx = cl = length of potential name
  1174                                  		;  (dx-1) = maximum value for si
  1175                                  		;  ah = 0
  1176                                  		; Before the first iteration additionally,
  1177                                  		;  bx&~3 = index to return for this name (if match)
  1178                                  		;  al = 0
  1179                                  		; Before subsequent iterations additionally,
  1180                                  		;  (bx+2)&~3 = index to return for this name (if match)
  1181                                  		;  al = offset to add to si first
  1182 00000505 A9                      	db __TEST_IMM16			; (skip two times inc bx)
  1183                                  .loop:
  1184 00000506 43                      	inc bx
  1185 00000507 43                      	inc bx				; increase index
  1186 00000508 01C6                    	add si, ax			; -> next table entry
  1187 0000050A AC                      	lodsb				; ax = length of full name
  1188 0000050B 39D6                    	cmp si, dx			; checked all allowed names?
  1189 0000050D 7312                    	jae .notype			; yes, done -->
  1190 0000050F 39C8                    	cmp ax, cx			; full name large enough ?
  1191 00000511 72F3                    	jb .loop			; no -->
  1192 00000513 57                      	push di
  1193 00000514 51                      	push cx
  1194 00000515 56                      	push si
  1195 00000516 F3A6                    	 repe cmpsb			; potential name matches ?
  1196 00000518 5E                      	pop si
  1197 00000519 59                      	pop cx
  1198 0000051A 5F                      	pop di
  1199 0000051B 75E9                    	jne .loop			; no -->
  1200                                  
  1201 0000051D 80E3FC                  	and bl, ~3			; conflate alternative type names
  1202 00000520 A8                      	db __TEST_IMM8			; (NC, skip stc)
  1203                                  .notype:
  1204 00000521 F9                      	stc
  1205 00000522 C3                      	retn
  1206                                  
  1207                                  
  1208                                  	usesection lDEBUG_DATA_ENTRY
  1208          ------------------       note: usesection lDEBUG_DATA_ENTRY
  1209                                  
  1210                                  		; Table of bit masks and shift counts to determine
  1211                                  		;  how a type modifies the bit mask of required bytes.
  1212                                  		;
  1213                                  		; It would be possible to always retrieve a full dword
  1214                                  		;  from memory to process indirection in expressions,
  1215                                  		;  but this could fault if accessing inexistent data.
  1216                                  		;  Hence the debugger should minimise memory access.
  1217                                  		; For this reason, types allow the expression evaluator
  1218                                  		;  to keep track which of the term's bytes are actually
  1219                                  		;  going to be used. The bit mask of required bytes
  1220                                  		;  indicates which bytes are not discarded by any of a
  1221                                  		;  term's type operators.
  1222                                  		;
  1223                                  		; The second byte of each entry (applied to ch by the
  1224                                  		;  reader, ie high byte of cx) indicates a mask to
  1225                                  		;  apply to the bit mask of required bytes. Note that
  1226                                  		;  this mask is applied first, before the shift that's
  1227                                  		;  described next.
  1228                                  		; The first byte of each entry (loaded into cl by the
  1229                                  		;  reader, ie low byte of cx) indicates a shift left
  1230                                  		;  count to apply to the bit mask of required bytes.
  1231                                  		;  (Only the segment type doesn't have 0 currently.)
  1232                                  		;
  1233                                  		; Note that types are parsed forwards through the input
  1234                                  		;  (ie the specified command) but are actually applied
  1235                                  		;  to the numeric value they refer to backwards, that
  1236                                  		;  is, a type that is closer to the term in the input
  1237                                  		;  is applied to the term's result before a type that's
  1238                                  		;  farther from the term.
  1239                                  		; Misleadingly, this reversal isn't very apparent in
  1240                                  		;  most processing of the type and unary operators.
  1241                                  		; The segment type's shifting and masking reflects the
  1242                                  		;  reversal: while the actual operation is to shift
  1243                                  		;  right then restrict to the low word, the entry in
  1244                                  		;  this table indicates to restrict the bit mask to
  1245                                  		;  the low word then shift left.
  1246                                  	align 2, db 0
  1247                                  typebitmasks:
  1248 00000024 0001                    	db 0,    1b	; byte
  1249 00000026 0003                    	db 0,   11b	; word
  1250 00000028 0007                    	db 0,  111b	; 3byte
  1251 0000002A 000F                    	db 0, 1111b	; dword
  1252 0000002C 000F                    	db 0, 1111b	; pointer
  1253 0000002E 0003                    	db 0,   11b	; offset
  1254 00000030 0203                    	db 2,   11b	; segment
  1255                                  
  1256                                  
  1257                                  		; Dispatch table for type conversion functions.
  1258                                  		;
  1259                                  		; INP:	bx:dx = dword input
  1260                                  		;	CF = signedness of type conversion
  1261                                  		;	ah from lahf with the same CF as current
  1262                                  		;	al = type (80h = pointer, 40h = signed)
  1263                                  		; OUT:	bx:dx = new value
  1264                                  		;	ah = type (80h = pointer, 40h = signed)
  1265                                  		; CHG:	ax
  1266                                  		; REM:	Dispatch table in section lDEBUG_CODE or lDEBUG_CODE2
  1267                                  	align 2, db 0
  1268                                  typehandlers:
  1269 00000032 [3605]                  	dw handlebyte
  1270 00000034 [4105]                  	dw handleword
  1271 00000036 [2905]                  	dw handle3byte
  1272 00000038 [4C05]                  	dw handledword
  1273 0000003A [5405]                  	dw handlepointer
  1274 0000003C [4105]                  	dw handleoffset
  1275 0000003E [2305]                  	dw handlesegment
  1276                                  
  1277                                  
  1278                                  %if _EXPRDUALCODE && _DUALCODE
  1279                                  	usesection lDEBUG_CODE2
  1279          ------------------       note: usesection lDEBUG_CODE2
  1280                                  %else
  1281                                  	usesection lDEBUG_CODE
  1282                                  %endif
  1283                                  
  1284                                  handlesegment: section_of_function
  1285 00000523 89DA                    	mov dx, bx
  1286 00000525 30E4                    	xor ah, ah		; NC, ah = 0
  1287 00000527 EB18                    	jmp short handleword
  1288                                  handleoffset equ handleword
  1289                                  
  1290                                  handle3byte: section_of_function
  1291 00000529 B700                    	mov bh, 0
  1292 0000052B 7307                    	jnc .zero		; (iff unsigned type -->)
  1293 0000052D 84DB                    	test bl, bl		; signed ?
  1294 0000052F 7902                    	jns .zero_f		; no -->
  1295 00000531 FECF                    	dec bh
  1296                                  .zero_f:
  1297 00000533 9E                      	sahf			; restore CF
  1298                                  .zero:
  1299 00000534 EB16                    	jmp handledword
  1300                                  
  1301                                  handlebyte: section_of_function
  1302 00000536 B600                    	mov dh, 0
  1303 00000538 7307                    	jnc .zero		; (iff unsigned type -->)
  1304 0000053A 84D2                    	test dl, dl		; signed ?
  1305 0000053C 7902                    	jns .zero_f		; no -->
  1306 0000053E FECE                    	dec dh
  1307                                  .zero_f:
  1308 00000540 9E                      	sahf			; restore CF
  1309                                  .zero:
  1310                                  handleword: section_of_function
  1311 00000541 BB0000                  	mov bx, 0
  1312 00000544 7306                    	jnc .zero		; (iff unsigned type -->)
  1313 00000546 85D2                    	test dx, dx		; signed ?
  1314 00000548 7901                    	jns .zero_f		; no -->
  1315 0000054A 4B                      	dec bx
  1316                                  .zero_f:
  1317 0000054B 9E                      	sahf			; restore CF
  1318                                  .zero:
  1319                                  handledword: section_of_function
  1320 0000054C 7203                    	jc .signed		; if signed -->
  1321 0000054E 30E4                    	xor ah, ah		; return pointer=0 signed=0
  1322 00000550 C3                      	retn
  1323                                  
  1324                                  .signed:
  1325 00000551 B440                    	mov ah, 40h		; return pointer=0 signed=1
  1326 00000553 C3                      	retn
  1327                                  
  1328                                  handlepointer: section_of_function
  1329 00000554 B480                    	mov ah, 80h		; return pointer=1 signed=0
  1330 00000556 C3                      	retn
  1331                                  
  1332                                  
  1333                                  	usesection lDEBUG_DATA_ENTRY
  1333          ------------------       note: usesection lDEBUG_DATA_ENTRY
  1334                                  
  1335                                  		; List of binary and unary operators.
  1336                                  		; The order has to match that in the respective
  1337                                  		; operator handler dispatch table below.
  1338                                  	align 2, db 0
  1339                                  operators:
  1340 00000040 15006F4F6141785863-     .:		countedw "oOaAxXcC?","+-*/%<>=!|&^"
  1340 00000049 433F2B2D2A2F253C3E-
  1340 00000052 3D217C265E         
  1341                                  .amount: equ $ - . - 2
  1342 00000057 00                      	align 2, db 0
  1343                                  unaryoperators:
  1344 00000058 05002B2D7E213F          .:		countedw "+-~!?"
  1345                                  .amount: equ $ - . - 2
  1346                                  
  1347                                  
  1348                                  		; Dispatch table for unary operators,
  1349                                  		;  used by getexpression.
  1350                                  		; Functions in this table are called with:
  1351                                  		;
  1352                                  		; INP:	bx:dx = number
  1353                                  		;	ah = type
  1354                                  		; OUT:	bx:dx = result
  1355                                  		;	ah = type
  1356                                  		; CHG:	-
  1357                                  		; REM:	Dispatch table in section lDEBUG_CODE or lDEBUG_CODE2
  1358 0000005F 00                      	align 2, db 0
  1359                                  unaryoperatorhandlers:
  1360                                  .:
  1361 00000060 [6A05]                  	dw uoh_plus		; +
  1362 00000062 [6005]                  	dw uoh_minus		; -
  1363 00000064 [6B05]                  	dw uoh_not_bitwise	; ~
  1364 00000066 [7205]                  	dw uoh_not_boolean	; !
  1365 00000068 [5705]                  	dw uoh_abs		; ?
  1366                                  .amount: equ ($ - .) / 2
  1367                                  %if .amount != unaryoperators.amount
  1368                                   %error String and table mismatch
  1369                                  %endif
  1370                                  
  1371                                  
  1372                                  %if _EXPRDUALCODE && _DUALCODE
  1373                                  	usesection lDEBUG_CODE2
  1373          ------------------       note: usesection lDEBUG_CODE2
  1374                                  %else
  1375                                  	usesection lDEBUG_CODE
  1376                                  %endif
  1377                                  
  1378                                  uoh_abs: section_of_function
  1379 00000557 80E4BF                  	and ah, ~ 40h		; make type signed=0
  1380 0000055A F6C780                  	test bh, 80h		; negative ?
  1381 0000055D 7504                    	jnz calculate_minus_bxdx; yes -->
  1382 0000055F C3                      	retn			; no, done
  1383                                  
  1384                                  uoh_minus: section_of_function
  1385 00000560 80CC40                  	or ah, 40h		; make type signed=1
  1386                                  calculate_minus_bxdx: section_of_function
  1387 00000563 F7DB                    	neg bx
  1388 00000565 F7DA                    	neg dx
  1389 00000567 83DB00                  	sbb bx, byte 0		; neg bx:dx
  1390                                  uoh_plus: section_of_function	; (nop)
  1391 0000056A C3                      	retn
  1392                                  
  1393                                  uoh_not_bitwise: section_of_function
  1394 0000056B B400                    	mov ah, 0		; make type pointer=0 signed=0
  1395 0000056D F7D3                    	not bx
  1396 0000056F F7D2                    	not dx
  1397 00000571 C3                      	retn
  1398                                  
  1399                                  uoh_not_boolean: section_of_function
  1400 00000572 B400                    	mov ah, 0		; make type pointer=0 signed=0
  1401 00000574 E8CE01                  	nearcall toboolean
  1402 00000577 80F201                  	xor dl, 1		; toggle only bit 0
  1403 0000057A C3                      	retn
  1404                                  
  1405                                  
  1406                                  	usesection lDEBUG_DATA_ENTRY
  1406          ------------------       note: usesection lDEBUG_DATA_ENTRY
  1407                                  
  1408                                  		; Word table operatordispatchers: order as in string operators
  1409                                  		; Pointed functions dispatch depending on operator characters
  1410                                  		; Return: operator index, 0 = invalid
  1411                                  
  1412                                  		; Word table operator_default_indexes: order as in string operators
  1413                                  		; Default INP:bx for operator dispatchers functions.
  1414                                  		; This is used to optimise the operator dispatchers.
  1415                                  
  1416                                  		; Word table operator_default_strings: order as in string operators
  1417                                  		; Default INP:dx for operator dispatchers functions.
  1418                                  		; This is used to optimise the operator dispatchers.
  1419                                  
  1420                                  		; Operator index (byte):
  1421                                  		; 0 = invalid, no operator found
  1422                                  		; 1.. = 1-based index in byte table operatorprecedences
  1423                                  		;     = 1-based index in word table operatorfunctions
  1424                                  		;     = 1-based index in word table operatornames
  1425                                  
  1426                                  %include "exprops.mac"
     1                              <1> 
     2                              <1> %if 0
     3                              <1> 
     4                              <1> lDebug expression evaluator macros
     5                              <1> 
     6                              <1> Copyright (C) 2008-2026 E. C. Masloch
     7                              <1> 
     8                              <1> Usage of the works is permitted provided that this
     9                              <1> instrument is retained with the works, so that any entity
    10                              <1> that uses the works is notified of this instrument.
    11                              <1> 
    12                              <1> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    13                              <1> 
    14                              <1> %endif
    15                              <1> 
    16                              <1> 	struc opprecs
    17 00000000 ??                  <1> OPPREC_INVALID:	resb 1
    18 00000001 ??                  <1> OPPREC_COND:	resb 1
    19 00000002 ??                  <1> OPPREC_BOOL_OR:	resb 1
    20 00000003 ??                  <1> OPPREC_BOOL_XOR:resb 1
    21 00000004 ??                  <1> OPPREC_BOOL_AND:resb 1
    22 00000005 ??                  <1> OPPREC_COMPARE:	resb 1
    23 00000006 ??                  <1> OPPREC_BIT_OR:	resb 1
    24 00000007 ??                  <1> OPPREC_BIT_XOR:	resb 1
    25 00000008 ??                  <1> OPPREC_BIT_AND:	resb 1
    26 00000009 ??                  <1> OPPREC_BIT_CLR:	resb 1
    27 0000000A ??                  <1> OPPREC_SHIFT:	resb 1
    28 0000000B ??                  <1> OPPREC_ADDSUB:	resb 1
    29 0000000C ??                  <1> OPPREC_MULDIV:	resb 1
    30 0000000D ??                  <1> OPPREC_POWER:	resb 1
    31                              <1> OPPREC_RIGHTOP:		; (to process it first in getexpression)
    32                              <1> 	endstruc
    33                              <1> 		; The number of precedence levels indicates how many
    34                              <1> 		; intermediate results getexpression might have to save
    35                              <1> 		; on its stack. With thirteen levels of precedence, up to
    36                              <1> 		; twelve intermediate results are pushed by getexpression.
    37                              <1> 		; (With 6 bytes each, that gives a moderate 72 bytes.)
    38                              <1> 		; Key to this is that, in case of a low enough operator
    39                              <1> 		; behind the one that triggered the pushing, the pushed
    40                              <1> 		; value will be popped before proceeding. This way more
    41                              <1> 		; intermediate results may be pushed later but the stack
    42                              <1> 		; never holds intermediate results that don't need to be
    43                              <1> 		; on the stack.
    44                              <1> 
    45                              <1> 		; This is the definition of operator index values. The tables
    46                              <1> 		; operatorprecedences and operatorfunctions are ordered by this.
    47                              <1> 		; The operator dispatchers return one of these.
    48                              <1> 	struc ops
    49 00000000 ??                  <1> OPERATOR_INVALID:		resb 1	; 0 - invalid
    50 00000001 ??                  <1> OPERATOR_PLUS:			resb 1	; +
    51 00000002 ??                  <1> OPERATOR_MINUS:			resb 1	; -
    52 00000003 ??                  <1> OPERATOR_MULTIPLY:		resb 1	; *
    53 00000004 ??                  <1> OPERATOR_DIVIDE:		resb 1	; /
    54 00000005 ??                  <1> OPERATOR_MODULO:		resb 1	; %
    55 00000006 ??                  <1> OPERATOR_POWER:			resb 1	; **
    56 00000007 ??                  <1> OPERATOR_CMP_BELOW:		resb 1	; <
    57 00000008 ??                  <1> OPERATOR_CMP_BELOW_EQUAL:	resb 1	; <=
    58 00000009 ??                  <1> OPERATOR_CMP_ABOVE:		resb 1	; >
    59 0000000A ??                  <1> OPERATOR_CMP_ABOVE_EQUAL:	resb 1	; >=
    60 0000000B ??                  <1> OPERATOR_CMP_EQUAL:		resb 1	; ==
    61 0000000C ??                  <1> OPERATOR_CMP_NOT_EQUAL:		resb 1	; !=
    62 0000000D ??                  <1> OPERATOR_SHIFT_LEFT:		resb 1	; <<
    63 0000000E ??                  <1> OPERATOR_SHIFT_RIGHT:		resb 1	; >>
    64 0000000F ??                  <1> OPERATOR_SHIFT_RIGHT_SIGNED:	resb 1	; >>>
    65 00000010 ??                  <1> OPERATOR_BIT_MIRROR:		resb 1	; ><
    66 00000011 ??                  <1> OPERATOR_BIT_CLR:		resb 1	; clr (bitwise AND with bitwise NOT)
    67 00000012 ??                  <1> OPERATOR_BIT_OR:		resb 1	; |
    68 00000013 ??                  <1> OPERATOR_BIT_XOR:		resb 1	; ^
    69 00000014 ??                  <1> OPERATOR_BIT_AND:		resb 1	; &
    70 00000015 ??                  <1> OPERATOR_BOOL_OR:		resb 1	; ||
    71 00000016 ??                  <1> OPERATOR_BOOL_XOR:		resb 1	; ^^
    72 00000017 ??                  <1> OPERATOR_BOOL_AND:		resb 1	; &&
    73 00000018 ??                  <1> OPERATOR_COND:			resb 1	; ?? :: construct (special)
    74 00000019 ??                  <1> OPERATOR_RIGHTOP:		resb 1	; (dummy right-operand operator)
    75                              <1> 	endstruc
    76                              <1> 		; Order of BIT_* needs to be the same as that of BOOL_*.
    77                              <1> 		; BOOL_* have to follow directly behind BIT_*.
    78                              <1> 		; "R CF op= expr" depends on that (rr4 in rr.asm).
  1427                                  
  1428                                  
  1429                                  		; Dispatch table for (binary) expression operators,
  1430                                  		;  used by getexpression.
  1431                                  		; Functions in this table are called with:
  1432                                  		; INP:	al = operator character (which is also implicit)
  1433                                  		;	si-> remaining line (directly) behind operator character
  1434                                  		;	bx = value from operator_default_indexes
  1435                                  		;	dx = value from operator_default_strings,
  1436                                  		;	 random value if unused (the table is truncated)
  1437                                  		; OUT:	bl != 0 if a valid operator,
  1438                                  		;	 bl = operator index
  1439                                  		;	 si-> behind the last character belonging to the operator
  1440                                  		;	bl = 0 if no valid operator
  1441                                  		; CHG:	al, bh, dx
  1442                                  		; REM:	Dispatch table in section lDEBUG_CODE or lDEBUG_CODE2
  1443                                  	align 2, db 0
  1444                                  operatordispatchers:
  1445                                  .:
  1446 0000006A [D405]                  	dw od_o			; o
  1447 0000006C [D405]                  	dw od_o			; O
  1448 0000006E [D405]                  	dw od_a			; a
  1449 00000070 [D405]                  	dw od_a			; A
  1450 00000072 [D405]                  	dw od_x			; x
  1451 00000074 [D405]                  	dw od_x			; X
  1452 00000076 [D405]                  	dw od_c			; c
  1453 00000078 [D405]                  	dw od_c			; C
  1454 0000007A [D405]                  	dw od_cond		; ?
  1455                                  
  1456 0000007C [D305]                  	dw od_plus		; +
  1457 0000007E [D305]                  	dw od_minus		; -
  1458 00000080 [7B05]                  	dw od_multiply		; * **
  1459 00000082 [D305]                  	dw od_divide		; /
  1460 00000084 [D305]                  	dw od_modulo		; %
  1461 00000086 [A205]                  	dw od_below		; < <> <= <<
  1462 00000088 [8305]                  	dw od_above		; > >< >= >> >>>
  1463 0000008A [B505]                  	dw od_equal		; == =< =>
  1464 0000008C [C305]                  	dw od_not		; !=
  1465 0000008E [CB05]                  	dw od_or		; | ||
  1466 00000090 [CB05]                  	dw od_and		; & &&
  1467 00000092 [CB05]                  	dw od_xor		; ^ ^^
  1468                                  .end: equ $ - .
  1469                                  .amount: equ ($ - .) / 2
  1470                                  %if .amount != operators.amount
  1471                                   %error String and table mismatch
  1472                                  %endif
  1473                                  %if .amount > 100h
  1474                                   %error Too many operator dispatchers
  1475                                  %endif
  1476                                  
  1477                                  
  1478                                  	align 2, db 0
  1479                                  operator_default_indexes:
  1480                                  .:
  1481 00000094 1200                    	dw OPERATOR_BIT_OR	; o
  1482 00000096 1200                    	dw OPERATOR_BIT_OR	; O
  1483 00000098 1400                    	dw OPERATOR_BIT_AND	; a
  1484 0000009A 1400                    	dw OPERATOR_BIT_AND	; A
  1485 0000009C 1300                    	dw OPERATOR_BIT_XOR	; x
  1486 0000009E 1300                    	dw OPERATOR_BIT_XOR	; X
  1487 000000A0 1100                    	dw OPERATOR_BIT_CLR	; c
  1488 000000A2 1100                    	dw OPERATOR_BIT_CLR	; C
  1489 000000A4 1800                    	dw OPERATOR_COND	; ?
  1490                                  
  1491 000000A6 0100                    	dw OPERATOR_PLUS	; +
  1492 000000A8 0200                    	dw OPERATOR_MINUS	; -
  1493 000000AA 0300                    	dw OPERATOR_MULTIPLY	; * **
  1494 000000AC 0400                    	dw OPERATOR_DIVIDE	; /
  1495 000000AE 0500                    	dw OPERATOR_MODULO	; %
  1496 000000B0 0C00                    	dw OPERATOR_CMP_NOT_EQUAL ; < <> <= <<
  1497 000000B2 0900                    	dw OPERATOR_CMP_ABOVE	; > >< >= >> >>>
  1498 000000B4 0B00                    	dw OPERATOR_CMP_EQUAL	; == =< =>
  1499 000000B6 0C00                    	dw OPERATOR_CMP_NOT_EQUAL ; !=
  1500 000000B8 1200                    	dw OPERATOR_BIT_OR	; | ||
  1501 000000BA 1400                    	dw OPERATOR_BIT_AND	; & &&
  1502 000000BC 1300                    	dw OPERATOR_BIT_XOR	; ^ ^^
  1503                                  .end: equ $ - .
  1504                                  .amount: equ ($ - .) / 2
  1505                                  %if .amount != operators.amount
  1506                                   %error String and table mismatch
  1507                                  %endif
  1508                                  %if .amount > 100h
  1509                                   %error Too many operator dispatchers
  1510                                  %endif
  1511                                  
  1512                                  
  1513                                  	align 2, db 0
  1514                                  operator_default_strings:
  1515                                  .:
  1516 000000BE [0000]                  	dw msg.r	; o
  1517 000000C0 [0000]                  	dw msg.r	; O
  1518 000000C2 [0000]                  	dw msg.nd	; a
  1519 000000C4 [0000]                  	dw msg.nd	; A
  1520 000000C6 [0000]                  	dw msg.or	; x
  1521 000000C8 [0000]                  	dw msg.or	; X
  1522 000000CA [0000]                  	dw msg.lr	; c
  1523 000000CC [0000]                  	dw msg.lr	; C
  1524 000000CE [0000]                  	dw msg.questionmark	; ?
  1525                                  .end: equ $ - .
  1526                                  .amount: equ ($ - .) / 2
  1527                                  %if .amount > operators.amount
  1528                                   %error String and table mismatch
  1529                                  %endif
  1530                                  %if .amount > 100h
  1531                                   %error Too many operator dispatchers
  1532                                  %endif
  1533                                  
  1534                                  
  1535                                  operatorprecedences:
  1536                                  .:
  1537 000000D0 00                      	db OPPREC_INVALID		; need this for some checks
  1538 000000D1 0B                      	db OPPREC_ADDSUB		; +
  1539 000000D2 0B                      	db OPPREC_ADDSUB		; -
  1540 000000D3 0C                      	db OPPREC_MULDIV		; *
  1541 000000D4 0C                      	db OPPREC_MULDIV		; /
  1542 000000D5 0C                      	db OPPREC_MULDIV		; %
  1543 000000D6 0D                      	db OPPREC_POWER			; **
  1544 000000D7 05                      	db OPPREC_COMPARE		; <
  1545 000000D8 05                      	db OPPREC_COMPARE		; <=
  1546 000000D9 05                      	db OPPREC_COMPARE		; >
  1547 000000DA 05                      	db OPPREC_COMPARE		; >=
  1548 000000DB 05                      	db OPPREC_COMPARE		; ==
  1549 000000DC 05                      	db OPPREC_COMPARE		; !=
  1550 000000DD 0A                      	db OPPREC_SHIFT			; <<
  1551 000000DE 0A                      	db OPPREC_SHIFT			; >>
  1552 000000DF 0A                      	db OPPREC_SHIFT			; >>>
  1553 000000E0 0A                      	db OPPREC_SHIFT			; ><
  1554 000000E1 09                      	db OPPREC_BIT_CLR		; clr
  1555 000000E2 06                      	db OPPREC_BIT_OR		; |
  1556 000000E3 07                      	db OPPREC_BIT_XOR		; ^
  1557 000000E4 08                      	db OPPREC_BIT_AND		; &
  1558 000000E5 02                      	db OPPREC_BOOL_OR		; ||
  1559 000000E6 03                      	db OPPREC_BOOL_XOR		; ^^
  1560 000000E7 04                      	db OPPREC_BOOL_AND		; &&
  1561 000000E8 01                      	db OPPREC_COND			; ?? :: construct
  1562 000000E9 0E                      	db OPPREC_RIGHTOP		; getexpression: no number yet
  1563                                  .amount: equ $ - .
  1564                                  %if .amount != ops_size
  1565                                   %error Operators table size mismatch
  1566                                  %endif
  1567                                  
  1568                                  
  1569                                  		; REM:	Dispatch table in section lDEBUG_CODE or lDEBUG_CODE2
  1570                                  	align 2, db 0
  1571                                  operatorfunctions:
  1572                                  .:
  1573 000000EA [0000]                  	dw error_expr			; should not be called
  1574 000000EC [0106]                  	dw of_plus			; +
  1575 000000EE [FE05]                  	dw of_minus			; -
  1576 000000F0 [0E06]                  	dw of_multiply			; *
  1577 000000F2 [3406]                  	dw of_divide			; /
  1578 000000F4 [DE05]                  	dw of_modulo			; %
  1579 000000F6 [CE06]                  	dw of_power			; **
  1580 000000F8 [2707]                  	dw of_compare_below		; <
  1581 000000FA [2107]                  	dw of_compare_below_equal	; <=
  1582 000000FC [3F07]                  	dw of_compare_above		; >
  1583 000000FE [3907]                  	dw of_compare_above_equal	; >=
  1584 00000100 [3307]                  	dw of_compare_equal		; ==
  1585 00000102 [2D07]                  	dw of_compare_not_equal		; !=
  1586 00000104 [7A07]                  	dw of_shift_left		; <<
  1587 00000106 [6207]                  	dw of_shift_right		; >>
  1588 00000108 [6E07]                  	dw of_shift_right_signed	; >>>
  1589 0000010A [A107]                  	dw of_bit_mirror		; ><
  1590 0000010C [FE07]                  	dw of_clr_bitwise		; clr
  1591 0000010E [EC07]                  	dw of_or_bitwise		; |
  1592 00000110 [1308]                  	dw of_xor_bitwise		; ^
  1593 00000112 [0208]                  	dw of_and_bitwise		; &
  1594 00000114 [F707]                  	dw of_or_boolean		; ||
  1595 00000116 [1D08]                  	dw of_xor_boolean		; ^^
  1596 00000118 [0C08]                  	dw of_and_boolean		; &&
  1597 0000011A [B114]                  	dw of_cond			; ?? :: construct
  1598 0000011C [4F07]                  	dw of_rightop			; set to right operand
  1599                                  .amount: equ ($ - .) / 2
  1600                                  %if .amount != ops_size
  1601                                   %error Operators table size mismatch
  1602                                  %endif
  1603                                  
  1604                                  
  1605                                  %if _EXPRESSION_DEBUG
  1606                                  
  1607                                  %define OPNAMES db ""
  1608                                  %macro opname 1.nolist
  1609                                  %defstr %%string %1
  1610                                  %substr %%prefix %%string 1,3
  1611                                  %ifidni %%prefix, "of_"
  1612                                   %substr %%string %%string 4,-1
  1613                                  %endif
  1614                                  %xdefine OPNAMES OPNAMES,%%name:,{asciz %%string}
  1615                                  	dw %%name
  1616                                  %endmacro
  1617                                  
  1618                                  %macro opnamesstrings 1-*
  1619                                   %rep %0
  1620                                  %1
  1621                                    %rotate 1
  1622                                   %endrep
  1623                                  %endmacro
  1624                                  
  1625                                  	align 2, db 0
  1626                                  operatornames:
  1627                                  .:
  1628                                  	opname invalid			; invalid
  1629                                  	opname of_plus			; +
  1630                                  	opname of_minus			; -
  1631                                  	opname of_multiply		; *
  1632                                  	opname of_divide		; /
  1633                                  	opname of_modulo		; %
  1634                                  	opname of_power			; **
  1635                                  	opname of_compare_below		; <
  1636                                  	opname of_compare_below_equal	; <=
  1637                                  	opname of_compare_above		; >
  1638                                  	opname of_compare_above_equal	; >=
  1639                                  	opname of_compare_equal		; ==
  1640                                  	opname of_compare_not_equal		; !=
  1641                                  	opname of_shift_left		; <<
  1642                                  	opname of_shift_right		; >>
  1643                                  	opname of_shift_right_signed	; >>>
  1644                                  	opname of_bit_mirror		; ><
  1645                                  	opname of_clr_bitwise		; clr
  1646                                  	opname of_or_bitwise		; |
  1647                                  	opname of_xor_bitwise		; ^
  1648                                  	opname of_and_bitwise		; &
  1649                                  	opname of_or_boolean		; ||
  1650                                  	opname of_xor_boolean		; ^^
  1651                                  	opname of_and_boolean		; &&
  1652                                  	opname of_cond			; ?? :: construct
  1653                                  	opname right			; set to right operand
  1654                                  .amount: equ ($ - .) / 2
  1655                                  %if .amount != ops_size
  1656                                   %error Operators table size mismatch
  1657                                  %endif
  1658                                  
  1659                                  	opnamesstrings OPNAMES
  1660                                  %endif
  1661                                  
  1662                                  %if _EXPRDUALCODE && _DUALCODE
  1663                                  	usesection lDEBUG_CODE2
  1663          ------------------       note: usesection lDEBUG_CODE2
  1664                                  %else
  1665                                  	usesection lDEBUG_CODE
  1666                                  %endif
  1667                                  
  1668                                  
  1669                                  od_multiply: section_of_function
  1670 0000057B 3804                    	cmp byte [si], al
  1671 0000057D 7503                    	jne .ret
  1672 0000057F 46                      	inc si
  1673 00000580 B306                    	mov bl, OPERATOR_POWER
  1674                                  .ret:
  1675 00000582 C3                      	retn
  1676                                  
  1677                                  od_above: section_of_function
  1678 00000583 3804                    	cmp byte [si], al
  1679 00000585 740E                    	je .shr
  1680 00000587 803C3C                  	cmp byte [si], '<'
  1681 0000058A 7412                    	je .mirror
  1682 0000058C 803C3D                  	cmp byte [si], '='
  1683 0000058F 7542                    	jne od_retn
  1684                                  .cmp_ae:
  1685 00000591 46                      	inc si
  1686 00000592 B30A                    	mov bl, OPERATOR_CMP_ABOVE_EQUAL
  1687 00000594 C3                      	retn
  1688                                  .shr:
  1689 00000595 46                      	inc si
  1690 00000596 3804                    	cmp byte [si], al
  1691 00000598 B30F                    	mov bl, OPERATOR_SHIFT_RIGHT_SIGNED
  1692 0000059A 7404                    	je .inc_si
  1693                                  %if OPERATOR_SHIFT_RIGHT_SIGNED - 1 != OPERATOR_SHIFT_RIGHT
  1694                                   %error Unexpected layout
  1695                                  %endif
  1696 0000059C 4B                      	dec bx			; = OPERATOR_SHIFT_RIGHT
  1697 0000059D C3                      	retn
  1698                                  .mirror:
  1699 0000059E B310                    	mov bl, OPERATOR_BIT_MIRROR
  1700                                  .inc_si:
  1701 000005A0 46                      	inc si
  1702 000005A1 C3                      	retn
  1703                                  
  1704                                  od_below: section_of_function
  1705 000005A2 3804                    	cmp byte [si], al
  1706 000005A4 740C                    	je .shl
  1707 000005A6 803C3E                  	cmp byte [si], '>'
  1708 000005A9 7408                    	je .ncmp		; (default index)
  1709 000005AB B307                    	mov bl, OPERATOR_CMP_BELOW
  1710 000005AD 803C3D                  	cmp byte [si], '='
  1711 000005B0 7521                    	jne short od_retn
  1712                                  
  1713                                  .cmp_be:			; bl = OPERATOR_CMP_BELOW_EQUAL
  1714                                  %if OPERATOR_CMP_BELOW + 1 != OPERATOR_CMP_BELOW_EQUAL
  1715                                   %error Unexpected layout
  1716                                  %endif
  1717                                  .shl:				; bl = OPERATOR_SHIFT_LEFT
  1718                                  %if OPERATOR_CMP_NOT_EQUAL + 1 != OPERATOR_SHIFT_LEFT
  1719                                   %error Unexpected layout
  1720                                  %endif
  1721 000005B2 43                      	inc bx
  1722                                  .ncmp:
  1723                                  od_not.ncmp:
  1724                                  od_equal.inc_si:
  1725 000005B3 46                      	inc si
  1726 000005B4 C3                      	retn
  1727                                  
  1728                                  od_equal: section_of_function
  1729 000005B5 803C3E                  	cmp byte [si], '>'
  1730 000005B8 74D7                    	je od_above.cmp_ae
  1731 000005BA 803C3C                  	cmp byte [si], '<'
  1732 000005BD 74F3                    	je od_below.cmp_be
  1733 000005BF 3804                    	cmp byte [si], al
  1734 000005C1 74F0                    	je .inc_si
  1735                                  				; no valid operator
  1736                                  		; fall through, next cmp is also a mismatch
  1737                                  
  1738                                  od_not: section_of_function
  1739 000005C3 803C3D                  	cmp byte [si], '='
  1740 000005C6 74EB                    	je .ncmp		; (default index)
  1741                                  od_equal.invalid:
  1742                                  od_string_common.invalid:
  1743 000005C8 B300                    	mov bl, OPERATOR_INVALID
  1744 000005CA C3                      	retn
  1745                                  
  1746                                  od_or: section_of_function
  1747                                  od_and: section_of_function
  1748                                  od_xor: section_of_function
  1749 000005CB 3804                    	cmp byte [si], al
  1750 000005CD 7504                    	jne od_retn
  1751 000005CF 46                      	inc si
  1752                                  %if OPERATOR_BOOL_XOR - OPERATOR_BIT_XOR != OPERATOR_BOOL_AND - OPERATOR_BIT_AND
  1753                                   %error Unexpected layout
  1754                                  %endif
  1755                                  %if OPERATOR_BOOL_XOR - OPERATOR_BIT_XOR != OPERATOR_BOOL_OR - OPERATOR_BIT_OR
  1756                                   %error Unexpected layout
  1757                                  %endif
  1758 000005D0 80C303                  	add bl, OPERATOR_BOOL_XOR - OPERATOR_BIT_XOR
  1759                                  
  1760                                  od_minus: section_of_function
  1761                                  od_plus: section_of_function
  1762                                  od_divide: section_of_function
  1763                                  od_modulo: section_of_function
  1764                                  od_retn: section_of_function
  1765 000005D3 C3                      	retn
  1766                                  
  1767                                  od_cond: section_of_function
  1768                                  od_o: section_of_function
  1769                                  od_a: section_of_function
  1770                                  od_x: section_of_function
  1771                                  od_c: section_of_function
  1772                                  od_string_common: section_of_function
  1773 000005D4 E8(0000)EB02[0000]      	nearcall isstring?
  1774 000005DB 75EB                    	jne .invalid
  1775 000005DD C3                      	retn
  1776                                  
  1777                                  
  1778                                  		; (Binary) Expression operator functions,
  1779                                  		;  used by getexpression.
  1780                                  		; These functions are called with:
  1781                                  		; INP:	dword [hhvar] = previous number (left-hand operand)
  1782                                  		;	byte [hhtype] = previous type
  1783                                  		;	bx:dx = following number (right-hand operand)
  1784                                  		;	ah = following type
  1785                                  		; OUT:	bx:dx = result
  1786                                  		;	ah = type
  1787                                  		; CHG:	ax, cx
  1788                                  		; Note:	Errors (divisor zero) are currently simply handled
  1789                                  		;	 by jumping to "error".
  1790                                  		;	getexpression mustn't be called after until hhvar is
  1791                                  		;	 no longer used, as the call might overwrite hhvar.
  1792                                  		;
  1793                                  		; Type info (in ah and b[hhtype]) appears to be correctly
  1794                                  		; passed to here already. However, how should that be used?
  1795                                  		;
  1796                                  		; Quite simply, doing any arithmetic on two unsigned numbers
  1797                                  		; could return the smallest possible unsigned type (so that
  1798                                  		; if the result is <= 255 then the type is 1, if <= 65536
  1799                                  		; then the type is 2, else the type is 4).
  1800                                  		;
  1801                                  		; Handling two signed numbers here might be equally simple:
  1802                                  		; if the result is >= -128 && <= 127 then the type is 81h,
  1803                                  		; if the result is >= -32768 && <= 32767 then the type is
  1804                                  		; 82h, otherwise the type is 84h. Have to look into this.
  1805                                  		; (How does this interact with the unsignedness of the
  1806                                  		; actual computations?)
  1807                                  		;
  1808                                  		; It gets hairy when one operand is signed and the other
  1809                                  		; isn't; generally, two sub-cases of this exist: first, the
  1810                                  		; signed operand is positive, second, the signed operand is
  1811                                  		; negative. (Whether this distinction actually makes sense
  1812                                  		; for the implementation is still to be determined.)
  1813                                  		; Possible models:
  1814                                  		; * Result is always signed.
  1815                                  		; * Result is always unsigned(?!).
  1816                                  		; * Result is treated as signed, but if it's positive its
  1817                                  		;   type is changed to unsigned.
  1818                                  		;
  1819                                  		; It is also possible that operators could be handled
  1820                                  		; differently, for example, (some) bit and boolean
  1821                                  		; operators could imply unsigned operands in any case.
  1822                                  		; (>>> obviously implies a signed left operand already.)
  1823                                  		;
  1824                                  		; Note that (signed) negative bit shifting counts could
  1825                                  		; imply reversing the operation; << becomes >> and such.
  1826                                  		;
  1827                                  		; Note that for the addition of, for example, bit rotation,
  1828                                  		; it would be useful to retain the originally used type
  1829                                  		; inside getdword. At the end of getdword, the current bit
  1830                                  		; counting could be changed to use the "signed" bit of the
  1831                                  		; types and then determine which signed or unsigned type is
  1832                                  		; large enough to hold the value. (It might already work
  1833                                  		; mostly like that.) (Is this specifically about binary
  1834                                  		; operators? - No. In fact, binary operators are the most
  1835                                  		; likely to be (one of) the syntactic element(s) which
  1836                                  		; should change (and possible 'optimize') types. - Then
  1837                                  		; this might still apply to unary operators, and brackets
  1838                                  		; and parentheses. In particular, the later should call
  1839                                  		; a different entry or instruct getdword not to optimize
  1840                                  		; the type at the end so as to retain it. - Although in
  1841                                  		; cases where that matters, the parentheses are arguably
  1842                                  		; unnecessary, aren't they?)
  1843                                  		;
  1844                                  		; It has to be decided whether there should be implicit
  1845                                  		; dispatching based on the operands' types' signedness.
  1846                                  		; For example, currently (with all operands being implied
  1847                                  		; to be unsigned) there exist >> and >>>, and there could
  1848                                  		; exist > and S>. With implicit signedness dispatching, the
  1849                                  		; behaviour of >> would change: it would expose the current
  1850                                  		; >>'s behaviour with an unsigned (left) operand, and the
  1851                                  		; current >>>'s behaviour with a signed (left) operand.
  1852                                  		; (Either U(nsigned)>> and S(igned)>> operators could then
  1853                                  		; exist, which would imply an unsigned or signed left
  1854                                  		; operand respectively, or the affected operands' signedness
  1855                                  		; could be changed with the currently available prefix or
  1856                                  		; possible new postfix unary operators.
  1857                                  of_modulo: section_of_function
  1858 000005DE FF36[960C]              	push word [hhvar+2]
  1859 000005E2 FF36[940C]              	push word [hhvar]
  1860 000005E6 53                      	push bx
  1861 000005E7 52                      	push dx
  1862 000005E8 E86D00                  	call of_divide.no_hh_div; bx:dx := prev / foll
  1863 000005EB 8F06[940C]              	pop word [hhvar]
  1864 000005EF 8F06[960C]              	pop word [hhvar+2]
  1865 000005F3 E81800                  	nearcall of_multiply	; bx:dx := (prev / foll) * foll
  1866 000005F6 8F06[940C]              	pop word [hhvar]
  1867 000005FA 8F06[960C]              	pop word [hhvar+2]
  1868                                  ;	jmp short of_minus	; bx:dx := prev - ((prev / foll) * foll)
  1869                                  
  1870                                  of_minus: section_of_function
  1871 000005FE E862FF                  	nearcall calculate_minus_bxdx
  1872                                  of_plus: section_of_function
  1873 00000601 0316[940C]              	add dx, word [hhvar]
  1874 00000605 131E[960C]              	adc bx, word [hhvar+2]
  1875                                  or_hhtype: section_of_function
  1876 00000609 0A26[A50C]              	or ah, byte [hhtype]
  1877 0000060D C3                      	retn
  1878                                  
  1879                                  of_multiply: section_of_function; bx:dx := var * bx:dx
  1880 0000060E 0826[A50C]              	or byte [hhtype], ah
  1881 00000612 57                      	push di			; di is used as temporary storage
  1882 00000613 89D0                    	mov ax, dx		; low word
  1883 00000615 50                      	push ax			; save low word
  1884 00000616 F726[940C]              	mul word [hhvar]	; low * low
  1885 0000061A 97                      	xchg di, ax		; di = low word result, clobber ax
  1886 0000061B 58                      	pop ax
  1887 0000061C 53                      	 push bx
  1888 0000061D 89D3                    	mov bx, dx		; bx = high word result 1
  1889 0000061F F726[960C]              	mul word [hhvar+2]	; low * high
  1890 00000623 01C3                    	add bx, ax		; bx = high word result 1 plus low * high
  1891 00000625 58                      	 pop ax			; high word
  1892 00000626 F726[940C]              	mul word [hhvar]
  1893 0000062A 01C3                    	add bx, ax		; bx = high word result
  1894                                  	; bx*[hhvar+2] not required, completely overflows
  1895 0000062C 89FA                    	mov dx, di		; dx = low word result
  1896 0000062E 5F                      	pop di			; restore those
  1897                                  set_hhtype: section_of_function
  1898 0000062F 8A26[A50C]              	mov ah, byte [hhtype]
  1899 00000633 C3                      	retn
  1900                                  
  1901                                  of_divide: section_of_function	; bx:dx := var / bx:dx
  1902                                  %if _HHDIVREMAIN
  1903 00000634 833E[A00C]01            	cmp word [hh_depth], 1
  1904 00000639 751D                    	jne @F
  1905 0000063B C606[A60C]FF            	mov byte [hh_div_active], -1
  1906 00000640 8916[9C0C]              	mov word [hh_div_divisor], dx
  1907 00000644 891E[9E0C]              	mov word [hh_div_divisor + 2], bx
  1908 00000648 FF36[960C]              	push word [hhvar + 2]
  1909 0000064C FF36[940C]              	push word [hhvar]
  1910 00000650 8F06[980C]              	pop word [hh_div_dividend]
  1911 00000654 8F06[9A0C]              	pop word [hh_div_dividend + 2]
  1912                                  @@:
  1913                                  %endif
  1914                                  .no_hh_div:
  1915 00000658 0826[A50C]              	or byte [hhtype], ah
  1916 0000065C 53                      	 push bx
  1917 0000065D 09D3                    	or bx, dx		; divisor zero ?
  1918 0000065F 5B                      	 pop bx
  1919 00000660 7448                    	jz short .error		; divisor zero !
  1920 00000662 EB49                    	_386_jmps .32		; 386, use 32-bit code -->
  1921                                  %ifn _ONLY386
  1922 00000664 85DB                    	test bx, bx		; need only 16-bit divisor ?
  1923 00000666 7512                    	jnz .difficultdiv16	; nope -->
  1924 00000668 89D1                    	mov cx, dx
  1925 0000066A 31D2                    	xor dx, dx
  1926 0000066C A1[960C]                	mov ax, word [hhvar+2]	; dx:ax = high word of previous number
  1927 0000066F F7F1                    	div cx
  1928 00000671 93                      	xchg bx, ax		; bx = ax, clobber ax
  1929 00000672 A1[940C]                	mov ax, word [hhvar]	; ax = low word of previous number, dx = remainder
  1930 00000675 F7F1                    	div cx
  1931 00000677 92                      	xchg dx, ax		; bx:dx = result, clobber ax
  1932 00000678 EBB5                    	jmp set_hhtype
  1933                                  
  1934                                  .difficultdiv16:		; code adapted from Art of Assembly chapter 9
  1935                                  				; refer to http://www.plantation-productions.com/Webster/www.artofasm.com/DOS/ch09/CH09-4.html#HEADING4-99
  1936 0000067A B92000                  	mov cx, 32
  1937 0000067D 55                      	push bp
  1938 0000067E 56                      	push si
  1939 0000067F 57                      	push di
  1940 00000680 A1[940C]                	mov ax, word [hhvar]
  1941 00000683 8B2E[960C]              	mov bp, word [hhvar+2]	; bp:ax = previous number
  1942 00000687 31FF                    	xor di, di
  1943 00000689 31F6                    	xor si, si		; clear variable si:di
  1944 0000068B 92                      	xchg ax, dx
  1945 0000068C 87EB                    	xchg bp, bx		; bx:dx = previous number, bp:ax = divisor
  1946                                  .bitloop:
  1947 0000068E D1E2                    	shl dx, 1
  1948 00000690 D1D3                    	rcl bx, 1
  1949 00000692 D1D7                    	rcl di, 1
  1950 00000694 D1D6                    	rcl si, 1		; si:di:bx:dx << 1
  1951 00000696 39EE                    	cmp si, bp		; does the divisor fit into si:di here ?
  1952 00000698 7502                    	jne @F
  1953 0000069A 39C7                    	cmp di, ax
  1954                                  @@:
  1955 0000069C 7205                    	jb .trynext		; no -->
  1956                                  .goesinto:
  1957 0000069E 29C7                    	sub di, ax
  1958 000006A0 19EE                    	sbb si, bp		; subtract divisor
  1959 000006A2 42                      	inc dx			; set a bit of the result (bit was zero before, never carries)
  1960                                  .trynext:
  1961 000006A3 E2E9                    	loop .bitloop		; loop for 32 bits
  1962 000006A5 5F                      	pop di
  1963 000006A6 5E                      	pop si
  1964 000006A7 5D                      	pop bp
  1965 000006A8 EB85                    	jmp set_hhtype
  1966                                  %endif
  1967                                  
  1968                                  .error:
  1969 000006AA E953F9                  	jmp error_expr
  1970                                  
  1971                                  %ifn _ONLYNON386
  1972                                  .32:
  1973                                  [cpu 386]
  1974 000006AD 6650                    	push eax
  1975 000006AF 6653                    	push ebx
  1976 000006B1 6652                    	push edx		; to preserve the high words
  1977 000006B3 53                      	 push bx
  1978 000006B4 52                      	 push dx
  1979 000006B5 665B                    	 pop ebx		; ebx = following number
  1980 000006B7 6631D2                  	xor edx, edx
  1981 000006BA 66A1[940C]              	mov eax, dword [hhvar]	; edx:eax = previous number
  1982 000006BE 66F7F3                  	div ebx
  1983 000006C1 665A                    	pop edx
  1984 000006C3 665B                    	pop ebx			; restore high words
  1985 000006C5 6650                    	 push eax
  1986 000006C7 5A                      	 pop dx
  1987 000006C8 5B                      	 pop bx			; bx:dx = result
  1988 000006C9 6658                    	pop eax			; restore high word of eax
  1989                                  __CPU__
  1990 000006CB E961FF                  	jmp set_hhtype
  1991                                  %endif
  1992                                  
  1993                                  
  1994                                  of_power: section_of_function
  1995 000006CE 0826[A50C]              	or byte [hhtype], ah
  1996 000006D2 89D9                    	mov cx, bx
  1997 000006D4 89D0                    	mov ax, dx		; get exponent
  1998 000006D6 09D3                    	or bx, dx		; exponent zero ?
  1999 000006D8 BB0000                  	mov bx, 0
  2000 000006DB BA0100                  	mov dx, 1
  2001 000006DE 743E                    	jz .ret			; yes, return with result as 1 -->
  2002 000006E0 3916[940C]              	cmp word [hhvar], dx	; optimization:
  2003 000006E4 7506                    	jne .notone
  2004 000006E6 391E[960C]              	cmp word [hhvar+2], bx
  2005 000006EA 7432                    	je .ret			; if base is one (and exponent not zero), result is 1 -->
  2006                                  .notone:
  2007 000006EC 55                      	push bp
  2008                                  
  2009                                  .loop:				; cx:ax non-zero here
  2010 000006ED D1E9                    	shr cx, 1
  2011 000006EF D1D8                    	rcr ax, 1		; exponent /= 2
  2012 000006F1 50                      	push ax
  2013 000006F2 51                      	push cx
  2014 000006F3 7303                    	jnc .even		; if exponent was even -->
  2015 000006F5 E816FF                  	nearcall of_multiply	; var *= base
  2016                                  .even:
  2017                                  		; In the last iteration, cx:ax might be zero here
  2018                                  		; making the next call unnecessary. Oh well.
  2019 000006F8 53                      	push bx
  2020 000006F9 52                      	push dx
  2021 000006FA 8B1E[960C]              	mov bx, word [hhvar+2]
  2022 000006FE 8B16[940C]              	mov dx, word [hhvar]	; base
  2023 00000702 E809FF                  	nearcall of_multiply	;  * base = base squared
  2024 00000705 891E[960C]              	mov word [hhvar+2], bx
  2025 00000709 8916[940C]              	mov word [hhvar], dx	; store as new base
  2026 0000070D 5A                      	pop dx
  2027 0000070E 5B                      	pop bx
  2028 0000070F 59                      	pop cx
  2029 00000710 58                      	pop ax
  2030                                  
  2031 00000711 89DD                    	mov bp, bx		; optimization:
  2032 00000713 09D5                    	or bp, dx		;  register now zero ?
  2033 00000715 7406                    	jz .ret_bp		; if so, return now --> (multiplying zero always results in zero)
  2034 00000717 89CD                    	mov bp, cx
  2035 00000719 09C5                    	or bp, ax		; exponent now zero ?
  2036 0000071B 75D0                    	jnz .loop		; no, loop -->
  2037                                  
  2038                                  .ret_bp:
  2039 0000071D 5D                      	pop bp
  2040                                  .ret:
  2041 0000071E E90EFF                  	jmp set_hhtype
  2042                                  
  2043                                  of_compare_below_equal: section_of_function
  2044 00000721 E82C00                  	nearcall of_helper_compare
  2045 00000724 7628                    	jbe of_helper_compare_true
  2046 00000726 C3                      	retn
  2047                                  
  2048                                  of_compare_below: section_of_function
  2049 00000727 E82600                  	nearcall of_helper_compare
  2050 0000072A 7222                    	jb of_helper_compare_true
  2051 0000072C C3                      	retn
  2052                                  
  2053                                  of_compare_not_equal: section_of_function
  2054 0000072D E82000                  	nearcall of_helper_compare
  2055 00000730 751C                    	jne of_helper_compare_true
  2056 00000732 C3                      	retn
  2057                                  
  2058                                  of_compare_equal: section_of_function
  2059 00000733 E81A00                  	nearcall of_helper_compare
  2060 00000736 7416                    	je of_helper_compare_true
  2061 00000738 C3                      	retn
  2062                                  
  2063                                  of_compare_above_equal: section_of_function
  2064 00000739 E81400                  	nearcall of_helper_compare
  2065 0000073C 7310                    	jae of_helper_compare_true
  2066 0000073E C3                      	retn
  2067                                  
  2068                                  of_compare_above: section_of_function
  2069 0000073F E80E00                  	nearcall of_helper_compare
  2070 00000742 770A                    	ja of_helper_compare_true
  2071 00000744 C3                      	retn
  2072                                  
  2073                                  
  2074                                  		; Called by operator functions to convert a number to boolean
  2075                                  		;
  2076                                  		; INP:	bx:dx
  2077                                  		; OUT:	dx = 0 or 1
  2078                                  		;	bx = 0
  2079                                  		;	ZF
  2080                                  toboolean: section_of_function
  2081 00000745 09D3                    	or bx, dx		; = 0 iff it was 0000_0000h
  2082 00000747 83FB01                  	cmp bx, byte 1		; CY iff it was 0000_0000h, else NC
  2083 0000074A 19D2                    	sbb dx, dx		; -1 iff it was 0000_0000h, else 0
  2084 0000074C 31DB                    	xor bx, bx
  2085                                  
  2086                                  		; INP:	dx
  2087                                  		; OUT:	dx += 1
  2088                                  of_helper_compare_true: section_of_function
  2089 0000074E 42                      	inc dx			; bx:dx = 0 iff it was 0000_0000h, else 1
  2090                                  
  2091                                  		; Dummy operator computation function,
  2092                                  		;  used when setting a register without operator (rr)
  2093                                  		;  and to initialize the first getexpression loop iteration
  2094                                  		; INP:	dword [hhvar] = previous number (left-hand operand)
  2095                                  		;	byte [hhtype] = previous type
  2096                                  		;	bx:dx = following number (right-hand operand)
  2097                                  		;	ah = following type
  2098                                  		; OUT:	bx:dx = result (right-hand operand)
  2099                                  		;	ah = type
  2100                                  		; CHG:	ax, cx
  2101                                  of_rightop: section_of_function
  2102 0000074F C3                      	retn
  2103                                  
  2104                                  
  2105                                  		; Called by operator functions to compare operands
  2106                                  		;
  2107                                  		; INP:	dword [hhvar], byte [hhtype]
  2108                                  		;	bx:dx, ah
  2109                                  		; OUT:	Flags as for "cmp d[hhvar], bxdx"
  2110                                  		;	bx:dx = 0
  2111                                  		;	ah = 0
  2112                                  of_helper_compare: section_of_function
  2113 00000750 30E4                    	xor ah, ah		; type signed=0 pointer=0
  2114 00000752 391E[960C]              	cmp word [hhvar+2], bx
  2115 00000756 7504                    	jne .ret
  2116 00000758 3916[940C]              	cmp word [hhvar], dx
  2117                                  .ret:
  2118 0000075C BB0000                  	mov bx, 0
  2119 0000075F 89DA                    	mov dx, bx		; set both to zero (without affecting flags)
  2120 00000761 C3                      	retn
  2121                                  
  2122                                  of_shift_right: section_of_function
  2123 00000762 30E4                    	xor ah, ah
  2124 00000764 E81F00                  	nearcall of_helper_getshiftdata
  2125                                  .loop:
  2126 00000767 D1EB                    	shr bx, 1
  2127 00000769 D1DA                    	rcr dx, 1
  2128 0000076B E2FA                    	loop .loop
  2129 0000076D C3                      	retn
  2130                                  
  2131                                  of_shift_right_signed: section_of_function
  2132 0000076E B440                    	mov ah, 40h
  2133 00000770 E81300                  	nearcall of_helper_getshiftdata
  2134                                  .loop:
  2135 00000773 D1FB                    	sar bx, 1
  2136 00000775 D1DA                    	rcr dx, 1
  2137 00000777 E2FA                    	loop .loop
  2138 00000779 C3                      	retn
  2139                                  
  2140                                  of_shift_left: section_of_function
  2141 0000077A 30E4                    	xor ah, ah
  2142 0000077C E80700                  	nearcall of_helper_getshiftdata
  2143                                  .loop:
  2144 0000077F D1E2                    	shl dx, 1
  2145 00000781 D1D3                    	rcl bx, 1
  2146 00000783 E2FA                    	loop .loop
  2147 00000785 C3                      	retn
  2148                                  
  2149                                  		; Called by operator functions to get shift data
  2150                                  		;
  2151                                  		; This returns to the next caller with the unchanged input
  2152                                  		; operand if the shift count is zero. Otherwise, large shift
  2153                                  		; counts are normalized so the returned value in cx is not
  2154                                  		; zero and not higher than 32. This normalization is not just
  2155                                  		; an optimization, it's required for shift counts that don't
  2156                                  		; fit into a 16-bit counter.
  2157                                  		;
  2158                                  		; INP:	bx:dx = shift count
  2159                                  		; OUT:	bx:dx = input operand
  2160                                  		;	If shift count is >= 1 and <= 32,
  2161                                  		;	 cx = shift count
  2162                                  		;	If shift count is > 32,
  2163                                  		;	 cx = 32
  2164                                  		;	If shift count is zero,
  2165                                  		;	 discards one near return address before returning
  2166                                  		; CHG:	cx
  2167                                  of_helper_getshiftdata: section_of_function
  2168 00000786 89D1                    	mov cx, dx
  2169 00000788 85DB                    	test bx, bx
  2170 0000078A 7505                    	jnz .largeshift
  2171 0000078C 83FA20                  	cmp dx, byte 32
  2172 0000078F 7203                    	jb .normalshift
  2173                                  .largeshift:
  2174 00000791 B92000                  	mov cx, 32		; fix at maximal shift count
  2175                                  .normalshift:
  2176 00000794 8B16[940C]              	mov dx, word [hhvar]
  2177 00000798 8B1E[960C]              	mov bx, word [hhvar+2]
  2178 0000079C E301                    	jcxz .break		; shift count zero, return input -->
  2179 0000079E C3                      	retn
  2180                                  
  2181                                  .break:
  2182 0000079F 59                      	pop cx			; discard near return address
  2183 000007A0 C3                      	retn
  2184                                  
  2185                                  of_bit_mirror: section_of_function
  2186 000007A1 30E4                    	xor ah, ah
  2187 000007A3 89D1                    	mov cx, dx
  2188 000007A5 85DB                    	test bx, bx
  2189 000007A7 7505                    	jnz .large
  2190 000007A9 83FA40                  	cmp dx, byte 64
  2191 000007AC 7205                    	jb .normal
  2192                                  .large:
  2193 000007AE 31DB                    	xor bx, bx		; mirror count 64 or higher:
  2194 000007B0 31D2                    	xor dx, dx		;  all 32 bits mirrored with (nonexistent) zero bits
  2195 000007B2 C3                      	retn
  2196                                  .normal:
  2197 000007B3 8B16[940C]              	mov dx, word [hhvar]
  2198 000007B7 8B1E[960C]              	mov bx, word [hhvar+2]
  2199 000007BB 80F901                  	cmp cl, 1
  2200 000007BE 762B                    	jbe .ret		; mirror count one or zero, return input -->
  2201 000007C0 56                      	push si
  2202 000007C1 57                      	push di
  2203                                  
  2204 000007C2 51                      	push cx
  2205 000007C3 BFFFFF                  	mov di, -1
  2206 000007C6 89FE                    	mov si, di
  2207                                  .loopmask:
  2208 000007C8 D1E7                    	shl di, 1
  2209 000007CA D1D6                    	rcl si, 1
  2210 000007CC E2FA                    	loop .loopmask		; create mask of bits not involved in mirroring
  2211 000007CE 21DE                    	and si, bx
  2212 000007D0 21D7                    	and di, dx		; get the uninvolved bits
  2213 000007D2 59                      	pop cx
  2214                                  
  2215 000007D3 56                      	push si
  2216 000007D4 57                      	push di			; save them
  2217 000007D5 31F6                    	xor si, si
  2218 000007D7 31FF                    	xor di, di		; initialize mirrored register
  2219                                  .loop:
  2220 000007D9 D1EB                    	shr bx, 1
  2221 000007DB D1DA                    	rcr dx, 1		; shift out of original register's current LSB
  2222 000007DD D1D7                    	rcl di, 1
  2223 000007DF D1D6                    	rcl si, 1		;  into other register's current LSB
  2224 000007E1 E2F6                    	loop .loop
  2225 000007E3 5A                      	pop dx
  2226 000007E4 5B                      	pop bx			; restore uninvolved bits
  2227 000007E5 09F3                    	or bx, si
  2228 000007E7 09FA                    	or dx, di		; combine with mirrored bits
  2229                                  
  2230 000007E9 5F                      	pop di
  2231 000007EA 5E                      	pop si
  2232                                  .ret:
  2233 000007EB C3                      	retn
  2234                                  
  2235                                  of_or_bitwise: section_of_function
  2236 000007EC 0B16[940C]              	or dx, word [hhvar]
  2237 000007F0 0B1E[960C]              	or bx, word [hhvar+2]	; bitwise or
  2238                                  or_hhtype_1: section_of_function
  2239 000007F4 E912FE                  	jmp or_hhtype
  2240                                  
  2241                                  of_or_boolean: section_of_function
  2242 000007F7 E82B00                  	nearcall of_helper_getbool
  2243 000007FA 09DA                    	or dx, bx		; boolean or
  2244 000007FC EB24                    	jmp short of_helper_retbool
  2245                                  
  2246                                  of_clr_bitwise: section_of_function
  2247 000007FE F7D3                    	not bx
  2248 00000800 F7D2                    	not dx
  2249                                  
  2250                                  of_and_bitwise: section_of_function
  2251 00000802 2316[940C]              	and dx, word [hhvar]
  2252 00000806 231E[960C]              	and bx, word [hhvar+2]	; bitwise and
  2253 0000080A EBE8                    	jmp or_hhtype_1
  2254                                  
  2255                                  of_and_boolean: section_of_function
  2256 0000080C E81600                  	nearcall of_helper_getbool
  2257 0000080F 21DA                    	and dx, bx		; boolean and
  2258 00000811 EB0F                    	jmp short of_helper_retbool
  2259                                  
  2260                                  of_xor_bitwise: section_of_function
  2261 00000813 3316[940C]              	xor dx, word [hhvar]
  2262 00000817 331E[960C]              	xor bx, word [hhvar+2]	; bitwise xor
  2263 0000081B EBD7                    	jmp or_hhtype_1
  2264                                  
  2265                                  of_xor_boolean: section_of_function
  2266 0000081D E80500                  	nearcall of_helper_getbool
  2267 00000820 31DA                    	xor dx, bx		; boolean xor
  2268                                  of_helper_retbool: section_of_function
  2269 00000822 31DB                    	xor bx, bx		; high word always zero
  2270 00000824 C3                      	retn
  2271                                  
  2272                                  		; Called by operator functions to convert operands to boolean
  2273                                  		;
  2274                                  		; INP:	bx:dx = next number, ah = type
  2275                                  		;	[hhvar] = previous number, [hhtype] = type
  2276                                  		; OUT:	bx = next number's boolean value
  2277                                  		;	dx = previous number's boolean value
  2278                                  		;	ah = 0
  2279                                  of_helper_getbool: section_of_function
  2280 00000825 30E4                    	xor ah, ah
  2281 00000827 E81BFF                  	nearcall toboolean
  2282 0000082A 52                      	push dx
  2283 0000082B 8B16[940C]              	mov dx, word [hhvar]
  2284 0000082F 8B1E[960C]              	mov bx, word [hhvar+2]
  2285 00000833 E80FFF                  	nearcall toboolean
  2286 00000836 5B                      	pop bx
  2287 00000837 C3                      	retn
  2288                                  
  2289                                  
  2290                                  	usesection lDEBUG_DATA_ENTRY
  2290          ------------------       note: usesection lDEBUG_DATA_ENTRY
  2291                                  
  2292                                  isvariable_data:
  2293 0000011E 1F                      reverselfsrtop:	db 1Fh
  2294                                  
  2295                                  %if _DEBUG3
  2296                                  	align 8, db 0
  2297                                  kregs:	dd 0
  2298                                  	dd 1
  2299                                  	dd 0aa55aa55h
  2300                                  	dd -1
  2301                                  	times 12 dd 0
  2302                                  %endif
  2303                                  
  2304 0000011F 00                      	align 4, db 0
  2305 00000120 02000000                lfsr:		dd 2
  2306 00000124 01000000                reverselfsr:	dd 1
  2307 00000128 03002080                lfsrtap:	dd 8020_0003h
  2308                                  %if _SLEEP_NEW
  2309 0000012C 0000                    getc_repeat_idle:	dw 0
  2310 0000012E 0000                    sleep_repeat_idle:	dw 0
  2311 00000130 0000                    sleep_highest_delta:	dw 0
  2312 00000132 0500                    sleep_delta_limit:	dw 5
  2313                                  %endif
  2314                                  %if _COUNT || _SCOUNT
  2315 00000134 00000000                count_var:	dd 0
  2316                                  %endif
  2317                                  %if _RH
  2318 00000138 0000                    rhcount:	dw 0
  2319                                  %endif
  2320                                  
  2321                                  
  2322                                  		; REM:	Dispatch table in section lDEBUG_CODE or lDEBUG_CODE2
  2323                                  	align 2, db 0
  2324                                  isvariable_struc_list:
  2325                                  
  2326                                  %assign IVS_ONEBYTE 1
  2327                                  isvariable_struc_onebyte_list:
  2328                                  	; name, size, flags, address, array last index, array skip
  2329 0000013A 00003000[0000]-         isvariablestruc "V", 4, 0, vregs, VREGSAMOUNT - 1
  2329 00000140 [490D]FF00         
  2330                                  %if _DEBUG3
  2331                                  isvariablestruc "K", 4, 0, kregs, 15
  2332                                  %endif
  2333                                  isvariable_struc_onebyte_list_end:
  2334                                  
  2335                                  %assign IVS_ONEBYTE 0
  2336                                  isvariable_struc_morebyte_list:
  2337                                  
  2338                                  %if _EXTENSIONS && _EXT_VARIABLES
  2339                                  ext_var:
  2340                                  ext_var_amount equ _EXT_VARIABLES
  2341                                  ext_var_format equ 1
  2342                                  ext_var_size equ ISVARIABLESTRUC_size
  2343                                   %rep _EXT_VARIABLES
  2344                                   	istruc ISVARIABLESTRUC
  2345                                  at ivName,		dw 0
  2346                                  at ivFlags,		dw 0
  2347                                  at ivAddress,		dw 0
  2348                                  at ivSetup,		dw var_ext_setup
  2349                                  at ivArrayLast,		db 0
  2350                                  at ivArrayBetween,	db 0
  2351                                  	iend
  2352                                   %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2353                                   %endrep
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 00000144 0000                <1> at ivName, dw 0
  2346 00000146 0000                <1> at ivFlags, dw 0
  2347 00000148 0000                <1> at ivAddress, dw 0
  2348 0000014A [3808]              <1> at ivSetup, dw var_ext_setup
  2349 0000014C 00                  <1> at ivArrayLast, db 0
  2350 0000014D 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 0000014E 0000                <1> at ivName, dw 0
  2346 00000150 0000                <1> at ivFlags, dw 0
  2347 00000152 0000                <1> at ivAddress, dw 0
  2348 00000154 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 00000156 00                  <1> at ivArrayLast, db 0
  2350 00000157 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 00000158 0000                <1> at ivName, dw 0
  2346 0000015A 0000                <1> at ivFlags, dw 0
  2347 0000015C 0000                <1> at ivAddress, dw 0
  2348 0000015E [3808]              <1> at ivSetup, dw var_ext_setup
  2349 00000160 00                  <1> at ivArrayLast, db 0
  2350 00000161 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 00000162 0000                <1> at ivName, dw 0
  2346 00000164 0000                <1> at ivFlags, dw 0
  2347 00000166 0000                <1> at ivAddress, dw 0
  2348 00000168 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 0000016A 00                  <1> at ivArrayLast, db 0
  2350 0000016B 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 0000016C 0000                <1> at ivName, dw 0
  2346 0000016E 0000                <1> at ivFlags, dw 0
  2347 00000170 0000                <1> at ivAddress, dw 0
  2348 00000172 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 00000174 00                  <1> at ivArrayLast, db 0
  2350 00000175 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 00000176 0000                <1> at ivName, dw 0
  2346 00000178 0000                <1> at ivFlags, dw 0
  2347 0000017A 0000                <1> at ivAddress, dw 0
  2348 0000017C [3808]              <1> at ivSetup, dw var_ext_setup
  2349 0000017E 00                  <1> at ivArrayLast, db 0
  2350 0000017F 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 00000180 0000                <1> at ivName, dw 0
  2346 00000182 0000                <1> at ivFlags, dw 0
  2347 00000184 0000                <1> at ivAddress, dw 0
  2348 00000186 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 00000188 00                  <1> at ivArrayLast, db 0
  2350 00000189 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 0000018A 0000                <1> at ivName, dw 0
  2346 0000018C 0000                <1> at ivFlags, dw 0
  2347 0000018E 0000                <1> at ivAddress, dw 0
  2348 00000190 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 00000192 00                  <1> at ivArrayLast, db 0
  2350 00000193 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 00000194 0000                <1> at ivName, dw 0
  2346 00000196 0000                <1> at ivFlags, dw 0
  2347 00000198 0000                <1> at ivAddress, dw 0
  2348 0000019A [3808]              <1> at ivSetup, dw var_ext_setup
  2349 0000019C 00                  <1> at ivArrayLast, db 0
  2350 0000019D 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 0000019E 0000                <1> at ivName, dw 0
  2346 000001A0 0000                <1> at ivFlags, dw 0
  2347 000001A2 0000                <1> at ivAddress, dw 0
  2348 000001A4 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 000001A6 00                  <1> at ivArrayLast, db 0
  2350 000001A7 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 000001A8 0000                <1> at ivName, dw 0
  2346 000001AA 0000                <1> at ivFlags, dw 0
  2347 000001AC 0000                <1> at ivAddress, dw 0
  2348 000001AE [3808]              <1> at ivSetup, dw var_ext_setup
  2349 000001B0 00                  <1> at ivArrayLast, db 0
  2350 000001B1 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 000001B2 0000                <1> at ivName, dw 0
  2346 000001B4 0000                <1> at ivFlags, dw 0
  2347 000001B6 0000                <1> at ivAddress, dw 0
  2348 000001B8 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 000001BA 00                  <1> at ivArrayLast, db 0
  2350 000001BB 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 000001BC 0000                <1> at ivName, dw 0
  2346 000001BE 0000                <1> at ivFlags, dw 0
  2347 000001C0 0000                <1> at ivAddress, dw 0
  2348 000001C2 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 000001C4 00                  <1> at ivArrayLast, db 0
  2350 000001C5 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 000001C6 0000                <1> at ivName, dw 0
  2346 000001C8 0000                <1> at ivFlags, dw 0
  2347 000001CA 0000                <1> at ivAddress, dw 0
  2348 000001CC [3808]              <1> at ivSetup, dw var_ext_setup
  2349 000001CE 00                  <1> at ivArrayLast, db 0
  2350 000001CF 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 000001D0 0000                <1> at ivName, dw 0
  2346 000001D2 0000                <1> at ivFlags, dw 0
  2347 000001D4 0000                <1> at ivAddress, dw 0
  2348 000001D6 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 000001D8 00                  <1> at ivArrayLast, db 0
  2350 000001D9 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2344                              <1>  istruc ISVARIABLESTRUC
  2345 000001DA 0000                <1> at ivName, dw 0
  2346 000001DC 0000                <1> at ivFlags, dw 0
  2347 000001DE 0000                <1> at ivAddress, dw 0
  2348 000001E0 [3808]              <1> at ivSetup, dw var_ext_setup
  2349 000001E2 00                  <1> at ivArrayLast, db 0
  2350 000001E3 00                  <1> at ivArrayBetween, db 0
  2351                              <1>  iend
  2352                              <1>  %xdefine IVS_MOREBYTE_NAMEHEADERS IVS_MOREBYTE_NAMEHEADERS, 0
  2354                                  %endif
  2355                                  
  2356                                  %if !_LOADER
  2357 000001E4 [B009]1600[0000]-       isvariablestruc "INT8CTRL", 2, 0, intr8_limit
  2357 000001EA [490D]0000         
  2358                                  %endif
  2359 000001EE [B609]32000000-         isvariablestruc "LFSR", 4, 0, 0, 0, 0, var_lfsr_setup
  2359 000001F4 [7208]0000         
  2360 000001F8 [B809]33000000-         isvariablestruc "RLFSR", 4, 0, 0, 0, 0, var_reverselfsr_setup
  2360 000001FE [8808]0000         
  2361 00000202 [BB09]3500[2801]-       isvariablestruc "LFSRTAP", 4, 0, lfsrtap
  2361 00000208 [490D]0000         
  2362 0000020C [C009]0600[1E01]-       isvariablestruc "RLFSRTOP", 1, 0, reverselfsrtop
  2362 00000212 [490D]0000         
  2363                                  %if _SLEEP_NEW
  2364 00000216 [C609]0600[2C01]-       isvariablestruc "GREPIDLE", 1, 0, getc_repeat_idle
  2364 0000021C [490D]0000         
  2365 00000220 [CC09]0600[2E01]-       isvariablestruc "SREPIDLE", 1, 0, sleep_repeat_idle
  2365 00000226 [490D]0000         
  2366 0000022A [D209]1700[3001]-       isvariablestruc "SMAXDELTA", 2, 0, sleep_highest_delta
  2366 00000230 [490D]0000         
  2367 00000234 [D909]1900[3201]-       isvariablestruc "SDELTALIMIT", 2, 0, sleep_delta_limit
  2367 0000023A [490D]0000         
  2368                                  %endif
  2369                                  %if !_LOADER
  2370 0000023E [E209]9800[0000]-       isvariablestruc "DEVICESIZE", 2, ivfReadOnly, device_mcb_paragraphs
  2370 00000244 [490D]0000         
  2371 00000248 [EA09]BA00[0000]-       isvariablestruc "DEVICEHEADER", 4, ivfReadOnly, device_header_address
  2371 0000024E [490D]0000         
  2372                                  %endif
  2373 00000252 [F409]0700[0000]-       isvariablestruc "DDTEXTAND", 1, 0, dd_text_and
  2373 00000258 [490D]0000         
  2374 0000025C [FB09]8500[0000]-       isvariablestruc "MACHX86", 1, ivfReadOnly, machine
  2374 00000262 [490D]0000         
  2375 00000266 [000A]8500[0000]-       isvariablestruc "MACHX87", 1, ivfReadOnly, encodedmach87
  2375 0000026C [490D]0000         
  2376                                  %if !_LOADER
  2377 00000270 [050A]0100[0000]-       isvariablestruc "MMT", 1, 0, maxmachinetype
  2377 00000276 [490D]0000         
  2378                                  %endif
  2379 0000027A [060A]3103[0000]-       isvariablestruc "DCO", 4, 	ivfArrayOneBased | ivfArrayOptional, options, 7
  2379 00000280 [490D]0700         
  2381 00000284 [070A]B103[0000]-       isvariablestruc "DCS", 4, 	ivfReadOnly | ivfArrayOneBased | ivfArrayOptional, startoptions, 7
  2381 0000028A [490D]0700         
  2383 0000028E [080A]B103[0000]-       isvariablestruc "DIF", 4, 	ivfReadOnly | ivfArrayOneBased | ivfArrayOptional, internalflags, 7
  2383 00000294 [490D]0700         
  2385                                  %if !_LOADER
  2386 00000298 [090A]3100[0000]-       isvariablestruc "DAO", 4, 	0, asm_options
  2386 0000029E [490D]0000         
  2388 000002A2 [0A0A]B100[0000]-       isvariablestruc "DAS", 4, 	ivfReadOnly, asm_startoptions
  2388 000002A8 [490D]0000         
  2390 000002AC [0B0A]B100[0000]-       isvariablestruc "DPI", 4, 	ivfReadOnly, psp22
  2390 000002B2 [490D]0000         
  2392                                  %endif
  2393 000002B6 [0C0A]9100[0000]-       isvariablestruc "DPR", 2, 	ivfReadOnly, pspdbg
  2393 000002BC [490D]0000         
  2395                                  %if !_LOADER
  2396 000002C0 [0D0A]9100[0000]-       isvariablestruc "DPP", 2, 	ivfReadOnly, parent
  2396 000002C6 [490D]0000         
  2398 000002CA [0E0A]B200[0000]-       isvariablestruc "DPRA", 4, 	ivfReadOnly, psp22
  2398 000002D0 [490D]0000         
  2400                                  %endif
  2401 000002D4 [100A]9200[0000]-       isvariablestruc "DPSP", 2, 	ivfReadOnly, pspdbg
  2401 000002DA [490D]0000         
  2403                                  %if !_LOADER
  2404 000002DE [120A]9500[0000]-       isvariablestruc "DPARENT", 2, 	ivfReadOnly, parent
  2404 000002E4 [490D]0000         
  2406                                  %endif
  2407                                  %if _PM
  2408 000002E8 [170A]91000000-         isvariablestruc "DPS", 2, 	ivfReadOnly, 0, 0, 0, var_seldbg_setup
  2408 000002EE [EB08]0000         
  2410 000002F2 [180A]95000000-         isvariablestruc "DPSPSEL", 2, 	ivfReadOnly, 0, 0, 0, var_dpspsel_setup
  2410 000002F8 [E408]0000         
  2412                                  %else
  2413                                  isvariablestruc "DPSPSEL", 2, 	ivfReadOnly, pspdbg
  2415                                  %endif
  2416                                  
  2417                                  %if !_LOADER
  2418 000002FC [1D0A]3100[0000]-       isvariablestruc "PPC", 4, 0, default_pp_count
  2418 00000302 [490D]0000         
  2419 00000306 [1E0A]3100[0000]-       isvariablestruc "TPC", 4, 0, default_tp_count
  2419 0000030C [490D]0000         
  2420 00000310 [1F0A]3100[0000]-       isvariablestruc "TTC", 4, 0, default_tt_count
  2420 00000316 [490D]0000         
  2421                                  
  2422 0000031A [200A]3500[0000]-       isvariablestruc "RELIMIT", 4, 0, re_limit
  2422 00000320 [490D]0000         
  2423 00000324 [250A]3500[0000]-       isvariablestruc "RECOUNT", 4, 0, re_count
  2423 0000032A [490D]0000         
  2424                                  %endif
  2425 0000032E [2A0A]3500[0000]-       isvariablestruc "RCLIMIT", 4, 0, rc_limit
  2425 00000334 [490D]0000         
  2426 00000338 [2F0A]3500[0000]-       isvariablestruc "RCCOUNT", 4, 0, rc_count
  2426 0000033E [490D]0000         
  2427                                  
  2428 00000342 [340A]1000[0000]-       isvariablestruc "RC", 2, 0, priorrc
  2428 00000348 [490D]0000         
  2429 0000034C [340A]1100[0000]-       isvariablestruc "ERC", 2, 0, erc
  2429 00000352 [490D]0000         
  2430                                  %if !_LOADER
  2431 00000356 [350A]0400[0000]-       isvariablestruc "QQCODE", 1, 0, qqtermcode
  2431 0000035C [490D]0000         
  2432 00000360 [390A]1600[0000]-       isvariablestruc "TERMCODE", 2, 0, usertermcode
  2432 00000366 [490D]0000         
  2433                                  %endif
  2434                                  
  2435                                  %if _PM
  2436                                   %assign var_addr_offset 4
  2437                                  %else
  2438                                   %assign var_addr_offset 2
  2439                                  %endif
  2440                                  
  2441                                  %if !_LOADER
  2442 0000036A [3F0A]3100[0000]-       isvariablestruc "AAO", var_addr_offset, 0, a_addr
  2442 00000370 [490D]0000         
  2443 00000374 [400A]1100[0400]-       isvariablestruc "AAS", 2, 0, a_addr + saSegSel
  2443 0000037A [490D]0000         
  2444                                  %endif
  2445 0000037E [410A]3100[0000]-       isvariablestruc "ADO", var_addr_offset, 0, d_addr
  2445 00000384 [490D]0000         
  2446 00000388 [420A]1100[0400]-       isvariablestruc "ADS", 2, 0, d_addr + saSegSel
  2446 0000038E [490D]0000         
  2447                                  %if !_LOADER
  2448 00000392 [430A]3100[0000]-       isvariablestruc "ABO", var_addr_offset, 0, behind_r_u_addr
  2448 00000398 [490D]0000         
  2449 0000039C [440A]1100[0400]-       isvariablestruc "ABS", 2, 0, behind_r_u_addr + saSegSel
  2449 000003A2 [490D]0000         
  2450 000003A6 [450A]3100[0000]-       isvariablestruc "AUO", var_addr_offset, 0, u_addr
  2450 000003AC [490D]0000         
  2451 000003B0 [460A]1100[0400]-       isvariablestruc "AUS", 2, 0, u_addr + saSegSel
  2451 000003B6 [490D]0000         
  2452                                  %endif
  2453 000003BA [470A]3100[0000]-       isvariablestruc "AEO", var_addr_offset, 0, e_addr
  2453 000003C0 [490D]0000         
  2454 000003C4 [480A]1100[0400]-       isvariablestruc "AES", 2, 0, e_addr + saSegSel
  2454 000003CA [490D]0000         
  2455                                  %if _DSTRINGS
  2456 000003CE [490A]3100[0000]-       isvariablestruc "AZO", var_addr_offset, 0, dz_addr
  2456 000003D4 [490D]0000         
  2457 000003D8 [4A0A]1100[0400]-       isvariablestruc "AZS", 2, 0, dz_addr + saSegSel
  2457 000003DE [490D]0000         
  2458 000003E2 [4B0A]3100[0000]-       isvariablestruc "ACO", var_addr_offset, 0, dcpm_addr
  2458 000003E8 [490D]0000         
  2459 000003EC [4C0A]1100[0400]-       isvariablestruc "ACS", 2, 0, dcpm_addr + saSegSel
  2459 000003F2 [490D]0000         
  2460 000003F6 [4D0A]3100[0000]-       isvariablestruc "APO", var_addr_offset, 0, dcount_addr
  2460 000003FC [490D]0000         
  2461 00000400 [4E0A]1100[0400]-       isvariablestruc "APS", 2, 0, dcount_addr + saSegSel
  2461 00000406 [490D]0000         
  2462 0000040A [4F0A]3100[0000]-       isvariablestruc "AWO", var_addr_offset, 0, dwcount_addr
  2462 00000410 [490D]0000         
  2463 00000414 [500A]1100[0400]-       isvariablestruc "AWS", 2, 0, dwcount_addr + saSegSel
  2463 0000041A [490D]0000         
  2464                                  %endif
  2465                                  %if _DX
  2466                                  isvariablestruc "AXO", 4, 0, x_addr
  2467                                  %endif
  2468                                  
  2469 0000041E [510A]0100[0000]-       isvariablestruc "DSR", 1, 0, serial_rows
  2469 00000424 [490D]0000         
  2470 00000428 [520A]0100[0000]-       isvariablestruc "DSC", 1, 0, serial_columns
  2470 0000042E [490D]0000         
  2471 00000432 [530A]0100[0000]-       isvariablestruc "DST", 1, 0, serial_keep_timeout
  2471 00000438 [490D]0000         
  2472                                  %if _USE_TX_FIFO
  2473 0000043C [540A]0100[0000]-       isvariablestruc "DSF", 1, 0, serial_fifo_size
  2473 00000442 [490D]0000         
  2474                                  %endif
  2475 00000446 [550A]0300[0000]-       isvariablestruc "DSPVI", 1, 0,		 serial_var_intnum
  2475 0000044C [490D]0000         
  2476 00000450 [580A]8300[0000]-       isvariablestruc "DSPUI", 1, ivfReadOnly, serial_use_intnum
  2476 00000456 [490D]0000         
  2477 0000045A [5B0A]0300[0000]-       isvariablestruc "DSPVS", 1, 0,		 serial_var_params
  2477 00000460 [490D]0000         
  2478 00000464 [5E0A]8300[0000]-       isvariablestruc "DSPUS", 1, ivfReadOnly, serial_use_params
  2478 0000046A [490D]0000         
  2479 0000046E [610A]0300[0000]-       isvariablestruc "DSPVF", 1, 0,		 serial_var_fifo
  2479 00000474 [490D]0000         
  2480 00000478 [640A]8300[0000]-       isvariablestruc "DSPUF", 1, ivfReadOnly, serial_use_fifo
  2480 0000047E [490D]0000         
  2481 00000482 [670A]1300[0000]-       isvariablestruc "DSPVP", 2, 0,		 serial_var_baseport
  2481 00000488 [490D]0000         
  2482 0000048C [6A0A]9300[0000]-       isvariablestruc "DSPUP", 2, ivfReadOnly, serial_use_baseport
  2482 00000492 [490D]0000         
  2483 00000496 [6D0A]1300[0000]-       isvariablestruc "DSPVD", 2, 0,		 serial_var_dl
  2483 0000049C [490D]0000         
  2484 000004A0 [700A]9300[0000]-       isvariablestruc "DSPUD", 2, ivfReadOnly, serial_use_dl
  2484 000004A6 [490D]0000         
  2485 000004AA [730A]1300[0000]-       isvariablestruc "DSPVM", 2, 0,		 serial_var_irqmask
  2485 000004B0 [490D]0000         
  2486 000004B4 [760A]9300[0000]-       isvariablestruc "DSPUM", 2, ivfReadOnly, serial_use_irqmask
  2486 000004BA [490D]0000         
  2487                                  
  2488                                  %if _40COLUMNS
  2489 000004BE [790A]0500[0000]-       isvariablestruc "IOCLINE", 1, 0, io_columns_getline
  2489 000004C4 [490D]0000         
  2490                                  	; IOCLINE must be before IOC as otherwise "IOCLINE" would get
  2491                                  	;  misdetected as "IOC" + "L" separator + junk
  2492                                  %endif
  2493 000004C8 [7E0A]0100[0000]-       isvariablestruc "IOR", 1, 0, io_rows
  2493 000004CE [490D]0000         
  2494 000004D2 [7F0A]0100[0000]-       isvariablestruc "IOC", 1, 0, io_columns
  2494 000004D8 [490D]0000         
  2495 000004DC [800A]1100[0000]-       isvariablestruc "IOS", 2, 0, io_start_buffer
  2495 000004E2 [490D]0000         
  2496 000004E6 [810A]1100[0000]-       isvariablestruc "IOE", 2, 0, io_end_buffer
  2496 000004EC [490D]0000         
  2497 000004F0 [820A]1100[0000]-       isvariablestruc "IOL", 2, 0, io_levels
  2497 000004F6 [490D]0000         
  2498 000004FA [830A]1100[0000]-       isvariablestruc "IOF", 2, 0, io_flags
  2498 00000500 [490D]0000         
  2499 00000504 [840A]91000000-         isvariablestruc "IOI", 2, ivfReadOnly, 0, 0, 0, var_ioi_setup
  2499 0000050A [1D09]0000         
  2500 0000050E [850A]91000000-         isvariablestruc "IOK", 2, ivfReadOnly, 0, 0, 0, var_iok_setup
  2500 00000514 [3509]0000         
  2501                                  
  2502                                  %if _CATCHINT2D
  2503 00000518 [860A]8500[0000]-       isvariablestruc "AMISNUM", 1, ivfReadOnly, amis_multiplex_number
  2503 0000051E [490D]0000         
  2504 00000522 [8B0A]0800[0000]-       isvariablestruc "TRYAMISNUM", 1, 0, try_amis_multiplex_number
  2504 00000528 [490D]0000         
  2505                                  %endif
  2506                                  
  2507 0000052C [930A]3600[0000]-       isvariablestruc "HHRESULT", 4, 0, hhresult
  2507 00000532 [490D]0000         
  2508                                  %if _PM
  2509 00000536 [990A]1600[0000]-       isvariablestruc "DARESULT", 2, 0, daresult
  2509 0000053C [490D]0000         
  2510                                  %endif
  2511                                  %if _EMS
  2512                                  isvariablestruc "XARESULT", 2, 0, xaresult
  2513                                  %endif
  2514                                  %if _COUNT || _SCOUNT
  2515 00000540 [9F0A]3300[3401]-       isvariablestruc "COUNT", 4, 0, count_var
  2515 00000546 [490D]0000         
  2516                                  %endif
  2517                                  %if _RH
  2518 0000054A [A20A]95000000-         isvariablestruc "RHCOUNT", 2, ivfReadOnly, 0, 0, 0, var_rhcount_setup
  2518 00000550 [FE08]0000         
  2519                                  %endif
  2520                                  
  2521                                  %if _DEBUG1
  2522                                  isvariablestruc "TRC", 2, ivfArrayOptional, 	test_records_Readmem + 4, 15, 4
  2524                                  isvariablestruc "TRA", 4, ivfArrayOptional, 	test_records_Readmem, 15, 2
  2526                                  isvariablestruc "TWC", 2, ivfArrayOptional, 	test_records_Writemem + 4, 15, 4
  2528                                  isvariablestruc "TWA", 4, ivfArrayOptional, 	test_records_Writemem, 15, 2
  2530                                  isvariablestruc "TLC", 2, ivfArrayOptional, 	test_records_getLinear + 4, 15, 4
  2532                                  isvariablestruc "TLA", 4, ivfArrayOptional, 	test_records_getLinear, 15, 2
  2534                                  isvariablestruc "TSC", 2, ivfArrayOptional, 	test_records_getSegmented + 4, 15, 4
  2536                                  isvariablestruc "TSA", 4, ivfArrayOptional, 	test_records_getSegmented, 15, 2
  2538                                  isvariablestruc "TRV", 1, 0, 	test_readmem_value
  2540                                  %endif
  2541                                  
  2542                                  
  2543                                  %if !_LOADER
  2544                                  %if _PM
  2545 00000554 [A70A]B102[0000]-       isvariablestruc "SRO", 4, ivfArrayOptional | ivfReadOnly, 	search_results, 15, 2
  2545 0000055A [490D]0F02         
  2547 0000055E [A80A]9102[0400]-       isvariablestruc "SRS", 2, ivfArrayOptional | ivfReadOnly, 	search_results + 4, 15, 4
  2547 00000564 [490D]0F04         
  2549                                  %else
  2550                                  isvariablestruc "SRO", 2, ivfArrayOptional | ivfReadOnly, 	search_results, 15, 2
  2552                                  isvariablestruc "SRS", 2, ivfArrayOptional | ivfReadOnly, 	search_results + 2, 15, 2
  2554                                  %endif
  2555 00000568 [A90A]B100[0000]-       isvariablestruc "SRC", 4, ivfReadOnly, 	sscounter
  2555 0000056E [490D]0000         
  2557                                  %endif
  2558                                  
  2559 00000572 [AA0A]90040000-         isvariablestruc "RI", 2, ivfSeparatorSpecial | ivfReadOnly, 	0, 255, 0, var_ri_setup
  2559 00000578 [0C0E]FF00         
  2561                                  
  2562                                  %if _MMXSUPP
  2563 0000057C [AA0A]B0040000-         isvariablestruc "MM", 4, ivfSeparatorSpecial | ivfReadOnly, 	0, 7, 0, var_mm_setup
  2563 00000582 [620D]0700         
  2565                                  %endif
  2566                                  
  2567                                  %if _DEBUG3
  2568                                  isvariablestruc "MT", 4, 0, 0, 1, 0, var_mt_setup
  2569                                  %endif
  2570                                  
  2571                                  %if _INPUT_FILE_BOOT || _INPUT_FILE_HANDLES
  2572 00000586 [AA0A]11020000-         isvariablestruc "YSF", 2, ivfArrayOptional, 	0, 15, 0, var_ysf_setup
  2572 0000058C [BF0E]0F00         
  2574                                   %if _INPUT_FILE_HANDLES
  2575 00000590 [AB0A]11020000-         isvariablestruc "YHF", 2, ivfArrayOptional, 	0, 15, 0, var_ysf_setup
  2575 00000596 [BF0E]0F00         
  2577                                   %endif
  2578                                   %if _INPUT_FILE_BOOT
  2579 0000059A [AC0A]11020000-         isvariablestruc "YBF", 2, ivfArrayOptional, 	0, 15, 0, var_ysf_setup
  2579 000005A0 [BF0E]0F00         
  2581                                   %endif
  2582                                  %endif
  2583                                  
  2584                                  %if _ACCESS_VARIABLES_AMOUNT
  2585 000005A4 [AD0A]B502[0000]-       isvariablestruc "READADR", 4, ivfReadOnly | ivfArrayOptional, 	reading_access_variables, _ACCESS_VARIABLES_AMOUNT - 1, 4
  2585 000005AA [490D]0304         
  2587 000005AE [B20A]B502[0400]-       isvariablestruc "READLEN", 4, ivfReadOnly | ivfArrayOptional, 	reading_access_variables + 4, _ACCESS_VARIABLES_AMOUNT - 1, 4
  2587 000005B4 [490D]0304         
  2589 000005B8 [B70A]B502[0000]-       isvariablestruc "WRITADR", 4, ivfReadOnly | ivfArrayOptional, 	writing_access_variables, _ACCESS_VARIABLES_AMOUNT - 1, 4
  2589 000005BE [490D]0304         
  2591 000005C2 [BC0A]B502[0400]-       isvariablestruc "WRITLEN", 4, ivfReadOnly | ivfArrayOptional, 	writing_access_variables + 4, _ACCESS_VARIABLES_AMOUNT - 1, 4
  2591 000005C8 [490D]0304         
  2593                                  %endif
  2594                                  
  2595                                  %if !_LOADER
  2596                                  %if _PSPVARIABLES
  2597                                   %if _PM
  2598 000005CC [C10A]92000000-         isvariablestruc "PSPS", 2, ivfReadOnly, 0, 0, 0, var_psps_setup
  2598 000005D2 [4D09]0000         
  2599 000005D6 [C30A]94000000-         isvariablestruc "PSPSEL", 2, ivfReadOnly, 0, 0, 0, var_psps_setup
  2599 000005DC [4D09]0000         
  2600                                   %else
  2601                                  isvariablestruc "PSPS", 2, ivfReadOnly, pspdbe
  2602                                  isvariablestruc "PSPSEL", 2, ivfReadOnly, pspdbe
  2603                                   %endif
  2604 000005E0 [C70A]9100[0000]-       isvariablestruc "PSP", 2, ivfReadOnly, pspdbe
  2604 000005E6 [490D]0000         
  2605 000005EA [C80A]91000000-         isvariablestruc "PPR", 2, ivfReadOnly, 0, 0, 0, var_ppr_setup
  2605 000005F0 [6A09]0000         
  2606 000005F4 [C90A]B1000000-         isvariablestruc "PPI", 4, ivfReadOnly, 0, 0, 0, var_ppi_setup
  2606 000005FA [9009]0000         
  2607 000005FE [CA0A]94000000-         isvariablestruc "PARENT", 2, ivfReadOnly, 0, 0, 0, var_ppr_setup
  2607 00000604 [6A09]0000         
  2608 00000608 [CE0A]B1000000-         isvariablestruc "PRA", 4, ivfReadOnly, 0, 0, 0, var_ppi_setup
  2608 0000060E [9009]0000         
  2609                                  %endif
  2610                                  %endif
  2611                                  
  2612                                  %if _BOOTLDR
  2613 00000612 [CF0A]08000000-         isvariablestruc "BOOTUNITFL", 1,  0, 0, 255, 0, var_bootunitflags_setup
  2613 00000618 [500A]FF00         
  2614 0000061C [D70A]89000000-         isvariablestruc "BOOTLDPUNIT", 1, ivfReadOnly, 0, 0, 0, var_bootldpunit_setup
  2614 00000622 [0E0A]0000         
  2615 00000626 [E00A]89000000-         isvariablestruc "BOOTSDPUNIT", 1, ivfReadOnly, 0, 0, 0, var_bootsdpunit_setup
  2615 0000062C [130A]0000         
  2616                                   %if _INPUT_FILE_BOOT
  2617 00000630 [E90A]89000000-         isvariablestruc "BOOTYDPUNIT", 1, ivfReadOnly, 0, 0, 0, var_bootydpunit_setup
  2617 00000636 [180A]0000         
  2618                                   %endif
  2619 0000063A [F20A]B9000000-         isvariablestruc "BOOTLDPPART", 4, ivfReadOnly, 0, 0, 0, var_bootldppart_setup
  2619 00000640 [2F0A]0000         
  2620 00000644 [FB0A]B9000000-         isvariablestruc "BOOTSDPPART", 4, ivfReadOnly, 0, 0, 0, var_bootsdppart_setup
  2620 0000064A [340A]0000         
  2621                                   %if _INPUT_FILE_BOOT
  2622 0000064E [040B]B9000000-         isvariablestruc "BOOTYDPPART", 4, ivfReadOnly, 0, 0, 0, var_bootydppart_setup
  2622 00000654 [390A]0000         
  2623                                   %endif
  2624                                  %endif
  2625                                  
  2626                                  %if !_LOADER
  2627 00000658 [0D0B]0900[0000]-       isvariablestruc "TRYDEBUGNUM", 1, 0, try_debugger_amis_multiplex_number
  2627 0000065E [490D]0000         
  2628 00000662 [160B]9700[0000]-       isvariablestruc "DEBUGFUNC", 2, ivfReadOnly, debuggerfunction
  2628 00000668 [490D]0000         
  2629                                  %if _MCLOPT
  2630                                  isvariablestruc "MASTERPICBASE", 1, 0, master_pic_base
  2631                                  %endif
  2632                                  %endif
  2633                                  
  2634 0000066C [1D0B]9700[0000]-       isvariablestruc "DSTACKLEN", 2, ivfReadOnly, entryseg_size
  2634 00000672 [490D]0000         
  2635 00000676 [240B]9700[0000]-       isvariablestruc "DSTACKSEG", 2, ivfReadOnly, pspdbg
  2635 0000067C [490D]0000         
  2636 00000680 [2B0B]9700[0000]-       isvariablestruc "DENTRYLEN", 2, ivfReadOnly, entryseg_size
  2636 00000686 [490D]0000         
  2637 0000068A [320B]9700[0000]-       isvariablestruc "DENTRYSEG", 2, ivfReadOnly, pspdbg
  2637 00000690 [490D]0000         
  2638 00000694 [390B]9700[0000]-       isvariablestruc "DCODE1LEN", 2, ivfReadOnly, code_size
  2638 0000069A [490D]0000         
  2639 0000069E [400B]9700[0000]-       isvariablestruc "DCODE1SEG", 2, ivfReadOnly, code_seg
  2639 000006A4 [490D]0000         
  2640                                  %if _DUALCODE
  2641 000006A8 [470B]9700[0000]-       isvariablestruc "DCODE2LEN", 2, ivfReadOnly, code2_size
  2641 000006AE [490D]0000         
  2642 000006B2 [4E0B]9700[0000]-       isvariablestruc "DCODE2SEG", 2, ivfReadOnly, code2_seg
  2642 000006B8 [490D]0000         
  2643                                  %endif
  2644                                  %if _MESSAGESEGMENT
  2645 000006BC [550B]9900[0000]-       isvariablestruc "DMESSAGELEN", 2, ivfReadOnly, messageseg_size
  2645 000006C2 [490D]0000         
  2646 000006C6 [5E0B]9900[0000]-       isvariablestruc "DMESSAGESEG", 2, ivfReadOnly, messageseg
  2646 000006CC [490D]0000         
  2647                                  %endif
  2648 000006D0 [670B]9800[0000]-       isvariablestruc "DAUXBUFLEN", 2, ivfReadOnly, auxbuff_current_size
  2648 000006D6 [490D]0000         
  2649                                  %if _PM
  2650 000006DA [6F0B]9800[0200]-       isvariablestruc "DAUXBUFSEG", 2, ivfReadOnly, auxbuff_segorsel + soaSegment
  2650 000006E0 [490D]0000         
  2651                                   %if _HISTORY_SEPARATE_FIXED && _HISTORY
  2652 000006E4 [770B]9800[0000]-       isvariablestruc "DHISBUFLEN", 2, ivfReadOnly, historyseg_size
  2652 000006EA [490D]0000         
  2653 000006EE [7F0B]9800[0200]-       isvariablestruc "DHISBUFSEG", 2, ivfReadOnly, history.segorsel + soaSegment
  2653 000006F4 [490D]0000         
  2654                                   %endif
  2655                                  %else
  2656                                  isvariablestruc "DAUXBUFSEG", 2, ivfReadOnly, auxbuff_segorsel
  2657                                   %if _HISTORY_SEPARATE_FIXED && _HISTORY
  2658                                  isvariablestruc "DHISBUFLEN", 2, ivfReadOnly, historyseg_size
  2659                                  isvariablestruc "DHISBUFSEG", 2, ivfReadOnly, history.segorsel
  2660                                   %endif
  2661                                  %endif
  2662                                   %if _IMMASM
  2663 000006F8 [870B]9500[0000]-       isvariablestruc "DIMMSEG", 2, ivfReadOnly, immseg
  2663 000006FE [490D]0000         
  2664                                   %endif
  2665                                   %if _EXTENSIONS
  2666 00000702 [8C0B]9500[0000]-       isvariablestruc "DEXTLEN", 2, ivfReadOnly, extseg_size
  2666 00000708 [490D]0000         
  2667 0000070C [910B]9600[0000]-       isvariablestruc "DEXTUSED", 2, ivfReadOnly, extseg_used
  2667 00000712 [490D]0000         
  2668                                  	; problem: is not currently effective value if to reclaim
  2669 00000716 [970B]9500[0000]-       isvariablestruc "DEXTSEG", 2, ivfReadOnly, extseg
  2669 0000071C [490D]0000         
  2670 00000720 [9C0B]9900[0000]-       isvariablestruc "DEXTDATALEN", 2, ivfReadOnly, extdata_size
  2670 00000726 [490D]0000         
  2671 0000072A [A50B]9A00[0000]-       isvariablestruc "DEXTDATAUSED", 2, ivfReadOnly, extdata_used
  2671 00000730 [490D]0000         
  2672                                  	; problem: is not currently effective value if to reclaim
  2673 00000734 [AF0B]9900[0000]-       isvariablestruc "DEXTDATAOFS", 2, ivfReadOnly, extdata
  2673 0000073A [490D]0000         
  2674                                   %endif
  2675                                  %if _APP_ENV_SIZE || _DEV_ENV_SIZE || _BOOT_ENV_SIZE
  2676 0000073E [B80B]9500[0000]-       isvariablestruc "DENVLEN", 2, ivfReadOnly, env_size
  2676 00000744 [490D]0000         
  2677 00000748 [BD0B]9500[0000]-       isvariablestruc "DENVSEG", 2, ivfReadOnly, envseg
  2677 0000074E [490D]0000         
  2678                                  %endif
  2679 00000752 [C20B]9800[0000]-       isvariablestruc "DALLOCSIZE", 2, ivfReadOnly, alloc_size
  2679 00000758 [490D]0000         
  2680 0000075C [CA0B]9700[0000]-       isvariablestruc "DALLOCSEG", 2, ivfReadOnly, alloc_seg
  2680 00000762 [490D]0000         
  2681                                  
  2682                                  %if _PM
  2683 00000766 [D10B]9700[0000]-       isvariablestruc "DSTACKSEL", 2, ivfReadOnly, dssel
  2683 0000076C [490D]0000         
  2684 00000770 [D80B]9700[0000]-       isvariablestruc "DENTRYSEL", 2, ivfReadOnly, cssel
  2684 00000776 [490D]0000         
  2685 0000077A [DF0B]9700[0000]-       isvariablestruc "DCODE1SEL", 2, ivfReadOnly, code_sel
  2685 00000780 [490D]0000         
  2686                                   %if _DUALCODE
  2687 00000784 [E60B]9700[0000]-       isvariablestruc "DCODE2SEL", 2, ivfReadOnly, code2_sel
  2687 0000078A [490D]0000         
  2688                                   %endif
  2689                                  %if _MESSAGESEGMENT
  2690 0000078E [ED0B]9900[0000]-       isvariablestruc "DMESSAGESEL", 2, ivfReadOnly, messagesel
  2690 00000794 [490D]0000         
  2691                                  %endif
  2692 00000798 [F60B]9800[0400]-       isvariablestruc "DAUXBUFSEL", 2, ivfReadOnly, auxbuff_segorsel + soaSelector
  2692 0000079E [490D]0000         
  2693                                   %if _HISTORY_SEPARATE_FIXED && _HISTORY
  2694 000007A2 [FE0B]9800[0400]-       isvariablestruc "DHISBUFSEL", 2, ivfReadOnly, history.segorsel + soaSelector
  2694 000007A8 [490D]0000         
  2695                                   %endif
  2696 000007AC [060C]9900[0000]-       isvariablestruc "DSCRATCHSEL", 2, ivfReadOnly, scratchsel
  2696 000007B2 [490D]0000         
  2697                                   %if _SYMBOLIC
  2698                                  isvariablestruc "DSYM1SEL", 2, ivfReadOnly, symsel1
  2699                                  isvariablestruc "DSYM2SEL", 2, ivfReadOnly, symsel2
  2700                                   %endif
  2701                                   %if _IMMASM
  2702 000007B6 [0F0C]9500[0000]-       isvariablestruc "DIMMSEL", 2, ivfReadOnly, immsel
  2702 000007BC [490D]0000         
  2703                                   %endif
  2704                                   %if _EXTENSIONS
  2705 000007C0 [140C]9700[0000]-       isvariablestruc "DEXTCSSEL", 2, ivfReadOnly, extcssel
  2705 000007C6 [490D]0000         
  2706 000007CA [1B0C]9700[0000]-       isvariablestruc "DEXTDSSEL", 2, ivfReadOnly, extdssel
  2706 000007D0 [490D]0000         
  2707                                   %endif
  2708                                  %endif
  2709                                  
  2710 000007D4 [220C]1900[0000]-       isvariablestruc "DEFAULTDLEN", 2, 0, dd_default_length
  2710 000007DA [490D]0000         
  2711 000007DE [2B0C]1B00[0000]-       isvariablestruc "DEFAULTDLINES", 2, 0, dd_default_lines
  2711 000007E4 [490D]0000         
  2712                                  %if !_LOADER
  2713 000007E8 [360C]1900[0000]-       isvariablestruc "DEFAULTULEN", 2, 0, uu_default_length
  2713 000007EE [490D]0000         
  2714 000007F2 [3F0C]1B00[0000]-       isvariablestruc "DEFAULTULINES", 2, 0, uu_default_lines
  2714 000007F8 [490D]0000         
  2715                                  %endif
  2716                                  
  2717                                  %if _PM
  2718 000007FC [4A0C]11000000-         isvariablestruc "CIP", 2, 0, 0, 0, 0, var_cip_setup
  2718 00000802 [4E08]0000         
  2719 00000806 [4B0C]11000000-         isvariablestruc "CSP", 2, 0, 0, 0, 0, var_csp_setup
  2719 0000080C [6208]0000         
  2720                                  %else
  2721                                  isvariablestruc "CIP", 2, 0, reg_eip
  2722                                  isvariablestruc "CSP", 2, 0, reg_esp
  2723                                  %endif
  2724                                  
  2725                                  %if _ELDLINKINFO
  2726 00000810 [4C0C]9800[0000]-       isvariablestruc "LINKOFFSET", 2, ivfReadOnly, linkinfoaddress
  2726 00000816 [490D]0000         
  2727 0000081A [540C]B900[0000]-       isvariablestruc "LINKPOINTER", 4, ivfReadOnly, linkinfoaddress
  2727 00000820 [490D]0000         
  2728 00000824 [5D0C]9500[0000]-       isvariablestruc "LINKSEG", 2, ivfReadOnly, linkseg
  2728 0000082A [490D]0000         
  2729                                   %if _PM
  2730 0000082E [620C]9500[0000]-       isvariablestruc "LINKSEL", 2, ivfReadOnly, linksel
  2730 00000834 [490D]0000         
  2731                                   %endif
  2732                                  
  2733                                   %if _LINK
  2734                                  %if _MESSAGESEGMENT
  2735                                   %if _PM
  2736                                  linksel equ messagesel
  2737                                   %else
  2738                                  linksel equ linkseg
  2739                                   %endif
  2740                                  linkseg equ messageseg
  2741                                  %else
  2742                                   %if _PM
  2743                                  linksel equ dssel
  2744                                   %else
  2745                                  linksel equ linkseg
  2746                                   %endif
  2747                                  linkseg equ pspdbg
  2748                                  %endif
  2749                                   %endif
  2750                                  %endif
  2751                                  
  2752                                  %if _PM && _DEBUG_PM_ENTRY
  2753                                  isvariablestruc "DEBUGPMET", 4, 0, debug_pm_entry_total
  2754                                  isvariablestruc "DEBUGPMEH", 4, 0, debug_pm_entry_esph
  2755                                  isvariablestruc "DEBUGPMEB", 4, 0, debug_pm_entry_b
  2756                                  %endif
  2757                                  
  2758                                  isvariable_struc_morebyte_list_end:
  2759                                  isvariable_struc_list_end:
  2760                                  
  2761                                  	align 2, db 0
  2762 00000838 00000000                interrupt_var:	dd 0
  2763                                  	align 2, db 0
  2764 0000083C 0000                    ioi_var:	dw 0
  2765 0000083E 0000                    iok_var:	dw 0
  2766                                  %if _PM
  2767                                  	align 2, db 0
  2768 00000840 0000                    seldbg:	dw 0
  2769                                  	align 2, db 0
  2770 00000842 0000                    dpspsel:	dw 0
  2771                                  %endif
  2772                                  %if _PSPVARIABLES
  2773                                  	align 2, db 0
  2774                                   %if _PM
  2775 00000844 0000                    psp_selector:	dw 0
  2776                                   %endif
  2777 00000846 0000                    psp_parent:	dw 0
  2778 00000848 00000000                psp_pra:	dd 0
  2779                                  %endif
  2780                                  
  2781                                  	align 2, db 0
  2782                                  isvariable_morebyte_nameheaders:
  2783                                  .ext:
  2784 0000084C 000000000000000000-     	dw IVS_MOREBYTE_NAMEHEADERS
  2784 00000855 000000000000000000-
  2784 0000085E 000000000000000000-
  2784 00000867 0000000000494E4C46-
  2784 00000870 524C4C46524C475253-
  2784 00000879 52534D534444454445-
  2784 00000882 44444D414D414D4D44-
  2784 0000088B 434443444944414441-
  2784 00000894 445044504450445044-
  2784 0000089D 504450445044505050-
  2784 000008A6 545054545245524552-
  2784 000008AF 435243524345525151-
  2784 000008B8 544541414141414441-
  2784 000008C1 444142414241554155-
  2784 000008CA 41454145415A415A41-
  2784 000008D3 434143415041504157-
  2784 000008DC 415744534453445344-
  2784 000008E5 534453445344534453-
  2784 000008EE 445344534453445344-
  2784 000008F7 53445344534453494F-
  2784 00000900 494F494F494F494F49-
  2784 00000909 4F494F494F494F414D-
  2784 00000912 545248484441434F52-
  2784 0000091B 485352535253525249-
  2784 00000924 4D4D59535948594252-
  2784 0000092D 455245575257525053-
  2784 00000936 505350535050505050-
  2784 0000093F 415052424F424F424F-
  2784 00000948 424F424F424F424F54-
  2784 00000951 524445445344534445-
  2784 0000095A 444544434443444344-
  2784 00000963 43444D444D44414441-
  2784 0000096C 444844484449444544-
  2784 00000975 454445444544454445-
  2784 0000097E 444544454441444144-
  2784 00000987 53444544434443444D-
  2784 00000990 444144484453444944-
  2784 00000999 454445444544454445-
  2784 000009A2 4445434943534C494C-
  2784 000009AB 494C494C49         
  2785                                  .end:
  2786                                  %if IVS_HAVE_ONEBYTE && ! IVS_SINGLE_ONEBYTE
  2787                                  isvariable_onebyte_names:
  2788                                  	db IVS_ONEBYTE_NAMES
  2789                                  .end:
  2790                                  %endif
  2791                                  
  2792 000009B0 54384354524C535246-     isvariablestrings ISVARIABLESTRINGS
  2792 000009B9 535253525441504653-
  2792 000009C2 52544F50455049444C-
  2792 000009CB 45455049444C454158-
  2792 000009D4 44454C5441454C5441-
  2792 000009DD 4C494D495456494345-
  2792 000009E6 53495A455649434548-
  2792 000009EF 454144455254455854-
  2792 000009F8 414E44434858383643-
  2792 00000A01 48583837544F53464F-
  2792 00000A0A 534952505241535041-
  2792 00000A13 52454E545353505345-
  2792 00000A1C 4C4343434C494D4954-
  2792 00000A25 434F554E544C494D49-
  2792 00000A2E 54434F554E5443434F-
  2792 00000A37 4445524D434F44454F-
  2792 00000A40 534F534F534F534F53-
  2792 00000A49 4F534F534F534F5352-
  2792 00000A52 435446505649505549-
  2792 00000A5B 505653505553505646-
  2792 00000A64 505546505650505550-
  2792 00000A6D 50564450554450564D-
  2792 00000A76 50554D434C494E4552-
  2792 00000A7F 4353454C46494B4953-
  2792 00000A88 4E554D59414D49534E-
  2792 00000A91 554D524553554C5452-
  2792 00000A9A 4553554C54554E5443-
  2792 00000AA3 4F554E544F53434646-
  2792 00000AAC 46414441445241444C-
  2792 00000AB5 454E49544144524954-
  2792 00000ABE 4C454E50535053454C-
  2792 00000AC7 50524952454E54414F-
  2792 00000AD0 54554E4954464C4F54-
  2792 00000AD9 4C4450554E49544F54-
  2792 00000AE2 534450554E49544F54-
  2792 00000AEB 594450554E49544F54-
  2792 00000AF4 4C4450504152544F54-
  2792 00000AFD 534450504152544F54-
  2792 00000B06 594450504152545944-
  2792 00000B0F 454255474E554D4255-
  2792 00000B18 4746554E435441434B-
  2792 00000B21 4C454E5441434B5345-
  2792 00000B2A 474E5452594C454E4E-
  2792 00000B33 5452595345474F4445-
  2792 00000B3C 314C454E4F44453153-
  2792 00000B45 45474F4445324C454E-
  2792 00000B4E 4F4445325345474553-
  2792 00000B57 534147454C454E4553-
  2792 00000B60 534147455345475558-
  2792 00000B69 4255464C454E555842-
  2792 00000B72 554653454749534255-
  2792 00000B7B 464C454E4953425546-
  2792 00000B84 5345474D4D53454758-
  2792 00000B8D 544C454E5854555345-
  2792 00000B96 445854534547585444-
  2792 00000B9F 4154414C454E585444-
  2792 00000BA8 415441555345445854-
  2792 00000BB1 444154414F46534E56-
  2792 00000BBA 4C454E4E565345474C-
  2792 00000BC3 4C4F4353495A454C4C-
  2792 00000BCC 4F435345475441434B-
  2792 00000BD5 53454C4E5452595345-
  2792 00000BDE 4C4F44453153454C4F-
  2792 00000BE7 44453253454C455353-
  2792 00000BF0 41474553454C555842-
  2792 00000BF9 554653454C49534255-
  2792 00000C02 4653454C4352415443-
  2792 00000C0B 4853454C4D4D53454C-
  2792 00000C14 5854435353454C5854-
  2792 00000C1D 445353454C4641554C-
  2792 00000C26 54444C454E4641554C-
  2792 00000C2F 54444C494E45534641-
  2792 00000C38 554C54554C454E4641-
  2792 00000C41 554C54554C494E4553-
  2792 00000C4A 50504E4B4F46465345-
  2792 00000C53 544E4B504F494E5445-
  2792 00000C5C 524E4B5345474E4B53-
  2792 00000C65 454C               
  2793                                  
  2794                                  
  2795                                  %if _EXPRDUALCODE && _DUALCODE
  2796                                  	usesection lDEBUG_CODE2
  2796          ------------------       note: usesection lDEBUG_CODE2
  2797                                  %else
  2798                                  	usesection lDEBUG_CODE
  2799                                  %endif
  2800                                  isvariable_code:
  2801                                  		; INP:	ax = array index (0-based)
  2802                                  		;	di = 0
  2803                                  		;	cl = default size of variable (1..4)
  2804                                  		;	ch = length of variable name
  2805                                  		;	bx -> ISVARIABLESTRUC structure
  2806                                  		; CHG:	ax, bx, cx, dx, si, di
  2807                                  		; OUT:	NC if valid,
  2808                                  		;	 bx -> var, di = 0 or di -> mask
  2809                                  		;	 cl = size of variable (1..4)
  2810                                  		;	 ch = length of variable name
  2811                                  
  2812                                  %if _EXTENSIONS && _EXT_VARIABLES
  2813                                  var_ext_setup: section_of_function
  2814 00000838 87F9                    	xchg di, cx
  2815 0000083A 8B4F04                  	mov cx, word [bx + ivAddress]
  2816 0000083D E307                    	jcxz .cy
  2817                                  %if _EXPRDUALCODE && _DUALCODE
  2818 0000083F E8(0000)EB02[0000]      	nearcall transfer_ext_cx_nearcall_from_code2
  2819                                  
  2820                                  	usesection lDEBUG_CODE
  2820          ------------------       note: usesection lDEBUG_CODE
  2821                                  transfer_ext_cx_nearcall_from_code2: section_of_function
  2822 00000000 83C406                  	add sp, 6
  2823                                  %endif
  2824 00000003 E9(0000)                	jmp transfer_ext_cx
  2825                                  
  2826                                  %if _EXPRDUALCODE && _DUALCODE
  2827                                  	usesection lDEBUG_CODE2
  2827          ------------------       note: usesection lDEBUG_CODE2
  2828                                  %endif
  2829                                  
  2830                                  var_ext_setup.cy:
  2831 00000846 87F9                    	xchg di, cx
  2832 00000848 F9                      	stc
  2833 00000849 C3                      	retn
  2834                                  
  2835                                  var_ext_setup_done: section_of_function
  2836 0000084A 58                      	pop ax
  2837 0000084B 58                      	pop ax
  2838 0000084C 58                      	pop ax
  2839 0000084D C3                      	retn
  2840                                  %endif
  2841                                  
  2842                                  
  2843                                  %if _PM
  2844                                  var_cip_setup: section_of_function
  2845 0000084E 8B1E[0000]              	mov bx, word [reg_cs]
  2846 00000852 E8(0000)EB02[0000]      	nearcall test_d_b_bit
  2847 00000859 BB[0000]                	mov bx, reg_eip
  2848                                  @@:
  2849 0000085C 7402                    	jz .ret
  2850 0000085E 41                      	inc cx
  2851 0000085F 41                      	inc cx			; = 4
  2852                                  .ret:
  2853 00000860 F8                      	clc			; (NC)
  2854 00000861 C3                      	retn
  2855                                  
  2856                                  var_csp_setup: section_of_function
  2857 00000862 8B1E[0000]              	mov bx, word [reg_ss]
  2858 00000866 E8(0000)EB02[0000]      	nearcall test_d_b_bit
  2859 0000086D BB[0000]                	mov bx, reg_esp
  2860 00000870 EBEA                    	jmp @B
  2861                                  %endif
  2862                                  
  2863                                  
  2864                                  var_lfsr_setup: section_of_function
  2865 00000872 BB[2001]                	mov bx, lfsr
  2866 00000875 D16F02                  	shr word [bx + 2], 1
  2867 00000878 D11F                    	rcr word [bx], 1
  2868 0000087A 730B                    	jnc .ret		; if not to tap --> (NC)
  2869 0000087C A1[2801]                	mov ax, word [lfsrtap]
  2870 0000087F 3107                    	xor word [bx], ax
  2871 00000881 A1[2A01]                	mov ax, word [lfsrtap + 2]
  2872 00000884 314702                  	xor word [bx + 2], ax	; (NC)
  2873                                  .ret:
  2874 00000887 C3                      	retn
  2875                                  
  2876                                  
  2877                                  var_reverselfsr_setup: section_of_function
  2878 00000888 BB[2401]                	mov bx, reverselfsr
  2879 0000088B 91                      	xchg ax, cx		; preserve original cx
  2880 0000088C 8A0E[1E01]              	mov cl, byte [reverselfsrtop]
  2881 00000890 BE0100                  	mov si, 1		; register for shift mask
  2882 00000893 80F910                  	cmp cl, 16		; fits in low 16 bits ?
  2883 00000896 721B                    	jb .below_16		; yes -->
  2884 00000898 80E910                  	sub cl, 16		; get bit within high word
  2885 0000089B 80F910                  	cmp cl, 16		; beyond maximum ?
  2886 0000089E 7202                    	jb @F
  2887 000008A0 B10F                    	mov cl, 15		; yes, clamp to bit 31 (for now)
  2888                                  @@:
  2889 000008A2 D3E6                    	shl si, cl		; shift to get a bitmask
  2890 000008A4 91                      	xchg cx, ax		; restore the original cx
  2891 000008A5 857702                  	test word [bx + 2], si	; is top bit set ?
  2892 000008A8 9F                      	lahf			; preserve ZF
  2893 000008A9 F7D6                    	not si			; invert mask to allow clearing
  2894 000008AB 217702                  	and word [bx + 2], si	; clear the bit if it was set
  2895 000008AE BFFFFF                  	mov di, -1		; si:di = mask what to clear in taps
  2896 000008B1 EB0F                    	jmp @F
  2897                                  
  2898                                  .below_16:
  2899 000008B3 D3E6                    	shl si, cl		; shift to get a bitmask
  2900 000008B5 91                      	xchg cx, ax		; restore the original cx
  2901 000008B6 8537                    	test word [bx], si	; is top bit set ?
  2902 000008B8 9F                      	lahf			; preserve ZF
  2903 000008B9 F7D6                    	not si			; invert mask to allow clearing
  2904 000008BB 2137                    	and word [bx], si	; clear the bit if it was set
  2905 000008BD 89F7                    	mov di, si
  2906 000008BF BEFFFF                  	mov si, -1		; si:di = mask what to clear in taps
  2907                                  @@:
  2908 000008C2 9E                      	sahf			; restore ZF
  2909 000008C3 97                      	xchg ax, di		; si:ax = mask what to clear in taps
  2910 000008C4 7416                    	jz .justshift		; if not to tap, just shift --> (NC)
  2911 000008C6 E81300                  	call .justshift		; also shift, but return to us afterwards
  2912 000008C9 2306[2801]              	and ax, word [lfsrtap]
  2913 000008CD 2336[2A01]              	and si, word [lfsrtap + 2]
  2914                                  				; get the taps (highest bit cleared)
  2915 000008D1 F9                      	stc			; lowest bit will get set to 1
  2916 000008D2 D1D0                    	rcl ax, 1
  2917 000008D4 D1D6                    	rcl si, 1		; shift the taps to create reverse taps
  2918 000008D6 3107                    	xor word [bx], ax
  2919 000008D8 317702                  	xor word [bx + 2], si	; tap (NC)
  2920 000008DB C3                      	retn
  2921                                  
  2922                                  .justshift:
  2923 000008DC D127                    	shl word [bx], 1
  2924 000008DE D15702                  	rcl word [bx + 2], 1
  2925 000008E1 31FF                    	xor di, di		; restore di = 0
  2926                                  				; also: set NC if return from setup function
  2927 000008E3 C3                      	retn
  2928                                  
  2929                                  
  2930                                  %if _PM
  2931                                  var_dpspsel_setup: section_of_function
  2932 000008E4 BB[4208]                	mov bx, dpspsel
  2933 000008E7 8C17                    	mov word [bx], ss
  2934 000008E9 F8                      	clc
  2935 000008EA C3                      	retn
  2936                                  
  2937                                  var_seldbg_setup: section_of_function
  2938 000008EB BB[4008]                	mov bx, seldbg
  2939 000008EE 832700                  	and word [bx], byte 0
  2940 000008F1 E8(0000)EB02[0000]      	nearcall ispm
  2941 000008F8 7502                    	jnz @F
  2942 000008FA 8C1F                    	mov word [bx], ds
  2943                                  @@:
  2944 000008FC F8                      	clc
  2945 000008FD C3                      	retn
  2946                                  %endif
  2947                                  
  2948                                  %if _DEBUG3
  2949                                  var_mt_setup: section_of_function
  2950                                  	mov bx, ax
  2951                                  	add bx, bx
  2952                                  	add bx, bx
  2953                                  	mov di, bx
  2954                                  	add bx, mtest_regs
  2955                                  	add di, masks_test
  2956                                  	clc
  2957                                  	retn
  2958                                  %endif
  2959                                  
  2960                                  
  2961                                  %if _RH
  2962                                  		; INP:	ax = array index (0-based)
  2963                                  		;	di = 0
  2964                                  		;	cl = default size of variable (1..4)
  2965                                  		;	ch = length of variable name
  2966                                  		;	bx -> ISVARIABLESTRUC structure
  2967                                  		; CHG:	ax, bx, cx, dx, si, di
  2968                                  		; OUT:	NC if valid,
  2969                                  		;	 bx -> var, di = 0 or di -> mask
  2970                                  		;	 cl = size of variable (1..4)
  2971                                  		;	 ch = length of variable name
  2972                                  var_rhcount_setup: section_of_function
  2973 000008FE 51                      	push cx
  2974                                  %if _PM
  2975 000008FF 8B3E[0000]              	mov di, word [auxbuff_switchbuffer_size]
  2976                                  %else
  2977                                  	xor di, di
  2978                                  %endif
  2979 00000903 E8(0000)EB02[0000]      	nearcall silence_get_start.have_di
  2980 0000090A E8(0000)EB02[0000]      	nearcall silence_count_zeroes
  2981                                  
  2982 00000911 93                      	xchg bx, ax
  2983 00000912 BB[3801]                	mov bx, rhcount
  2984 00000915 8907                    	mov word [bx], ax
  2985 00000917 59                      	pop cx
  2986 00000918 16                      	push ss
  2987 00000919 07                      	pop es
  2988 0000091A 31FF                    	xor di, di		; NC
  2989 0000091C C3                      	retn
  2990                                  %endif
  2991                                  
  2992                                  
  2993                                  var_ioi_setup: section_of_function
  2994 0000091D 800E[0000]10            	setopt [internalflags3], dif3_input_terminal_override
  2995 00000922 E8(0000)EB02[0000]      	nearcall peekc
  2996 00000929 8026[0000]EF            	clropt [internalflags3], dif3_input_terminal_override
  2997 0000092E BB[3C08]                	mov bx, ioi_var
  2998 00000931 8907                    	mov word [bx], ax
  2999 00000933 F8                      	clc
  3000 00000934 C3                      	retn
  3001                                  
  3002                                  var_iok_setup: section_of_function
  3003 00000935 800E[0000]10            	setopt [internalflags3], dif3_input_terminal_override
  3004 0000093A E8(0000)EB02[0000]      	nearcall getc
  3005 00000941 8026[0000]EF            	clropt [internalflags3], dif3_input_terminal_override
  3006 00000946 BB[3E08]                	mov bx, iok_var
  3007 00000949 8907                    	mov word [bx], ax
  3008 0000094B F8                      	clc
  3009 0000094C C3                      	retn
  3010                                  
  3011                                  %if !_LOADER
  3012                                  %if _PSPVARIABLES
  3013                                  %if _PM
  3014                                  var_psps_setup: section_of_function
  3015 0000094D BB[4408]                	mov bx, psp_selector
  3016 00000950 E86100                  	nearcall var_get_psp_segment
  3017 00000953 7211                    	jc @F
  3018 00000955 E8(0000)EB02[0000]      	nearcall ispm
  3019 0000095C 7508                    	jnz @F
  3020 0000095E 53                      	push bx
  3021 0000095F 93                      	xchg ax, bx
  3022 00000960 B80200                  	mov ax, 0002h
  3023 00000963 CD31                    	int 31h
  3024 00000965 5B                      	pop bx
  3025                                  @@:
  3026 00000966 8907                    	mov word [bx], ax
  3027 00000968 F8                      	clc
  3028 00000969 C3                      	retn
  3029                                  %endif
  3030                                  
  3031                                  
  3032                                  var_ppr_setup: section_of_function
  3033                                   %if _PM
  3034 0000096A 83EC08                  	 sub sp, 8
  3035 0000096D E8BC0C                  	call save_scratchsel
  3036                                   %endif
  3037 00000970 BB[4608]                	mov bx, psp_parent
  3038 00000973 31C0                     	xor ax, ax
  3039 00000975 8907                    	mov word [bx], ax
  3040 00000977 E84900                  	nearcall var_get_psp_selector
  3041 0000097A 7206                    	jc @F
  3042 0000097C 26A11600                	mov ax, word [es:16h]
  3043 00000980 8907                    	mov word [bx], ax		; retrieve parent process
  3044                                  @@:
  3045 00000982 16                      	push ss
  3046 00000983 07                      	pop es
  3047                                   %if _PM
  3048 00000984 E8CA0C                  	call restore_scratchsel
  3049                                  		; This is not really needed but does not hurt either.
  3050                                   		;  getsegmented is used above, but only from PM.
  3051                                   		;  This is assumed not to switch modes.
  3052 00000987 E8(0000)EB02[0000]      	nearcall resetmode		; reset mode if we switched
  3053                                   %endif
  3054 0000098E F8                      	clc
  3055 0000098F C3                      	retn
  3056                                  
  3057                                  
  3058                                  var_ppi_setup: section_of_function
  3059                                   %if _PM
  3060 00000990 83EC08                  	 sub sp, 8
  3061 00000993 E8960C                  	call save_scratchsel
  3062                                   %endif
  3063 00000996 BB[4808]                	mov bx, psp_pra
  3064 00000999 31C0                     	xor ax, ax
  3065 0000099B 8907                    	mov word [bx], ax
  3066 0000099D 894702                  	mov word [bx + 2], ax
  3067 000009A0 E82000                  	nearcall var_get_psp_selector
  3068 000009A3 72DD                    	jc @B
  3069 000009A5 26A10A00                	mov ax, word [es:TPIV]
  3070 000009A9 8907                    	mov word [bx], ax
  3071 000009AB 26A10C00                	mov ax, word [es:TPIV + 2]
  3072 000009AF 894702                  	mov word [bx + 2], ax		; retrieve Int22 address
  3073 000009B2 EBCE                    	jmp @B
  3074                                  
  3075                                  
  3076                                  var_get_psp_segment: section_of_function
  3077 000009B4 A1[0000]                	mov ax, word [pspdbe]
  3078 000009B7 40                      	inc ax				; FFFFh ?
  3079 000009B8 7405                    	jz short .pspvar_psp_invalid	; yes, invalid -->
  3080 000009BA 48                      	dec ax				; 0 ?
  3081 000009BB 7402                    	jz short .pspvar_psp_invalid	; yes, invalid -->
  3082 000009BD F8                      	clc
  3083 000009BE C3                      	retn
  3084                                  
  3085                                  .pspvar_psp_invalid:
  3086 000009BF 31C0                    	xor ax, ax
  3087 000009C1 F9                      	stc
  3088 000009C2 C3                      	retn
  3089                                  
  3090                                  
  3091                                  var_get_psp_selector: section_of_function
  3092 000009C3 E8EEFF                  	nearcall var_get_psp_segment
  3093 000009C6 723F                    	jc .pspvar_psp_invalid
  3094                                   %if _PM
  3095 000009C8 E8(0000)EB02[0000]      	nearcall ispm
  3096 000009CF 7529                    	jnz short .pspvar_rm
  3097 000009D1 53                      	push bx
  3098 000009D2 66                      	_386_o32		; push edx
  3099 000009D3 52                      	push dx
  3100 000009D4 51                      	push cx
  3101 000009D5 31D2                    	xor dx, dx
  3102 000009D7 B90400                  	mov cx, 4
  3103                                  .pspvar_shift:
  3104 000009DA D1E0                    	shl ax, 1
  3105 000009DC D1D2                    	rcl dx, 1
  3106 000009DE E2FA                    	loop .pspvar_shift		; dx:ax = PSP segment << 4
  3107 000009E0 E8(0000)EB02[0000]      	nearcall getsegmented
  3108                                  		; getsegmented is assumed not to switch modes (see below).
  3109 000009E7 7220                    	jc short .pspvar_error		; (shouldn't happen)
  3110 000009E9 66                      	_386_o32
  3111 000009EA 85D2                    	test dx, dx		; test edx, edx
  3112 000009EC 751B                    	jnz short .pspvar_error		; (assumed not to happen)
  3113 000009EE E8(0000)EB02[0000]      	nearcall setrmlimit
  3114 000009F5 59                      	pop cx
  3115 000009F6 66                      	_386_o32
  3116 000009F7 5A                      	pop dx			; pop edx
  3117 000009F8 93                      	xchg ax, bx			; ax = selector
  3118 000009F9 5B                      	pop bx
  3119                                  .pspvar_rm:
  3120                                   %endif
  3121 000009FA 8EC0                    	mov es, ax			; es = segment/selector
  3122 000009FC 26813E0000CD20          	cmp word [es:0], 20CDh		; int 20h opcode ?
  3123 00000A03 7502                    	jne short .pspvar_psp_invalid	; no, invalid -->
  3124 00000A05 F8                      	clc
  3125 00000A06 C3                      	retn
  3126                                  
  3127                                  .pspvar_psp_invalid:
  3128 00000A07 F9                      	stc
  3129 00000A08 C3                      	retn
  3130                                  
  3131                                  .pspvar_error:
  3132 00000A09 31F6                    	xor si, si
  3133 00000A0B E9F2F5                  	jmp error_expr
  3134                                  %endif
  3135                                  %endif
  3136                                  
  3137                                  
  3138                                  %if _BOOTLDR
  3139                                  var_bootldpunit_setup: section_of_function
  3140 00000A0E BB[6000]                	mov bx, loaddata_loadedfrom - LOADDATA 			+ bsBPB + ebpbNew + bpbnBootUnit
  3142 00000A11 EB45                    	jmp @F
  3143                                  
  3144                                  var_bootsdpunit_setup: section_of_function
  3145 00000A13 BB[7000]                	mov bx, load_data - LOADDATA2 			+ bsBPB + ebpbNew + bpbnBootUnit
  3147 00000A16 EB40                    	jmp @F
  3148                                  
  3149                                  %if _INPUT_FILE_BOOT
  3150                                  var_bootydpunit_setup: section_of_function
  3151 00000A18 F606[0300]02            	testopt [internalflags2], dif2_input_file_boot
  3152 00000A1D 7440                    	jz .retc
  3153                                  
  3154 00000A1F 52                      	push dx
  3155 00000A20 B8A000                  	mov ax, LOAD_INPUT_FILE_SIZE
  3156 00000A23 F726[0000]              	mul word [load_input_file.active]
  3157 00000A27 5A                      	pop dx
  3158                                  
  3159 00000A28 93                      	xchg ax, bx
  3160 00000A29 8D9F[8000]              	lea bx, [load_input_file + bx - LOADDATA3 			+ bsBPB + ebpbNew + bpbnBootUnit]
  3162 00000A2D EB29                    	jmp @F
  3163                                  %endif
  3164                                  
  3165                                  var_bootldppart_setup: section_of_function
  3166 00000A2F BB[3C00]                	mov bx, loaddata_loadedfrom - LOADDATA 			+ bsBPB + bpbHiddenSectors
  3168 00000A32 EB24                    	jmp @F
  3169                                  
  3170                                  var_bootsdppart_setup: section_of_function
  3171 00000A34 BB[4C00]                	mov bx, load_data - LOADDATA2 			+ bsBPB + bpbHiddenSectors
  3173 00000A37 EB1F                    	jmp @F
  3174                                  
  3175                                  %if _INPUT_FILE_BOOT
  3176                                  var_bootydppart_setup: section_of_function
  3177 00000A39 F606[0300]02            	testopt [internalflags2], dif2_input_file_boot
  3178 00000A3E 741F                    	jz .retc
  3179                                  
  3180 00000A40 52                      	push dx
  3181 00000A41 B8A000                  	mov ax, LOAD_INPUT_FILE_SIZE
  3182 00000A44 F726[0000]              	mul word [load_input_file.active]
  3183 00000A48 5A                      	pop dx
  3184                                  
  3185 00000A49 93                      	xchg ax, bx
  3186 00000A4A 8D9F[5C00]              	lea bx, [load_input_file + bx - LOADDATA3 			+ bsBPB + bpbHiddenSectors]
  3188 00000A4E EB08                    	jmp @F
  3189                                  %endif
  3190                                  
  3191                                  var_bootunitflags_setup: section_of_function
  3192 00000A50 05[0000]                	add ax, load_unit_flags
  3193 00000A53 89C3                    	mov bx, ax
  3194 00000A55 BF[7C0C]                	mov di, mask_bootunitflags
  3195                                  @@:
  3196 00000A58 F606[0100]40            	testopt [internalflags], nodosloaded
  3197 00000A5D 7501                    	jnz @F				; (NC)
  3198                                  var_bootydpunit_setup.retc:
  3199                                  var_bootydppart_setup.retc:
  3200 00000A5F F9                      	stc
  3201                                  @@:
  3202 00000A60 C3                      	retn
  3203                                  %endif
  3204                                  
  3205                                  
  3206                                  	usesection lDEBUG_DATA_ENTRY
  3206          ------------------       note: usesection lDEBUG_DATA_ENTRY
  3207                                  
  3208 00000C67 00                      	align 4, db 0
  3209                                  masks:
  3210                                  	; size 4 want masks + 0
  3211                                  	; size 3 want masks + 1
  3212                                  	; size 2 want masks + 2
  3213                                  	; size 1 want masks + 3
  3214                                  	; size 0 want masks + 4
  3215                                  	; 4 - size = offset into masks
  3216 00000C68 00                      mask_4byte:		db 0
  3217 00000C69 00                      mask_3byte:		db 0
  3218 00000C6A 00                      mask_2byte:		db 0
  3219 00000C6B 00                      mask_1byte:		db 0
  3220 00000C6C FFFFFFFF                mask_0byte:		dd -1
  3221 00000C70 FFFF0000                mask_compoundwithzero:	db -1, -1, 0, 0
  3222                                  mask_compoundreg8withzero:
  3223 00000C74 FFFF00FF                			db -1, -1, 0, -1
  3224 00000C78 FF0FFFFF                mask_ysf:		dd ~ (ifhfTestReserved1 | ifhfTestReserved2 				| ifhfQuietInput | ifhfQuietOutput)
  3226                                  %if _BOOTLDR
  3227 00000C7C F8FFFFFF                mask_bootunitflags:	dd ~ luf_mask_writable
  3228                                  %endif
  3229                                  
  3230                                  %if _DEBUG3
  3231                                  masks_test:
  3232                                  mask_test_0:		dd 0AA55AA55h
  3233                                  mask_test_1:		dd 00FF00FFh
  3234                                  mtest_regs:
  3235                                  mtest_reg_0:		dd 0
  3236                                  mtest_reg_1:		dd 00110022h
  3237                                  %endif
  3238                                  
  3239                                  
  3240                                  %if _EXPRDUALCODE && _DUALCODE
  3241                                  	usesection lDEBUG_CODE2
  3241          ------------------       note: usesection lDEBUG_CODE2
  3242                                  %else
  3243                                  	usesection lDEBUG_CODE
  3244                                  %endif
  3245                                  
  3246                                  %if _SYMBOLIC
  3247                                  		; INP:	al = first character
  3248                                  		;	si -> next character
  3249                                  		; OUT:	CY if no symbol
  3250                                  		;	NC if symbol,
  3251                                  		;	 bx:dx = symbol (offset) value
  3252                                  		;	 al = next character behind symbol
  3253                                  		;	 si -> behind next character
  3254                                  		; CHG:	ah, bx, cx, dx
  3255                                  		; STT:	ss = ds = es, UP
  3256                                  		;
  3257                                  		; Note:	This invalidates the symbol table access slice.
  3258                                  issymbol?: section_of_function
  3259                                  	nearcall zz_detect_xms	; re-detect XMS if used after run (eg WHILE)
  3260                                  
  3261                                  	lframe near
  3262                                  	lvar word,	new_si
  3263                                  	lenter
  3264                                  	lvar word,	orig_si
  3265                                  	 push si
  3266                                  	lvar word,	orig_ax
  3267                                  	 push ax
  3268                                  	xor bx, bx
  3269                                  	lequ 1,		flag_has_nondigit
  3270                                  	lequ 2,		flag_has_symbol_prefix
  3271                                  	lequ 4,		flag_has_linear
  3272                                  	lequ 8,		flag_has_offset
  3273                                  	lequ 16,	flag_has_base
  3274                                  	lequ 32,	flag_is_86m_segment
  3275                                  	lvar word,	flags
  3276                                  	 push bx
  3277                                  	lvar word,	main_index	; used as parameter to zz_match_symbol
  3278                                  	 push ax
  3279                                  
  3280                                  	dec si
  3281                                  %if 0
  3282                                  	cmp al, '.'
  3283                                  	jne @F
  3284                                  	inc si			; allow dot prefix to symbol name
  3285                                  	mov al, byte [si]
  3286                                  @@:
  3287                                  %endif
  3288                                  	cmp al, '0'
  3289                                  	jb @F
  3290                                  	cmp al, '9'
  3291                                  	jbe .not
  3292                                  @@:
  3293                                  
  3294                                  	mov dx, msg.sl
  3295                                  	nearcall isstring?
  3296                                  	jne @F
  3297                                  	lodsb
  3298                                  	cmp al, '.'
  3299                                  	jne short .error
  3300                                  	or byte [bp + ?flags], ?flag_has_symbol_prefix | ?flag_has_linear
  3301                                  	jmp .not_symbol_prefix
  3302                                  @@:
  3303                                  
  3304                                  	mov dx, msg.symbol
  3305                                  	nearcall isstring?
  3306                                  	jne .not_symbol_prefix
  3307                                  	lodsb
  3308                                  	cmp al, '.'
  3309                                  	jne short .error
  3310                                  	or byte [bp + ?flags], ?flag_has_symbol_prefix
  3311                                  
  3312                                  	mov dx, msg.linear
  3313                                  	nearcall isstring?
  3314                                  	jne @F
  3315                                  	lodsb
  3316                                  	cmp al, '.'
  3317                                  	jne short .error
  3318                                  	or byte [bp + ?flags], ?flag_has_linear
  3319                                  @@:
  3320                                  
  3321                                  	mov dx, msg.offset
  3322                                  	nearcall isstring?
  3323                                  	jne @F
  3324                                  	lodsb
  3325                                  	cmp al, '.'
  3326                                  	jne short .error
  3327                                  	test byte [bp + ?flags], ?flag_has_linear
  3328                                  	jnz short .error
  3329                                  	or byte [bp + ?flags], ?flag_has_offset
  3330                                  @@:
  3331                                  
  3332                                  	mov dx, msg.base
  3333                                  	nearcall isstring?
  3334                                  	jne @F
  3335                                  	lodsb
  3336                                  	cmp al, '.'
  3337                                  	jne short .error
  3338                                  	test byte [bp + ?flags], ?flag_has_linear | ?flag_has_offset
  3339                                  	jnz short .error
  3340                                  	or byte [bp + ?flags], ?flag_has_base
  3341                                  @@:
  3342                                  
  3343                                  .not_symbol_prefix:
  3344                                  
  3345                                  	xor bx, bx
  3346                                  	mov dx, si
  3347                                  .loopname:
  3348                                  	lodsb
  3349                                  	nearcall isseparator?.except_L_or_dot
  3350                                  	je .endname
  3351                                  	nearcall getexpression.lit_ishexdigit?
  3352                                  	jnc @F
  3353                                  	or byte [bp + ?flags], ?flag_has_nondigit
  3354                                  @@:
  3355                                  	inc bx
  3356                                  	jmp .loopname
  3357                                  
  3358                                  .error:
  3359                                  	jmp error_expr			; does not use es
  3360                                  
  3361                                  .endname:
  3362                                  	mov word [bp + ?new_si], si
  3363                                  	mov cx, bx
  3364                                  	test cx, cx
  3365                                  	jz .not
  3366                                  
  3367                                  	test byte [bp + ?flags], ?flag_has_nondigit | ?flag_has_symbol_prefix
  3368                                  	jz .not
  3369                                  
  3370                                  	mov si, dx
  3371                                  	push cx
  3372                                  	nearcall zz_hash
  3373                                  	pop cx
  3374                                  
  3375                                  .loop:
  3376                                  		; ?main_index used as parameter
  3377                                  	 push ss
  3378                                  	 push dx
  3379                                  	 push cx
  3380                                  
  3381                                  	dualcall zz_match_symbol		; ! note that possibly es != ss
  3382                                  	jc .not
  3383                                  
  3384                                  	testopt [es:di + smFlags], smfPoison
  3385                                  	jz @F
  3386                                  	setopt [internalflags2], dif2_poison
  3387                                  @@:
  3388                                  
  3389                                  	mov dx, word [es:di + smLinear]
  3390                                  	mov bx, word [es:di + smLinear + 2]
  3391                                  	test byte [bp + ?flags], ?flag_has_linear
  3392                                  	jnz .got
  3393                                  	test byte [bp + ?flags], ?flag_has_base
  3394                                  	jz .offset
  3395                                  .base:
  3396                                  		; offset=100 linear=10100 base=10000
  3397                                  	sub dx, word [es:di + smOffset]
  3398                                  	sbb bx, word [es:di + smOffset + 2]
  3399                                  	jmp .got
  3400                                  
  3401                                  .offset:
  3402                                  	mov si, word [bp + ?new_si]
  3403                                  	dec si
  3404                                  	nearcall skipcomma		; does not use es
  3405                                  	dec si
  3406                                  	mov dx, msg.wrt
  3407                                  	push es
  3408                                  	 push ss
  3409                                  	 pop es
  3410                                  	nearcall isstring?		; uses es
  3411                                  	pop es
  3412                                  	jne .offset_no_wrt
  3413                                  
  3414                                  	nearcall skipcomma		; does not use es
  3415                                  
  3416                                  	cmp al, '$'
  3417                                  	jne @F
  3418                                  
  3419                                  	or byte [bp + ?flags], ?flag_is_86m_segment
  3420                                  	nearcall skipcomma		; does not use es
  3421                                  @@:
  3422                                  
  3423                                  	push word [hh_depth_of_single_term]
  3424                                  	mov dx, word [hh_depth]
  3425                                  	inc dx
  3426                                  	mov word [hh_depth_of_single_term], dx
  3427                                  	 push ss
  3428                                  	 pop es
  3429                                  	nearcall getexpression		; (recursive) uses es
  3430                                  	pop word [hh_depth_of_single_term]
  3431                                  
  3432                                  		; The getexpression call may recurse into calling
  3433                                  		;  this function itself again. Therefore, it can
  3434                                  		;  invalidate the access slice. To make sure we
  3435                                  		;  can access the SYMMAIN entry again, reload it.
  3436                                  	 push word [bp + ?main_index]
  3437                                  	 push ax		; (reserve space, uninitialised)
  3438                                  	dualcall getfarpointer.main
  3439                                  	 pop di
  3440                                  	 pop es
  3441                                  
  3442                                  	nearcall skipcomm0		; does not use es
  3443                                  	mov word [bp + ?new_si], si
  3444                                  
  3445                                  	test bx, bx
  3446                                  	jnz short .errorj1
  3447                                  
  3448                                  	mov bx, dx
  3449                                  %if _PM
  3450                                  	test byte [bp + ?flags], ?flag_is_86m_segment
  3451                                  	jnz .wrt_rm
  3452                                  	nearcall ispm			; does not use es
  3453                                  	jnz .wrt_rm
  3454                                  
  3455                                  	mov ax, 0006h
  3456                                  	int 31h					; cx:dx = base
  3457                                  	jc short .errorj1
  3458                                  	xchg ax, cx				; ax:dx = base
  3459                                  	xchg dx, ax				; dx:ax = base
  3460                                  	jmp .offset_wrt
  3461                                  
  3462                                  .wrt_rm:
  3463                                  %endif
  3464                                  	xor dx, dx
  3465                                  	mov ax, bx
  3466                                  	mov cx, 4
  3467                                  @@:
  3468                                  	shl ax, 1
  3469                                  	rcl dx, 1
  3470                                  	loop @B
  3471                                  
  3472                                  .offset_wrt:
  3473                                  		; dx:ax = seg base
  3474                                  
  3475                                  		; offset=100
  3476                                  		; linear=10100
  3477                                  		; seg base=8000
  3478                                  		; offset wrt seg=8100
  3479                                  	neg dx
  3480                                  	neg ax
  3481                                  	sbb dx, byte 0				; neg dx:ax
  3482                                  	add ax, word [es:di + smLinear]
  3483                                  	adc dx, word [es:di + smLinear + 2]	; linear - seg base
  3484                                  	xchg ax, dx				; ax:dx = value
  3485                                  	xchg ax, bx				; bx:dx = value
  3486                                  	jmp .got
  3487                                  
  3488                                  .errorj1:
  3489                                  	jmp error_expr			; does not use es
  3490                                  
  3491                                  
  3492                                  .offset_no_wrt:
  3493                                  	mov dx, word [es:di + smOffset]
  3494                                  	mov bx, word [es:di + smOffset + 2]
  3495                                  
  3496                                  .got:
  3497                                  	testopt [es:di + smFlags], smfBase
  3498                                  	jz @F
  3499                                  	push word [bp + ?main_index]
  3500                                  	pop word [sym_storage.main.based.base]
  3501                                  		; if called from zz_add set up base
  3502                                  @@:
  3503                                  
  3504                                  	mov si, word [bp + ?new_si]
  3505                                  	dec si
  3506                                  	lodsb
  3507                                  	clc
  3508                                  	jmp .ret
  3509                                  .not:
  3510                                  	stc
  3511                                  
  3512                                  	mov si, word [bp + ?orig_si]
  3513                                  	mov ax, word [bp + ?orig_ax]
  3514                                  .ret:
  3515                                  	push ss
  3516                                  	pop es				; reset es
  3517                                  	lleave
  3518                                  	retn
  3519                                  %endif
  3520                                  
  3521                                  
  3522                                  		; INP:	al = first character
  3523                                  		;	si-> next character
  3524                                  		; OUT:	CY if no variable,
  3525                                  		;	 al, si = unchanged
  3526                                  		;	NC if variable,
  3527                                  		;	 bx-> low word
  3528                                  		;	 dx-> high word
  3529                                  		;		(if cl <= 2 then dx-> some word in our memory)
  3530                                  		;		(dx != bx+2 if compound register)
  3531                                  		;	 cl = size of variable (1, 2, 3, 4 bytes)
  3532                                  		;	 ch = size of variable's name (2..13 bytes)
  3533                                  		;		(this is limited to ivfNameLengthLimit)
  3534                                  		;	 INP:si - 1 -> variable's name
  3535                                  		;		(can be modified from original content)
  3536                                  		;	 ah = 0 if a writeable variable (ie simply memory)
  3537                                  		;	      1 if a read-only variable (ie simply memory)
  3538                                  		;	      2..33 if an MMX register, see note below
  3539                                  		;	 al = next character behind variable
  3540                                  		;	 si-> behind next character
  3541                                  		;	 dword [di] = mask of bits that are read-only
  3542                                  		; CHG:	ah, bx, dx, cx, di
  3543                                  		; STT:	ss = ds = es, UP
  3544                                  		;
  3545                                  		; Note: For read access to (half of) an MMX register, no
  3546                                  		;	 special handling is necessary at all, because cl,
  3547                                  		;	 bx, and dx are set up to access a buffer that
  3548                                  		;	 contains the current value. (The value should be
  3549                                  		;	 read at once though, as the buffer may be shared
  3550                                  		;	 or become outdated otherwise.)
  3551                                  		;	Write access to an MMX register must be handled
  3552                                  		;	 specifically, however. The returned field type
  3553                                  		;	 in ah indicates the register number (0..7) in the
  3554                                  		;	 lowest three bits. The two bits above those specify
  3555                                  		;	 the access type, which also specifies what was read
  3556                                  		;	 but need not be examined by readers. The access
  3557                                  		;	 type must be adhered to by writers. These are the
  3558                                  		;	 access types:
  3559                                  		;	  0 zero extension from 32 bits to write all 64 bits
  3560                                  		;	  1 sign extension from 32 bits to write all 64 bits
  3561                                  		;	  2 writes only low 32 bits
  3562                                  		;	  3 writes only high 32 bits
  3563                                  		;	 (Access type 3 is the only one for which the read
  3564                                  		;	 buffer is initialised with the high 32 bits.)
  3565                                  		;
  3566                                  		;	As dx points to 'some word in our memory' if it
  3567                                  		;	 doesn't serve any purpose, it is still valid to
  3568                                  		;	 read the word that it points to. Particularly dx
  3569                                  		;	 mustn't contain 0FFFFh then, but with the current
  3570                                  		;	 implementation, it can also be assumed that we do
  3571                                  		;	 actually 'own' the word (even with a PM segment
  3572                                  		;	 shorter than 64 KiB the read would be allowed).
  3573                                  isvariable?: section_of_function
  3574 00000A61 A8                      	db __TEST_IMM8		; (skip stc, NC)
  3575                                  
  3576                                  		; As above but additionally:
  3577                                  		;
  3578                                  		; INP:	di -> buffer to receive variable name, 14 bytes
  3579                                  		; OUT:	if NC, buffer filled with all-caps ASCIZ name
  3580                                  .return_name: section_of_function isvariable?
  3581 00000A62 F9                      	stc
  3582                                  
  3583 00000A63 4E                      	dec si
  3584                                  	lframe
  3585 00000A64 5589E5                  	lenter
  3586                                  	lvar word, bit0_is_return_name
  3587 00000A67 9C                      	 pushf
  3588                                  	lvar word, return_name_pointer
  3589 00000A68 57                      	 push di
  3590                                  %if ivfNameLengthLimit != 13
  3591                                   %error Adjust code here to new ivfNameLengthLimit
  3592                                  %endif
  3593 00000A69 31C0                    	xor ax, ax
  3594                                  	lvar 16, namebuffer
  3595 00000A6B 50                      	 push ax		; ax = 0 so that accidentally reading past
  3596                                  				;	  the actual buffer wouldn't match
  3597 00000A6C FF740C                  	 push word [si+12]
  3598 00000A6F FF740A                  	 push word [si+10]
  3599 00000A72 FF7408                  	 push word [si+8]
  3600 00000A75 FF7406                  	 push word [si+6]
  3601 00000A78 FF7404                  	 push word [si+4]
  3602 00000A7B FF7402                  	 push word [si+2]
  3603 00000A7E FF34                    	 push word [si]
  3604 00000A80 89E7                    	mov di, sp		; -> name buffer
  3605                                  
  3606                                  	lvar word, fieldtype_high_flags_low
  3607                                  	lequ ?fieldtype_high_flags_low + 1, fieldtype
  3608                                  	lequ ?fieldtype_high_flags_low, flags
  3609 00000A82 50                      	push ax			; field type initialised to 0 (RW), flags too
  3610 00000A83 31DB                    _386	xor bx, bx		; (a flag for the 32-bit register name check)
  3611                                  	lvar word, length_to_add
  3612 00000A85 50                      	push ax			; = 0
  3613                                  	lvar word, startpointer
  3614 00000A86 56                      	push si			; -> name start
  3615 00000A87 89FE                    	mov si, di
  3616 00000A89 57                      	 push di
  3617                                  
  3618 00000A8A B91000                  	mov cx, 16
  3619                                  .store:
  3620 00000A8D AC                      	lodsb
  3621                                  	; nearcall uppercase; (isseparator? calls uppercase)
  3622 00000A8E E89EF9                  	nearcall isseparator?
  3623 00000A91 F8                      	clc
  3624 00000A92 7501                    	jne short .not_separator
  3625 00000A94 F9                      	stc
  3626                                  .not_separator:
  3627 00000A95 D1DA                    	rcr dx, 1		; dl = flags indicating separators
  3628 00000A97 AA                      	stosb
  3629 00000A98 E2F3                    	loop .store
  3630                                  
  3631 00000A9A 5E                      	 pop si
  3632                                  
  3633 00000A9B F646FE01                	test byte [bp + ?bit0_is_return_name], 1
  3634 00000A9F 7409                    	jz @F
  3635                                  
  3636 00000AA1 56                      	push si
  3637 00000AA2 B107                    	mov cl, 14 >> 1
  3638 00000AA4 8B7EFC                  	mov di, word [bp + ?return_name_pointer]
  3639 00000AA7 F3A5                    	rep movsw
  3640 00000AA9 5E                      	pop si
  3641                                  
  3642                                  @@:
  3643 00000AAA F6C214                  	test dl, 1<<2|1<<4
  3644 00000AAD AD                      	lodsw
  3645 00000AAE 7503E9A500              	jz .notreg16
  3646                                  
  3647 00000AB3 E88C00                  	call .reg16names_match	; (iff no match, --> .notreg16)
  3648                                  				; bx-> regs entry of (first) match
  3649 00000AB6 F6C204                  	test dl, 1<<2
  3650 00000AB9 AD                      	lodsw
  3651 00000ABA 7436                    	jz @F
  3652 00000ABC F6C220                  	test dl, 1<<5
  3653 00000ABF 742E                    	jz .reg16_j
  3654 00000AC1 817CFC464C              	cmp word [si - 4], "FL"
  3655 00000AC6 7527                    	jne .reg16_j
  3656 00000AC8 3C2E                    	cmp al, '.'
  3657 00000ACA 7523                    	jne .reg16_j
  3658 00000ACC 4E                      	dec si
  3659 00000ACD AD                      	lodsw
  3660 00000ACE BF[0000]                	mov di, flagnames
  3661 00000AD1 B9[0000]                	mov cx, flagbits.amount
  3662 00000AD4 F2AF                    	repne scasw
  3663 00000AD6 7517                    	jne .reg16_j
  3664                                  %if _LINK
  3665 00000AD8 8B85[FEFF]              	mov ax, [word di - 2 + flagbits]
  3666                                   wlcalc word_minusext_flagnames, equ $ - 2
  3667                                  %elif _LINK_COMPAT
  3668                                  	mov ax, [word di - (flagnames + 2) + flagbits]
  3669                                  %else
  3670                                  	mov ax, [di - (flagnames + 2) + flagbits]
  3671                                  %endif
  3672 00000ADC BB[0000]                	mov bx, flagvaron
  3673 00000ADF 8506[0000]              	test ax, word [reg_efl]
  3674 00000AE3 7501                    	jnz .flagon
  3675 00000AE5 43                      	inc bx
  3676                                  .flagon:
  3677 00000AE6 B90105                  	mov cx, (5 << 8) | 1	; 5-byte name, 1-byte variable
  3678 00000AE9 FE46EB                  	inc byte [bp + ?fieldtype]
  3679                                  				; = 1 (RO)
  3680 00000AEC E9D300                  	jmp .return_success_var32_set_dx
  3681                                  
  3682                                  .reg16_j:
  3683 00000AEF E9CC00                  	jmp .reg16		; iff single match -->
  3684                                  
  3685                                  @@:
  3686 00000AF2 3D3030                  	cmp ax, "00"
  3687 00000AF5 743E                    	je .compoundwithzero
  3688                                  
  3689                                  		; Check for a second 16-bit register name
  3690                                  		;  (ie check for a compound register name)
  3691 00000AF7 E84800                  	call .reg16names_match	; (iff no match, --> .notreg16)
  3692                                  				; bx-> regs entry of second match
  3693 00000AFA 92                      	xchg dx, ax		; dx-> regs entry of first match
  3694 00000AFB B90404                  	mov cx, 4<<8|4
  3695                                  .return_success:		; cx, bx, dx, ?fieldtype set
  3696 00000AFE 31C0                    	xor ax, ax
  3697 00000B00 88C8                    	mov al, cl
  3698 00000B02 F7D8                    	neg ax
  3699 00000B04 05[6C0C]                	add ax, masks + 4	; 4 - size = offset into masks
  3700 00000B07 97                      	xchg di, ax		; di -> mask
  3701 00000B08 807EEB01                	cmp byte [bp + ?fieldtype], 1
  3702 00000B0C 7503                    	jne @F
  3703 00000B0E BF[6C0C]                	mov di, mask_0byte	; di -> mask
  3704                                  @@:
  3705                                  .return_success_di:
  3706 00000B11 31C0                    	xor ax, ax
  3707 00000B13 88E8                    	mov al, ch		; ax = length
  3708                                  
  3709 00000B15 F646FE01                	test byte [bp + ?bit0_is_return_name], 1
  3710 00000B19 7407                    	jz @F
  3711                                  
  3712 00000B1B 8B76FC                  	mov si, word [bp + ?return_name_pointer]
  3713 00000B1E 01C6                    	add si, ax
  3714 00000B20 8824                    	mov byte [si], ah	; zero-terminate
  3715                                  @@:
  3716                                  
  3717 00000B22 5E                      	pop si			; ?startpointer
  3718 00000B23 F646EA01                	testopt [bp + ?flags], 1
  3719 00000B27 7402                    	jz @F
  3720 00000B29 58                      	pop ax			; get length to add to start
  3721 00000B2A 50                      	push ax			; fill stack slot again
  3722                                  @@:
  3723 00000B2B 01C6                    	add si, ax		; -> behind name (should NC)
  3724 00000B2D 58                      	pop ax			; discard ?length_to_add
  3725 00000B2E F8                      	clc			; (NC)
  3726                                  .return_ax_frame_lodsb:
  3727 00000B2F 58                      	pop ax			; ah = ?type
  3728 00000B30 89EC5D                  	lleave code
  3729 00000B33 AC                      	lodsb
  3730                                  .retn:
  3731 00000B34 C3                      	retn
  3732                                  
  3733                                  
  3734                                  .compoundwithzero:
  3735 00000B35 BF[700C]                	mov di, mask_compoundwithzero
  3736                                  				; only allow writing upper word
  3737 00000B38 B90404                  	mov cx, 4 << 8 | 4	; 4-byte name, 4-byte variable
  3738                                  .return_compoundwithzero:
  3739 00000B3B 89DA                    	mov dx, bx		; -> word to use as upper word
  3740 00000B3D BB[720C]                	mov bx, mask_compoundwithzero + 2
  3741                                  				; -> (constant) word that is zero, as lower word
  3742                                  		; This depends on the contents of mask_compoundwithzero.
  3743 00000B40 EBCF                    	jmp .return_success_di
  3744                                  
  3745                                  
  3746                                  		; INP:	ax = capitalised candidate register name
  3747                                  		;	ch = 0
  3748                                  		;	dx, si, bx, etc set up for later checks
  3749                                  		; OUT:	Iff match,
  3750                                  		;	 bx-> associated regs entry (dword-aligned)
  3751                                  		;	 ax = INP:bx
  3752                                  		;	Else,
  3753                                  		;	 returns to .notreg16
  3754                                  		;	 bx left unchanged on 386 systems
  3755                                  		; CHG:	cl, di, bx, ax
  3756                                  		;
  3757                                  		; Note:	The 32-bit register name check depends on the
  3758                                  		;	 fact that the low two bits of bx are set to
  3759                                  		;	 zero on a match, which is true because regs
  3760                                  		;	 is dword-aligned.
  3761                                  		;	It also depends on bx being left unchanged on
  3762                                  		;	 a mismatch, which is the case unless the
  3763                                  		;	 non-386 additional FS,GS filtering occurs.
  3764                                  .reg16names_match:
  3765 00000B42 BF[0000]                	mov di, reg16names
  3766 00000B45 B110                    	mov cl, 16
  3767 00000B47 F2AF                    	repne scasw
  3768 00000B49 750C                    	jne short .notreg16_pop	; no match -->
  3769 00000B4B 01FF                    	add di, di
  3770 00000B4D 93                      	xchg ax, bx		; (returned for compound register name match)
  3771                                  %if _LINK
  3772 00000B4E 8D9D[FCFF]              	lea bx, [word di - 2*2 + regs]
  3773                                   wlcalc word_minusext_reg16names, equ $ - 2
  3774                                   wlcalc word_minusext_reg16names, equ $ - 2
  3775                                  %else
  3776                                  	lea bx, [di -2*(reg16names+DATASECTIONFIXUP+2) +regs]
  3777                                  %endif
  3778                                  				; -> regs entry
  3779 00000B52 C3                      _386	retn
  3780                                  				; cx = number of remaining reg16names
  3781 00000B53 D1E9                    _no386	shr cx, 1		; cx = number of remaining reg16names pairs
  3782                                  				;    = 1 iff exactly the IP,FL pair remaining
  3783                                  				;	  (ie matched one of FS,GS)
  3784 00000B55 E2DD                    _no386	loop .retn		; iff cx != 1, return the match -->
  3785                                  			; on non-386 systems, FS,GS matches fall through here
  3786                                  .notreg16_pop:
  3787 00000B57 58                      	pop ax			; (discard near return address)
  3788                                  .notreg16:
  3789                                  		; Check for a 32-bit register name
  3790 00000B58 F6C208                  _386	test dl, 1<<3
  3791 00000B5B 7419                    _386	jz short .notreg32
  3792                                  
  3793 00000B5D 8D76EC                  _386	lea si, [bp+?namebuffer]
  3794 00000B60 AC                      _386	lodsb
  3795 00000B61 D0EB                    _386	shr bl, 1		; CY iff second entry during same call
  3796                                  				;  (in that case, al contains 'E')
  3797 00000B63 1C45                    _386	sbb al, 'E'		; possibly an 'E' register ? (on first entry)
  3798 00000B65 AD                      _386	lodsw
  3799 00000B66 750E                    _386	jne short .notreg32	; no --> (or after second entry)
  3800 00000B68 43                      _386	inc bx			; prepare flag for second entry
  3801                                  				;  (this requires regs to be dword-aligned!)
  3802 00000B69 80FC53                  _386	cmp ah, 'S'		; candidate segment register ?
  3803 00000B6C 7408                    _386	je short .notreg32	; yes, skip check (disallow match) -->
  3804                                  
  3805 00000B6E E8D1FF                  _386	call .reg16names_match	; (iff no match, --> .notreg16 (second entry))
  3806                                  				; bx-> regs entry of match
  3807 00000B71 B90403                  _386	mov cx, 3<<8|4
  3808 00000B74 EB4C                    _386	jmp short .return_success_var32_set_dx
  3809                                  
  3810                                  .notreg32:
  3811                                  		; Check for an 8-bit register name
  3812 00000B76 F6C214                  	test dl, 1 << 2 | 1 << 4
  3813 00000B79 744D                    	jz .notreg8
  3814                                  
  3815 00000B7B 8D76EC                  	lea si, [bp+?namebuffer]
  3816 00000B7E AD                      	lodsw
  3817 00000B7F BF[0000]                	mov di, reg8names
  3818 00000B82 B108                    	mov cl, 8
  3819 00000B84 F2AF                    	repne scasw
  3820 00000B86 7540                    	jne short .notreg8
  3821                                  				; cx = cl = number of remaining reg8names
  3822 00000B88 80E101                  	and cl, 1		; cx = cl = 1 iff an xL register, else 0
  3823                                  %if _LINK
  3824 00000B8B 8D9D[FDFF]              	lea bx, [word di + regs - 2 - 1]
  3825                                   wlcalc word_minusext_reg8names, equ $ - 2
  3826                                  %else
  3827                                  	lea bx, [di-reg8names-2+regs-1]
  3828                                  %endif
  3829                                  				; bx-> reg_eax-1 if AL, reg_eax+1 if AH, etc
  3830 00000B8F 01CB                    	add bx, cx		; bx-> reg_eax   if AL, reg_eax+1 if AH, etc
  3831 00000B91 B101                    	mov cl, 1
  3832                                  
  3833 00000B93 F6C204                  	test dl, 1 << 2
  3834 00000B96 7528                    	jnz .got2bytename
  3835                                  
  3836 00000B98 AD                      	lodsw
  3837 00000B99 3D3030                  	cmp ax, "00"
  3838 00000B9C 7417                    	je .compoundreg8withzero
  3839                                  
  3840 00000B9E BF[0000]                	mov di, reg16names
  3841 00000BA1 B110                    	mov cl, 16
  3842 00000BA3 F2AF                    	repne scasw
  3843 00000BA5 7521                    	jne short .notreg8	; no match -->
  3844 00000BA7 01FF                    	add di, di
  3845 00000BA9 87D3                    	xchg dx, bx
  3846                                  %if _LINK
  3847 00000BAB 8D9D[FCFF]              	lea bx, [word di - 2*2 + regs]
  3848                                   wlcalc word_minusext_reg16names, equ $ - 2
  3849                                   wlcalc word_minusext_reg16names, equ $ - 2
  3850                                  %else
  3851                                  	lea bx, [di -2*(reg16names+DATASECTIONFIXUP+2) +regs]
  3852                                  %endif
  3853                                  				; -> regs entry
  3854                                  				; bx-> regs entry of second match
  3855                                  				; dx-> regs entry of first match
  3856 00000BAF B90304                  	mov cx, 4 << 8 | 3	; 4-byte name, 3-byte variable
  3857 00000BB2 E949FF                  	jmp .return_success	; cx, bx, dx, ?fieldtype set
  3858                                  
  3859                                  .compoundreg8withzero:
  3860 00000BB5 BF[740C]                	mov di, mask_compoundreg8withzero
  3861                                  				; only allow writing low byte of upper word
  3862 00000BB8 B90304                  	mov cx, 4 << 8 | 3	; 4-byte name, 3-byte variable
  3863 00000BBB E97DFF                  	jmp .return_compoundwithzero
  3864                                  
  3865                                  .reg16:
  3866 00000BBE B102                    	mov cl, 2
  3867                                  .got2bytename:
  3868                                  .got2bytename_var32_set_dx:
  3869 00000BC0 B502                    	mov ch, 2
  3870                                  .return_success_var32_set_dx:
  3871 00000BC2 8D5702                  	lea dx, [bx+2]		; (irrelevant to 8-/16-bit register return)
  3872                                  %define .return_success_j .return_success_j1
  3873                                  %[.return_success_j]:
  3874 00000BC5 E936FF                  	jmp .return_success
  3875                                  
  3876                                  .notreg8:
  3877                                  
  3878 00000BC8 BF[4C08]                	mov di, isvariable_morebyte_nameheaders
  3879                                  
  3880                                  .loop:
  3881 00000BCB 8366EA00                	and word [bp + ?fieldtype_high_flags_low], 0
  3882                                  					; clear in case earlier iteration set it
  3883                                  
  3884 00000BCF 8B46EC                  	mov ax, word [bp + ?namebuffer]
  3885 00000BD2 B9[B009]                	mov cx, isvariable_morebyte_nameheaders.end
  3886 00000BD5 39CF                    	cmp di, cx
  3887 00000BD7 730A                    	jae @F
  3888 00000BD9 29F9                    	sub cx, di
  3889 00000BDB D1E9                    	shr cx, 1			; = how many headers remaining
  3890 00000BDD F2AF                    	repne scasw
  3891 00000BDF 7421                    	je .check_morebyte
  3892                                  %if IVS_HAVE_ONEBYTE
  3893 00000BE1 EB0C                    	jmp .next_no_pop
  3894                                  
  3895                                  @@:
  3896                                   %if IVS_SINGLE_ONEBYTE
  3897 00000BE3 41                      	inc cx
  3898 00000BE4 39CF                    	cmp di, cx			; iteration after one byte var check ?
  3899 00000BE6 7309                    	jae @F				; yes, end -->
  3900 00000BE8 47                      	inc di				; remember we did the one byte check
  3901 00000BE9 3C56                    	cmp al, IVS_SINGLE_ONEBYTE_NAME
  3902 00000BEB 740A                    	je .check_onebyte
  3903                                   %else
  3904                                  	mov cx, isvariable_onebyte_names.end
  3905                                  	sub cx, di			; = how many names remaining
  3906                                  	jbe @F				; if none -->
  3907                                  	repne scasb
  3908                                  	je .check_onebyte
  3909                                   %endif
  3910                                  %endif
  3911 00000BED A8                      	db __TEST_IMM8			; (skip pop)
  3912                                  .next:
  3913 00000BEE 5F                      	pop di
  3914                                  .next_no_pop:
  3915 00000BEF EBDA                    	jmp .loop
  3916                                  
  3917                                  @@:
  3918                                  .end:
  3919                                  .return_failure:
  3920 00000BF1 5E                      	pop si			; ?startpointer
  3921 00000BF2 58                      	pop ax			; ?length_to_add
  3922 00000BF3 F9                      	stc
  3923 00000BF4 E938FF                  	jmp .return_ax_frame_lodsb
  3924                                  
  3925                                  
  3926                                  %if IVS_HAVE_ONEBYTE
  3927                                  .check_onebyte:
  3928 00000BF7 57                      	push di
  3929                                   %if IVS_SINGLE_ONEBYTE
  3930 00000BF8 BB[3A01]                	mov bx, isvariable_struc_onebyte_list
  3931                                   %else
  3932                                  	sub di, isvariable_onebyte_names + 1
  3933                                  					; = index
  3934                                  %if ISVARIABLESTRUC_size == 10
  3935                                  	add di, di			; = index * 2
  3936                                  	mov bx, di			; = index * 2
  3937                                  	add di, di			; = index * 4
  3938                                  	add di, di			; = index * 8
  3939                                  	add di, bx			; = index * 10
  3940                                  %else
  3941                                   %error Unexpected structure size
  3942                                  %endif
  3943                                  	lea bx, [di + isvariable_struc_onebyte_list]
  3944                                   %endif
  3945 00000BFB 8D76ED                  	lea si, [bp + ?namebuffer + 1]	; -> buffered string (allcaps)
  3946 00000BFE 31C9                    	xor cx, cx			; = 0, gets incremented next
  3947 00000C00 EB25                    	jmp @F
  3948                                  %endif
  3949                                  
  3950                                  .check_morebyte:
  3951 00000C02 57                      	push di
  3952 00000C03 81EF[4E08]              	sub di, isvariable_morebyte_nameheaders + 2
  3953                                  					; = index * 2
  3954                                  %if ISVARIABLESTRUC_size == 10
  3955 00000C07 89FB                    	mov bx, di			; = index * 2
  3956 00000C09 01FF                    	add di, di			; = index * 4
  3957 00000C0B 01FF                    	add di, di			; = index * 8
  3958 00000C0D 01DF                    	add di, bx			; = index * 10
  3959                                  %else
  3960                                   %error Unexpected structure size
  3961                                  %endif
  3962 00000C0F 8D9D[4401]              	lea bx, [di + isvariable_struc_morebyte_list]
  3963 00000C13 8B4F02                  	mov cx, word [bx + ivFlags]
  3964 00000C16 83E10F                  	and cx, ivfNameLengthMask	; cx = length
  3965 00000C19 8B3F                    	mov di, word [bx + ivName]	; -> name
  3966 00000C1B 8D76EE                  	lea si, [bp + ?namebuffer + 2]	; -> buffered string (allcaps)
  3967 00000C1E 38C0                    	cmp al, al		; ZR (in case remaining length is zero)
  3968 00000C20 51                      	push cx
  3969 00000C21 F3A6                    	repe cmpsb		; compare
  3970 00000C23 59                      	pop cx
  3971 00000C24 75C8                    	jne .next		; if not same -->
  3972 00000C26 41                      	inc cx			; increment twice
  3973                                  @@:
  3974 00000C27 41                      	inc cx			; increment once
  3975 00000C28 AC                      	lodsb			; get next byte in buffer
  3976 00000C29 807F0800                	cmp byte [bx + ivArrayLast], 0
  3977 00000C2D 7503E9DD00              	je .notarray
  3978                                  
  3979                                  .array:
  3980 00000C32 3C28                    	cmp al, '('
  3981 00000C34 7560                    	jne .array_not_index_expression	; not index expression -->
  3982                                  
  3983                                  .array_index_expression:
  3984 00000C36 8B76E6                  	mov si, word [bp + ?startpointer]
  3985 00000C39 01CE                    	add si, cx		; -> at opening parens
  3986 00000C3B 46                      	inc si			; -> behind opening parens
  3987 00000C3C AC                      	lodsb
  3988 00000C3D 52                      	push dx
  3989 00000C3E 53                      	push bx
  3990 00000C3F E80903                  	nearcall getexpression
  3991 00000C42 50                      	push ax
  3992 00000C43 80E43F                  	and ah, 3Fh
  3993 00000C46 80FC08                  	cmp ah, 8		; from checksignificantbits
  3994 00000C49 58                      	pop ax
  3995 00000C4A B600                    	mov dh, 0
  3996 00000C4C 89D7                    	mov di, dx		; di = index
  3997 00000C4E 5B                      	pop bx
  3998 00000C4F 5A                      	pop dx
  3999 00000C50 779C                    	ja short .next		; more than 8 significant bits -->
  4000 00000C52 E8(0000)EB02[0000]      	nearcall skipwh0
  4001 00000C59 3C29                    	cmp al, ')'		; insure closing parens
  4002 00000C5B 7547                    	jne short .error_j3
  4003                                  
  4004 00000C5D 56                      	push si
  4005 00000C5E 2B76E6                  	sub si, word [bp + ?startpointer]
  4006                                  				; = how much to skip
  4007 00000C61 8976E8                  	mov word [bp + ?length_to_add], si
  4008 00000C64 5E                      	pop si
  4009 00000C65 804EEA01                	setopt [bp + ?flags], 1
  4010                                  
  4011 00000C69 F646FE01                	test byte [bp + ?bit0_is_return_name], 1
  4012 00000C6D 741D                    	jz .array_no_return_name
  4013                                  
  4014 00000C6F 97                      	xchg ax, di
  4015 00000C70 8B7EFC                  	mov di, word [bp + ?return_name_pointer]
  4016 00000C73 01CF                    	add di, cx		; -> behind name
  4017 00000C75 807F080F                	cmp byte [bx + ivArrayLast], 0Fh
  4018 00000C79 7709                    	ja @F			; if >= 10h is a valid index -->
  4019 00000C7B E8(0000)EB02[0000]      	nearcall hexnyb		; expand to single digit
  4020 00000C82 EB07                    	jmp @FF
  4021                                  @@:
  4022 00000C84 E8(0000)EB02[0000]      	nearcall hexbyte	; expand to two digits
  4023                                  @@:
  4024 00000C8B 97                      	xchg ax, di		; restore di = index
  4025                                  
  4026                                  .array_no_return_name:
  4027 00000C8C 41                      	inc cx			; make space for one digit
  4028 00000C8D 807F080F                	cmp byte [bx + ivArrayLast], 0Fh
  4029 00000C91 7601                    	jna @F			; if maximum index <= 0Fh -->
  4030 00000C93 41                      	inc cx			; make space for another digit
  4031                                  @@:
  4032 00000C94 EB66                    	jmp .array_index_expression_common
  4033                                  
  4034                                  .array_not_index_expression:
  4035 00000C96 E896F7                  	nearcall isseparator?	; name ends ?
  4036 00000C99 750C                    	jne @F			; no -->
  4037 00000C9B F6470302                	testopt [bx + ivFlags], ivfArrayOptional
  4038                                  				; is the index optional ?
  4039 00000C9F 7573                    	jnz .arrayfirst		; yes, handle as if first -->
  4040                                  .next_j1:
  4041 00000CA1 E94AFF                  	jmp .next		; no, mismatch -->
  4042                                  
  4043                                  .error_j3:
  4044 00000CA4 E959F3                  	jmp error_expr
  4045                                  
  4046                                  @@:
  4047 00000CA7 E8AF08                  	nearcall getnyb
  4048 00000CAA 72F5                    	jc .next_j1
  4049 00000CAC 98                      	cbw			; ax = first nybble of index
  4050 00000CAD 97                      	xchg di, ax		; di = first nybble of index
  4051 00000CAE AC                      	lodsb
  4052 00000CAF F6470304                	 testopt [bx + ivFlags], ivfSeparatorSpecial
  4053 00000CB3 740D                    	 jz @F
  4054 00000CB5 807F080F                	cmp byte [bx + ivArrayLast], 0Fh
  4055                                  				; highest > 0Fh ?
  4056 00000CB9 7635                    	jna .gotseparatorspecial; no -->
  4057 00000CBB E89B08                  	nearcall getnyb
  4058 00000CBE 7230                    	jc .gotseparatorspecial	; not hexit, treat as separator -->
  4059 00000CC0 EB10                    	jmp .have_second_digit	; have al == 0..0Fh
  4060                                  
  4061                                  @@:
  4062 00000CC2 E86AF7                  	nearcall isseparator?	; single digit ?
  4063 00000CC5 7424                    	je @F			; yes -->
  4064 00000CC7 807F080F                	cmp byte [bx + ivArrayLast], 0Fh
  4065                                  				; highest > 0Fh ?
  4066 00000CCB 76D4                    	jna .next_j1		; no -->
  4067                                  .get_second_digit:
  4068 00000CCD E88908                  	nearcall getnyb
  4069 00000CD0 72CF                    	jc .next_j1
  4070                                  .have_second_digit:
  4071 00000CD2 98                      	cbw			; ax = second nybble of index
  4072 00000CD3 01FF                    	add di, di
  4073 00000CD5 01FF                    	add di, di
  4074 00000CD7 01FF                    	add di, di
  4075 00000CD9 01FF                    	add di, di		; di = first digit times 16
  4076 00000CDB 01C7                    	add di, ax		; di = full index
  4077 00000CDD AC                      	lodsb
  4078 00000CDE F6470304                	 testopt [bx + ivFlags], ivfSeparatorSpecial
  4079 00000CE2 7507                    	 jnz @F
  4080 00000CE4 E848F7                  	nearcall isseparator?
  4081 00000CE7 75B8                    	jne .next_j1
  4082 00000CE9 EB05                    	jmp .gotseparatorspecial
  4083                                  @@:		; make sure no hexit follows
  4084 00000CEB E86B08                  	nearcall getnyb
  4085 00000CEE 73B1                    	jnc .next_j1
  4086                                  .gotseparatorspecial:
  4087                                  
  4088 00000CF0 F7DE                    	neg si			; minus -> after separator
  4089 00000CF2 8D4AED                  	lea cx, [bp + ?namebuffer + 1 + si]
  4090                                  		; -> buffered string plus 1 minus -> after separator
  4091                                  		; -> buffered string plus 1 minus (-> at separator plus 1)
  4092                                  		; -> buffered string minus -> at separator
  4093 00000CF5 F7D9                    	neg cx			; -> at separator minus -> buffered string
  4094 00000CF7 8B76E6                  	mov si, word [bp + ?startpointer]
  4095 00000CFA 01CE                    	add si, cx
  4096                                  
  4097                                  .array_index_expression_common:
  4098                                  		; si -> behind index
  4099 00000CFC 89F8                    	mov ax, di
  4100                                  	; test ah, ah
  4101                                  	; jnz short .error_j1	; (not possible)
  4102 00000CFE 3A4708                  	cmp al, byte [bx + ivArrayLast]
  4103                                  				; index > last ?
  4104 00000D01 779E                    	ja short .next_j1	; then error -->
  4105                                  
  4106 00000D03 F6470301                	testopt [bx + ivFlags], ivfArrayOneBased
  4107 00000D07 7403                    	jz @F			; got index
  4108 00000D09 48                      	dec ax			; decrement index to get 0-based
  4109 00000D0A 7895                    	js short .next_j1	; if it was 0, invalid -->
  4110                                  @@:
  4111 00000D0C 96                      	xchg ax, si		; si = index
  4112 00000D0D EB07                    	jmp .arraycommon	; continue
  4113                                  
  4114                                  
  4115                                  .notarray:
  4116 00000D0F E81DF7                  	nearcall isseparator?	; name ends ?
  4117 00000D12 758D                    	jne short .next_j1	; no, mismatch -->
  4118                                  
  4119                                  .arrayfirst:
  4120 00000D14 31F6                    	xor si, si		; si = array index (0 here)
  4121                                  
  4122                                  .arraycommon:
  4123 00000D16 88CD                    	mov ch, cl		; ch = name length
  4124 00000D18 8B4702                  	mov ax, word [bx + ivFlags]
  4125 00000D1B 83E030                  	and ax, ivfVarLengthMask; ax = shifted encoded var length
  4126 00000D1E B104                    	mov cl, ivfVarLengthShift
  4127 00000D20 D3E8                    	shr ax, cl		; ax = encoded var length
  4128 00000D22 40                      	inc ax			; decode var length
  4129 00000D23 88C1                    	mov cl, al		; cl = var length
  4130                                  
  4131 00000D25 96                      	xchg ax, si		; ax = array index
  4132                                  
  4133 00000D26 F6470280                	testopt [bx + ivFlags], ivfReadOnly
  4134 00000D2A 7403                    	jz @F
  4135 00000D2C FE46EB                  	inc byte [bp + ?fieldtype]
  4136                                  				; = 1 (RO)
  4137                                  @@:
  4138 00000D2F 31FF                    	xor di, di		; (NC)
  4139 00000D31 8B7706                  	mov si, word [bx + ivSetup]
  4140 00000D34 FFD6                    	call si			; INP:	ax = array index (0-based)
  4141                                  				;	di = 0
  4142                                  				;	cl = default size of variable (1..4)
  4143                                  				;	ch = length of variable name
  4144                                  				;	bx -> ISVARIABLESTRUC structure
  4145                                  				; CHG:	ax, bx, cx, dx, si, di
  4146                                  				; OUT:	NC if valid,
  4147                                  				;	 bx -> var, di = 0 or di -> mask
  4148                                  				;	 cl = size of variable (1..4)
  4149                                  				;	 ch = length of variable name
  4150 00000D36 7303E9B3FE              	jc .next
  4151 00000D3B 5A                      	pop dx			; (discard pointer into names/headers)
  4152 00000D3C 8D5702                  	lea dx, [bx+2]		; (irrelevant to 8-/16-bit register return)
  4153 00000D3F 85FF                    	test di, di
  4154 00000D41 7503E9B8FD              	jz .return_success
  4155 00000D46 E9C8FD                  	jmp .return_success_di
  4156                                  
  4157                                  
  4158                                  default_variable_setup: section_of_function
  4159 00000D49 8A5709                  	mov dl, byte [bx + ivArrayBetween]
  4160 00000D4C B600                    	mov dh, 0		; dx = array between offset
  4161 00000D4E 00CA                    	add dl, cl
  4162 00000D50 10F6                    	adc dh, dh		; dx = array item size
  4163 00000D52 F7E2                    	mul dx			; dx:ax = ax times dx
  4164 00000D54 85D2                    	test dx, dx
  4165 00000D56 7507                    	jnz short .error_j2
  4166 00000D58 034704                  	add ax, word [bx + ivAddress]
  4167                                  				; ax -> variable
  4168 00000D5B 7202                    	jc short .error_j2
  4169                                  				; NC
  4170 00000D5D 93                      	xchg ax, bx		; bx -> variable
  4171 00000D5E C3                      	retn
  4172                                  
  4173                                  .error_j2:
  4174 00000D5F E99EF2                  	jmp error_expr
  4175                                  
  4176                                  
  4177                                  %if _MMXSUPP
  4178                                  var_mm_setup: section_of_function
  4179 00000D62 803E[0000]01            	cmp byte [has_mmx], 1	; MMX supported ?
  4180 00000D67 7301                    	jae @F			; yes -->
  4181 00000D69 C3                      	retn			; (CY)
  4182                                  
  4183                                  @@:
  4184                                  [cpu 586]
  4185 00000D6A 50                      	push ax
  4186 00000D6B 8D76EF                  	lea si, [bp + ?namebuffer + 3]
  4187                                  				; -> may be type letter, if not index expression
  4188 00000D6E F646EA01                	testopt [bp + ?flags], 1
  4189 00000D72 7409                    	jz @F
  4190 00000D74 8B76E6                  	mov si, word [bp + ?startpointer]
  4191 00000D77 0376E8                  	add si, word [bp + ?length_to_add]
  4192 00000D7A FF46E8                  	inc word [bp + ?length_to_add]
  4193                                  
  4194                                  @@:
  4195 00000D7D AC                      	lodsb			; load what may be type letter
  4196 00000D7E E8(0000)EB02[0000]      	nearcall capitalise
  4197                                  
  4198 00000D85 3C5A                    	cmp al, 'Z'
  4199 00000D87 7418                    	je @F			; 0 = ZX low -->
  4200 00000D89 B310                    	mov bl, 2<<3		; = 10h = low
  4201 00000D8B 3C4C                    	cmp al, 'L'
  4202 00000D8D 7414                    	je @FF
  4203 00000D8F B308                    	mov bl, 1<<3		; = 8h = SX low
  4204 00000D91 3C53                    	cmp al, 'S'
  4205 00000D93 740E                    	je @FF
  4206 00000D95 B318                    	mov bl, 3<<3		; = 18h = high
  4207 00000D97 3C48                    	cmp al, 'H'
  4208 00000D99 7408                    	je @FF
  4209 00000D9B FF4EE8                  	dec word [bp + ?length_to_add]
  4210 00000D9E 4E                      	dec si			; -> back at the last text
  4211                                  				;  (subsequent code will check for separator)
  4212 00000D9F B000                    	mov al, 0
  4213                                  @@:
  4214 00000DA1 B300                    	mov bl, 0		; 0 = ZX low
  4215                                  @@:				; is valid letter
  4216 00000DA3 50                      	push ax
  4217 00000DA4 AC                      	lodsb			; = candidate separator
  4218 00000DA5 E887F6                  	nearcall isseparator?	; is it ?
  4219 00000DA8 58                      	pop ax
  4220 00000DA9 755E                    	jne .ret_CY_pop		; no -->
  4221                                  
  4222 00000DAB F646FE01                	test byte [bp + ?bit0_is_return_name], 1
  4223 00000DAF 7406                    	jz .no_return_name
  4224                                  
  4225 00000DB1 8B76FC                  	mov si, word [bp + ?return_name_pointer]
  4226 00000DB4 884403                  	mov byte [si + 3], al	; store the additional letter (or 0)
  4227                                  				; pointer + 3 ("MM" then hexit)
  4228                                  
  4229                                  .no_return_name:
  4230 00000DB7 84C0                    	test al, al
  4231 00000DB9 58                      	pop ax
  4232 00000DBA 7402                    	jz @F
  4233 00000DBC FEC5                    	inc ch			; increment name length
  4234                                  @@:
  4235 00000DBE 93                      	xchg ax, bx
  4236                                  
  4237                                  		; INP:	bx = register number 0..7
  4238                                  		;	al = 0 for ZX low, 8 for SX low, 10h for low, 18h for high
  4239 00000DBF 08D8                    	or al, bl
  4240 00000DC1 40                      	inc ax
  4241 00000DC2 40                      	inc ax
  4242 00000DC3 8846EB                  	mov byte [bp + ?fieldtype], al
  4243                                  
  4244                                   %if _PM
  4245 00000DC6 83EC08                  	 sub sp, 8
  4246 00000DC9 E86008                  	call save_scratchsel
  4247                                   %if _EXPRDUALCODE && _DUALCODE
  4248 00000DCC 8B16[0000]              	mov dx, word [code2_seg]
  4249                                   %else
  4250                                  	mov dx, word [code_seg]
  4251                                   %endif
  4252 00000DD0 E8(0000)EB02[0000]      	nearcall setes2dx	; es => lDEBUG_CODE/2 (writable)
  4253                                  %else
  4254                                   %if _EXPRDUALCODE && _DUALCODE
  4255                                  	mov es, word [code2_seg]; es => lDEBUG_CODE2
  4256                                   %else
  4257                                  	mov es, word [code_seg]	; es => lDEBUG_CODE
  4258                                   %endif
  4259                                  %endif
  4260 00000DD7 C0E303                  	shl bl, 3		; shift into reg field
  4261 00000DDA 80CB07                  	or bl, 07h		; code to get our ModR/M byte (r/m = [bx])
  4262 00000DDD 26881E[F30D]            	mov byte [es:.getmmxlow_modrm], bl
  4263                                  				; SMC in section lDEBUG_CODE or lDEBUG_CODE2
  4264 00000DE2 26881E[000E]            	mov byte [es:.getmmxhigh_modrm], bl
  4265                                  				; SMC in section lDEBUG_CODE or lDEBUG_CODE2
  4266 00000DE7 EB00                    	jmp @F			; try to invalidate prefetch
  4267                                  @@:
  4268                                  
  4269 00000DE9 16                      	push ss
  4270 00000DEA 07                      	pop es
  4271                                  
  4272                                   %if _PM
  4273 00000DEB E86308                  	call restore_scratchsel
  4274                                   %endif
  4275                                  
  4276 00000DEE BB[0000]                	mov bx, mmxbuff
  4277                                  .getmmxlow:
  4278                                   .getmmxlow_modrm: equ $+2	; (opcode adjusted for the right MMX reg)
  4279 00000DF1 0F7E07                  	movd dword [bx], mm0	; first, initialise with low dword
  4280                                  
  4281 00000DF4 3C18                    	cmp al, 18h		; want to write high dword ?
  4282 00000DF6 720F                    	jb .mmxcommon		; no -->
  4283                                  
  4284                                  .getmmxhigh:
  4285 00000DF8 83EC08                  	sub sp, byte 8
  4286 00000DFB 89E0                    	mov ax, sp		; (ss = ds)
  4287 00000DFD 93                      	xchg bx, ax		; bx -> qword on stack, ax -> mmxbuff
  4288                                   .getmmxhigh_modrm: equ $+2	; (opcode adjusted for the right MMX reg)
  4289 00000DFE 0F7F07                  	movq qword [bx], mm0
  4290 00000E01 93                      	xchg bx, ax		; restore bx -> mmxbuff
  4291 00000E02 5E                      	pop si
  4292 00000E03 5E                      	pop si			; discard low dword
  4293 00000E04 668F07                  	pop dword [bx]		; save high dword here
  4294                                  
  4295                                  .mmxcommon:
  4296 00000E07 F8                      	clc
  4297 00000E08 C3                      	retn
  4298                                  __CPU__
  4299                                  
  4300                                  
  4301                                  .ret_CY_pop:
  4302 00000E09 58                      	pop ax
  4303                                  .ret_CY:
  4304 00000E0A F9                      	stc
  4305 00000E0B C3                      	retn
  4306                                  %endif
  4307                                  
  4308                                  
  4309                                  var_ri_setup: section_of_function
  4310 00000E0C 8D76EF                  	lea si, [bp + ?namebuffer + 3]
  4311 00000E0F F646EA01                	testopt [bp + ?flags], 1
  4312 00000E13 740F                    	jz @F
  4313 00000E15 8B76E6                  	mov si, word [bp + ?startpointer]
  4314 00000E18 0376E8                  	add si, word [bp + ?length_to_add]
  4315 00000E1B FF46E8                  	inc word [bp + ?length_to_add]
  4316 00000E1E 50                      	push ax
  4317 00000E1F B301                    	mov bl, 1		; set up 1 additional digit
  4318 00000E21 AC                      	lodsb			; load what must be type letter
  4319 00000E22 EB0A                    	jmp .expr
  4320                                  
  4321                                  @@:
  4322 00000E24 50                      	push ax
  4323 00000E25 B3FF                    	mov bl, -1
  4324                                  @@:
  4325 00000E27 AC                      	lodsb			; al = candidate type letter, or hexit
  4326 00000E28 43                      	inc bx			; count number of hexits
  4327 00000E29 E82D07                  	nearcall getnyb
  4328 00000E2C 73F9                    	jnc @B			; if was a hexit, loop -->
  4329                                  .expr:		; al = type letter
  4330 00000E2E E8(0000)EB02[0000]      	nearcall capitalise
  4331 00000E35 88C7                    	mov bh, al		; bh = letter
  4332 00000E37 3C4C                    	cmp al, 'L'		; valid one ?
  4333 00000E39 740C                    	je @F
  4334 00000E3B 3C4F                    	cmp al, 'O'
  4335 00000E3D 7408                    	je @F
  4336 00000E3F 3C53                    	cmp al, 'S'
  4337 00000E41 7404                    	je @F
  4338 00000E43 3C50                    	cmp al, 'P'
  4339 00000E45 7575                    	jne .ret_CY_pop		; no -->
  4340                                  @@:				; is valid letter
  4341 00000E47 AC                      	lodsb			; = candidate separator
  4342 00000E48 E8E4F5                  	nearcall isseparator?	; is it ?
  4343 00000E4B 756F                    	jne .ret_CY_pop		; no -->
  4344 00000E4D 58                      	pop ax
  4345                                  
  4346 00000E4E F646FE01                	test byte [bp + ?bit0_is_return_name], 1
  4347 00000E52 740E                    	jz .interrupt_no_return_name
  4348                                  
  4349 00000E54 89DF                    	mov di, bx
  4350 00000E56 81E7FF00                	and di, 255		; get number of additional hexits
  4351 00000E5A 037EFC                  	add di, word [bp + ?return_name_pointer]
  4352 00000E5D 83C703                  	add di, 3		; amount hexits + 3 + pointer
  4353 00000E60 883D                    	mov byte [di], bh	; store the additional letter
  4354                                  
  4355                                  .interrupt_no_return_name:
  4356 00000E62 FEC5                    	inc ch			; increment name length
  4357 00000E64 93                      	xchg ax, bx
  4358                                  
  4359                                  		; INP:	bx = interrupt number 0..255
  4360                                  		;	ah = 'S' for segment, 'O' for offset, 'L' for linear
  4361                                   %if _PM
  4362 00000E65 83EC08                  	 sub sp, 8
  4363 00000E68 E8C107                  	call save_scratchsel
  4364                                   %endif
  4365 00000E6B 31F6                    	xor si, si
  4366                                  %if _PM
  4367 00000E6D 53                      	push bx
  4368 00000E6E E8(0000)EB02[0000]      	nearcall setds2si	; ds => IVT
  4369 00000E75 5B                      	pop bx
  4370                                  %else
  4371                                  	mov ds, si		; ds => IVT
  4372                                  %endif
  4373 00000E76 80FC53                  	cmp ah, 'S'
  4374 00000E79 7502                    	jne @F
  4375 00000E7B 46                      	inc si
  4376 00000E7C 46                      	inc si			; si = 2 (displacement to get segment)
  4377                                  @@:
  4378 00000E7D 01DB                    	add bx, bx
  4379 00000E7F 01DB                    	add bx, bx		; ds:bx -> IVT entry
  4380 00000E81 FF7002                  	push word [bx + si + 2]
  4381 00000E84 FF30                    	push word [bx + si]	; get segment:offset or trash:segment
  4382 00000E86 16                      	 push ss
  4383 00000E87 1F                      	 pop ds
  4384 00000E88 BB[3808]                	mov bx, interrupt_var
  4385 00000E8B 8F07                    	pop word [bx]
  4386 00000E8D 8F4702                  	pop word [bx + 2]
  4387                                  				; store in variable
  4388                                   %if _PM
  4389 00000E90 E8BE07                  	call restore_scratchsel
  4390                                   %endif
  4391 00000E93 80FC50                  	cmp ah, 'P'		; for pointer type ?
  4392 00000E96 741F                    	je .var_size_4		; yes -->
  4393 00000E98 80FC4C                  	cmp ah, 'L'
  4394 00000E9B 751C                    	jne @FF
  4395 00000E9D 51                      	 push cx
  4396 00000E9E 31C0                    	xor ax, ax
  4397 00000EA0 874702                  	xchg ax, word [bx + 2]	; clear high word, get segment
  4398 00000EA3 31D2                    	xor dx, dx		; dx:ax = segment
  4399 00000EA5 B90400                  	mov cx, 4
  4400                                  @@:
  4401 00000EA8 D1E0                    	shl ax, 1
  4402 00000EAA D1D2                    	rcl dx, 1
  4403 00000EAC E2FA                    	loop @B			; shift up 4 bits
  4404 00000EAE 0107                    	add word [bx], ax
  4405 00000EB0 115702                  	adc word [bx + 2], dx	; add to dword
  4406 00000EB3 59                      	 pop cx
  4407 00000EB4 B103                    	mov cl, 3		; 3byte variable (21 bits needed)
  4408 00000EB6 A9                      	db __TEST_IMM16		; (skip mov)
  4409                                  .var_size_4:
  4410 00000EB7 B104                    	mov cl, 4		; dword variable
  4411                                  @@:
  4412 00000EB9 31FF                    	xor di, di		; (NC)
  4413 00000EBB C3                      	retn
  4414                                  
  4415                                  .ret_CY_pop:
  4416 00000EBC 58                      	pop ax
  4417                                  .ret_CY:
  4418 00000EBD F9                      	stc
  4419 00000EBE C3                      	retn
  4420                                  
  4421                                  
  4422                                  
  4423                                  %if _INPUT_FILE_BOOT || _INPUT_FILE_HANDLES
  4424                                  var_ysf_setup: section_of_function
  4425 00000EBF 93                      	xchg ax, bx			; bx = index
  4426 00000EC0 8A46ED                  	mov al, byte [bp + ?namebuffer + 1]
  4427 00000EC3 3C53                    	cmp al, 'S'
  4428 00000EC5 750B                    	jne @F
  4429                                  %if _INPUT_FILE_BOOT
  4430 00000EC7 F606[0300]02            	testopt [internalflags2], dif2_input_file_boot
  4431 00000ECC B042                    	mov al, 'B'
  4432 00000ECE 7502                    	jnz @F
  4433                                  %endif
  4434 00000ED0 B048                    	mov al, 'H'
  4435                                  @@:
  4436 00000ED2 3C42                    	cmp al, 'B'
  4437 00000ED4 7509                    	jne @F
  4438                                  %if _INPUT_FILE_BOOT
  4439 00000ED6 F606[0300]02            	testopt [internalflags2], dif2_input_file_boot
  4440 00000EDB 750D                    	jnz @FF
  4441                                  %endif
  4442                                  .notysf:
  4443 00000EDD F9                      	stc
  4444 00000EDE C3                      	retn
  4445                                  @@:
  4446                                  %if _INPUT_FILE_HANDLES
  4447 00000EDF 3C48                    	cmp al, 'H'
  4448 00000EE1 75FA                    	jne short .notysf
  4449 00000EE3 F606[0200]10            	testopt [internalflags2], dif2_input_file
  4450 00000EE8 74F3                    	jz .notysf
  4451                                  %else
  4452                                  	jmp .notysf
  4453                                  %endif
  4454                                  @@:
  4455                                  				; bx = index
  4456                                  %if _INPUT_FILE_HANDLES
  4457 00000EEA BF[0000]                	mov di, input_file_handles.active
  4458                                  				; -> active index for YHF
  4459                                  %endif
  4460                                  %if _INPUT_FILE_BOOT
  4461                                   %if _INPUT_FILE_HANDLES
  4462 00000EED 3C42                    	cmp al, 'B'
  4463 00000EEF 7503                    	jne @F
  4464                                   %endif
  4465 00000EF1 BF[0000]                	mov di, load_input_file.active
  4466                                  				; -> active index for YBF
  4467                                  @@:
  4468                                  %endif
  4469 00000EF4 F7DB                    	neg bx			; -1 .. 0
  4470 00000EF6 7406                    	jz @F			; if 0, always valid -->
  4471                                  		; index was nonzero, meaning bx now holds a
  4472                                  		;  negative number. if [.active] is large enough,
  4473                                  		;  adding it to bx yields a positive number, which
  4474                                  		;  carries in the addition. check for that.
  4475 00000EF8 031D                    	add bx, word [di]
  4476 00000EFA 73E1                    	jnc .notysf		; not valid index -->
  4477 00000EFC EB02                    	jmp @FF			; valid, use it
  4478                                  @@:
  4479 00000EFE 031D                    	add bx, word [di]
  4480                                  				; 0 means the topmost level
  4481                                  @@:
  4482                                  %if _INPUT_FILE_BOOT
  4483                                   %if _INPUT_FILE_HANDLES
  4484 00000F00 3C42                    	cmp al, 'B'
  4485 00000F02 750D                    	jne @F
  4486                                   %endif
  4487                                  
  4488 00000F04 B8A000                  	mov ax, LOAD_INPUT_FILE_SIZE
  4489 00000F07 93                      	xchg ax, bx
  4490 00000F08 F7E3                    	mul bx			; dx ignored, should be zero
  4491 00000F0A 93                      	xchg ax, bx		; bx = offset into array
  4492 00000F0B 81C3[2600]              	add bx, load_input_file - LOADDATA3 + ldFATType
  4493                                  				; -> flag word
  4494 00000F0F EB0A                    	jmp @FF
  4495                                  
  4496                                  @@:
  4497                                  %endif
  4498                                  %if _INPUT_FILE_HANDLES
  4499 00000F11 D1E3                    	shl bx, 1
  4500 00000F13 D1E3                    	shl bx, 1
  4501 00000F15 D1E3                    	shl bx, 1		; to qword array index
  4502                                   %if INPUTFILEHANDLE_size != 8
  4503                                    %error Unexpected structure size
  4504                                   %endif
  4505 00000F17 81C3[0200]              	add bx, input_file_handles + ifhFlags
  4506                                  				; -> flags word
  4507                                  %endif
  4508                                  @@:
  4509 00000F1B BF[780C]                	mov di, mask_ysf	; give the mask of read-only bits
  4510 00000F1E F8                      	clc
  4511 00000F1F C3                      	retn
  4512                                  %endif
  4513                                  
  4514                                  
  4515                                  	lleave ctx
  4516                                  
  4517                                  
  4518                                  		; INP:	al, si-> string
  4519                                  		; OUT:	CY if no valid digit 0..7
  4520                                  		;	NC if valid digit,
  4521                                  		;	 bl = 0..7
  4522                                  		;	 al, si-> behind digit specification
  4523                                  		; CHG:	bl
  4524                                  getstmmxdigit: section_of_function
  4525 00000F20 3C28                    	cmp al, '('
  4526 00000F22 7407                    	je .paropen
  4527 00000F24 E81A00                  	call .isdigit?
  4528 00000F27 7201                    	jc .ret
  4529                                  .retlodsb:
  4530 00000F29 AC                      	lodsb
  4531                                  .ret:
  4532 00000F2A C3                      	retn
  4533                                  
  4534                                  .paropen:
  4535 00000F2B 50                      	push ax
  4536 00000F2C 56                      	push si
  4537 00000F2D AC                      	lodsb
  4538 00000F2E E81000                  	call .isdigit?
  4539 00000F31 720B                    	jc .retpop
  4540 00000F33 AC                      	lodsb
  4541 00000F34 3C29                    	cmp al, ')'		; closing parenthesis ?
  4542 00000F36 F9                      	stc
  4543 00000F37 7505                    	jne .retpop		; no --> (CY)
  4544 00000F39 83C404                  	add sp, byte 4		; discard saved registers (NC)
  4545 00000F3C EBEB                    	jmp short .retlodsb
  4546                                  
  4547                                  .retpop:
  4548 00000F3E 5E                      	pop si
  4549 00000F3F 58                      	pop ax
  4550 00000F40 C3                      	retn
  4551                                  
  4552                                  .isdigit?:
  4553 00000F41 88C3                    	mov bl, al
  4554 00000F43 80EB30                  	sub bl, '0'
  4555 00000F46 80FB08                  	cmp bl, 8		; valid digit 0..7 ? (CY if so)
  4556 00000F49 F5                      	cmc			; NC if so
  4557 00000F4A C3                      	retn
  4558                                  
  4559                                  
  4560                                  %if _EXPRDUALCODE && _DUALCODE
  4561                                  	usesection lDEBUG_CODE2
  4561          ------------------       note: usesection lDEBUG_CODE2
  4562                                  %else
  4563                                  	usesection lDEBUG_CODE
  4564                                  %endif
  4565                                  isvariable_code_size equ $ - isvariable_code
  4566                                  
  4567                                  
  4568                                  	usesection lDEBUG_DATA_ENTRY
  4568          ------------------       note: usesection lDEBUG_DATA_ENTRY
  4569                                  isvariable_data_size equ $ - isvariable_data
  4570                                  
  4571                                  	numdef SHOW_ISVARIABLE_SIZE, _DEFAULTSHOWSIZE
  4572                                  %if _SHOW_ISVARIABLE_SIZE
  4573                                   %assign CODESIZE isvariable_code_size
  4574                                   %assign DATASIZE isvariable_data_size
  4575                                   %warning isvariable size: CODESIZE code, DATASIZE data
  4576                                  %endif
  4577                                  
  4578                                  
  4579                                  	align 2, db 0
  4580 00000C80 110020090D2F5C2C4C-     separators:	countedw 32,9,13,"/\,L;]:)(=.'",'"',0
  4580 00000C89 3B5D3A29283D2E2722-
  4580 00000C92 00                 
  4581                                  
  4582                                  %ifn _EXPRESSIONS
  4583                                   %error Building without the expression evaluator is not possible right now
  4584                                  %endif
  4585                                  
  4586                                  %if _EXPRESSIONS
  4587                                  
  4588 00000C93 00                      	align 4, db 0
  4589 00000C94 00000000                hhvar:	dd 0	; left-hand operand for operator functions
  4590                                  %if _HHDIVREMAIN
  4591                                  hh_div_dividend:
  4592 00000C98 00000000                	dd 0
  4593                                  hh_div_divisor:
  4594 00000C9C 00000000                	dd 0
  4595                                  %endif
  4596                                  	align 2, db 0
  4597                                  hh_depth:
  4598 00000CA0 0000                    	dw 0
  4599                                  hh_depth_of_single_term:
  4600 00000CA2 0000                    	dw 0
  4601 00000CA4 00                      hhflag:	db 0	; &2: getdword called from hh, default to sub (precedence over 1)
  4602                                  		; &1: getdword called from hh, default to add
  4603                                  		; &4: getdword defaulted to add/sub for hh
  4604                                  		; (Note that during recursive getexpression calls (ie,
  4605                                  		;  bracket handling), hh_depth is incremented to 2 and
  4606                                  		;  higher. As these flags are only used with hh_depth == 1,
  4607                                  		;  this means inside brackets the hh defaulting is
  4608                                  		;  not in effect.)
  4609 00000CA5 00                      hhtype:	db 0	; type info on left-hand operand for operator functions
  4610                                  %if _HHDIVREMAIN
  4611                                  hh_div_active:
  4612 00000CA6 00                      	db 0
  4613                                  %endif
  4614                                  %endif
  4615                                  
  4616                                  
  4617                                  %if _EXPRDUALCODE && _DUALCODE
  4618                                  	usesection lDEBUG_CODE2
  4618          ------------------       note: usesection lDEBUG_CODE2
  4619                                  %else
  4620                                  	usesection lDEBUG_CODE
  4621                                  %endif
  4622                                  
  4623                                  		; Get a numerical value from input line
  4624                                  		; INP:	al = first character
  4625                                  		;	si-> next character
  4626                                  		; OUT:	bx:dx = numerical value
  4627                                  		;	ah&80h = whether a pointer
  4628                                  		;	ah&40h = whether a signed type
  4629                                  		;	ah&3Fh = number of significant bits
  4630                                  		;	 one-based position of highest one bit if unsigned or signed but positive
  4631                                  		;	 one-based position of lowest one bit from the top if negative signed
  4632                                  		;
  4633                                  		; Note:	This invalidates the symbol table access slice.
  4634                                  getdword: section_of_function
  4635                                  getexpression: section_of_function
  4636 00000F4B FF06[A00C]              	inc word [hh_depth]
  4637 00000F4F E8(0000)EB02[0000]      	nearcall skipcomm0
  4638 00000F56 51                      	push cx
  4639 00000F57 57                      	push di
  4640                                  	lframe
  4641 00000F58 5589E5                  	lenter
  4642                                  
  4643 00000F5B 31C9                    	xor cx, cx
  4644 00000F5D 51                      	push cx
  4645                                  	lvar word, ??Count
  4646                                  %define lCount ???Count
  4647                                  
  4648                                  		; The first number field's operator is initialized to
  4649                                  		; the dummy right-operand operator, which is set up with
  4650                                  		; the highest precedence. This means it'll be processed
  4651                                  		; immediately in the first iteration below.
  4652 00000F5E B119                    	mov cl, OPERATOR_RIGHTOP
  4653 00000F60 51                      	push cx				; initialize dummy first number operator
  4654 00000F61 83EC0A                  	sub sp, byte 6+4
  4655                                  	lvar 6, ??A
  4656                                  %define lA ???A
  4657                                  	lvar 6, ??B
  4658                                  %define lB ???B
  4659                                  
  4660                                  .loop:
  4661                                  		; Get next term of an expression. A term is one variable,
  4662                                  		; one immediate number, one expression contained within
  4663                                  		; round brackets or one expression used to access memory.
  4664                                  		; This code also parses any number of unary operators
  4665                                  		; (including type conversions) in front of the term.
  4666                                  		;
  4667                                  		; INP:	(si-1)-> first character
  4668                                  		; OUT:	(see label .term_done)
  4669                                  		;	bx:dx = numerical value of term
  4670                                  		;	ah&80h = whether a pointer
  4671                                  		;	ah&40h = whether a signed type
  4672                                  		;	al = first character behind term
  4673                                  		;	si-> line
  4674                                  		; CHG:	di, cx
  4675                                  		;
  4676                                  		; This part might be simplified by directly modifying 6byte[bp+lB]
  4677                                  		; instead of setting bx:dx and ah. (The current interface is one of
  4678                                  		; the holdovers of getexpressionterm as a separate function.) In
  4679                                  		; that case, bx:dx and ah presumably will then be simply added to
  4680                                  		; the CHG specification.
  4681                                  .term:
  4682 00000F64 4E                      	dec si
  4683 00000F65 56                      	push si			; -> term
  4684                                  
  4685                                  		; count unary operators and type specifiers,
  4686                                  		;  get the bit mask of required bytes
  4687                                  		;  and skip past the operators and specifiers
  4688 00000F66 E88705                  	nearcall count_unary_operators
  4689                                  
  4690                                  %if _INDIRECTION
  4691 00000F69 3C5B                    	cmp al, '['
  4692 00000F6B 7503E9C302              	je .indirection		; handle indirected value -->
  4693                                  %endif
  4694 00000F70 3C28                    	cmp al, '('
  4695 00000F72 7503E92303              	je .parens		; handle term with precedence -->
  4696                                  
  4697 00000F77 52                      	push dx			; remember the count+1
  4698                                  				; (only if no indirection or bracket)
  4699                                  
  4700 00000F78 4E                      	dec si
  4701 00000F79 BA[0000]                	mov dx, msg.value	; does a VALUE keyword for VALUE x IN y go here ?
  4702 00000F7C E8(0000)EB02[0000]      	nearcall isstring?
  4703 00000F83 7503E9CE01              	je .value_in		; yes -->
  4704                                  
  4705 00000F88 BA[0000]                	mov dx, msg.linear	; does a LINEAR keyword go here ?
  4706 00000F8B E8(0000)EB02[0000]      	nearcall isstring?
  4707 00000F92 7503E98401              	je .linear		; yes -->
  4708                                  
  4709                                  %if _PM
  4710 00000F97 BA[0000]                	mov dx, msg.desctype
  4711 00000F9A E8(0000)EB02[0000]      	nearcall isstring?
  4712 00000FA1 7503E93001              	je .desctype		; yes -->
  4713                                  %endif
  4714                                  
  4715 00000FA6 AC                      	lodsb
  4716                                  
  4717 00000FA7 E8B7FA                  	nearcall isvariable?	; is it a variable ?
  4718 00000FAA 7226                    	jc .check_literal_or_symbol
  4719                                  				; no, may be an immediate value or symbol -->
  4720                                  
  4721                                  .variable:
  4722 00000FAC 87DA                    	xchg bx, dx		; bx-> high word
  4723 00000FAE 88CC                    	mov ah, cl
  4724 00000FB0 31C9                    	xor cx, cx
  4725 00000FB2 80FC02                  	cmp ah, 2
  4726 00000FB5 7609                    	jbe .variable_nohigh
  4727 00000FB7 8B0F                    	mov cx, word [bx]	; get high word
  4728 00000FB9 80FC03                  	cmp ah, 3
  4729 00000FBC 7702                    	ja @F
  4730 00000FBE B500                    	mov ch, 0
  4731                                  @@:
  4732                                  .variable_nohigh:
  4733 00000FC0 87DA                    	xchg bx, dx		; bx-> low word
  4734 00000FC2 8B17                    	mov dx, word [bx]	; get low word
  4735 00000FC4 89CB                    	mov bx, cx		; high word/zero
  4736 00000FC6 80FC01                  	cmp ah, 1
  4737 00000FC9 7702                    	ja .variable_notbyte
  4738 00000FCB B600                    	mov dh, 0		; limit to byte
  4739                                  .variable_notbyte:
  4740                                  .symbol:
  4741 00000FCD B400                    	mov ah, 0		; type pointer=0 signed=0
  4742 00000FCF E9D802                  	jmp .term_end
  4743                                  
  4744                                  
  4745                                  .check_literal_or_symbol:
  4746                                  %if _SYMBOLIC
  4747                                  	nearcall issymbol?	; is it a symbol ?
  4748                                  	jnc .symbol		; yes -->
  4749                                  				; no, must be an immediate value
  4750                                  %endif
  4751                                  
  4752                                  .literal:
  4753 00000FD2 31DB                    	xor bx, bx		; (in case of decimal base shortcut:
  4754 00000FD4 BA0A00                  	mov dx, 10		;   set base: decimal)
  4755 00000FD7 3C23                    	cmp al, '#'		; shortcut change to decimal base, or string literal?
  4756 00000FD9 7547                    	jne .lithex_common
  4757 00000FDB 803C22                  	cmp byte [si], '"'
  4758 00000FDE 7408                    	je .lit_string
  4759 00000FE0 803C27                  	cmp byte [si], "'"
  4760 00000FE3 7403                    	je .lit_string
  4761 00000FE5 E98000                  	jmp .lit_base		; decimal base -->
  4762                                  
  4763                                  .lit_string:
  4764 00000FE8 31D2                    	xor dx, dx
  4765 00000FEA AC                      	lodsb
  4766 00000FEB 86C4                    	xchg al, ah
  4767                                  
  4768 00000FED E81900                  	call @F
  4769 00000FF0 88C2                    	mov dl, al
  4770 00000FF2 E81400                  	call @F
  4771 00000FF5 88C6                    	mov dh, al
  4772 00000FF7 E80F00                  	call @F
  4773 00000FFA 88C3                    	mov bl, al
  4774 00000FFC E80A00                  	call @F
  4775 00000FFF 88C7                    	mov bh, al
  4776 00001001 AC                      	lodsb
  4777 00001002 38E0                    	cmp al, ah
  4778 00001004 7419                    	je @FFF
  4779                                  .err3:
  4780 00001006 E9CA00                  	jmp .err2
  4781                                  
  4782                                  @@:
  4783 00001009 AC                      	lodsb
  4784 0000100A 38E0                    	cmp al, ah
  4785 0000100C 740A                    	je @F
  4786 0000100E E8(0000)EB02[0000]      	nearcall iseol?.notsemicolon
  4787 00001015 74EF                    	je .err3
  4788                                  .lit_string_retn:
  4789 00001017 C3                      	retn
  4790                                  
  4791                                  @@:
  4792 00001018 AC                      	lodsb
  4793 00001019 38E0                    	cmp al, ah
  4794 0000101B 74FA                    	je .lit_string_retn
  4795 0000101D 59                      	pop cx			; (discard near return address)
  4796 0000101E 4E                      	dec si
  4797                                  @@:
  4798 0000101F AC                      	lodsb
  4799 00001020 EB3C                    	jmp .lit_end_string
  4800                                  
  4801                                  
  4802                                  .lithex_common:
  4803 00001022 E86B04                  	call .lit_ishexdigit?	; the first character must be a digit then
  4804 00001025 7303E9A900              	jc .err2
  4805 0000102A 30D2                    	xor dl, dl		; initialize value
  4806                                  .lithex_loopdigit:
  4807 0000102C 3C5F                    	cmp al, '_'
  4808 0000102E 7427                    	je .lithex_skip
  4809 00001030 E85D04                  	call .lit_ishexdigit?	; was last character ?
  4810 00001033 7225                    	jc .lit_end		; yes -->
  4811 00001035 F6C7F0                  	test bh, 0F0h		; would shift bits out ?
  4812 00001038 7403E99600              	jnz .err2
  4813 0000103D E8(0000)EB02[0000]      	nearcall capitalise
  4814 00001044 2C30                    	sub al, '0'
  4815 00001046 3C09                    	cmp al, 9		; was decimal digit ?
  4816 00001048 7602                    	jbe .lithex_decimaldigit; yes -->
  4817 0000104A 2C07                    	sub al, 'A'-('9'+1)	; else adjust for hexadecimal digit
  4818                                  .lithex_decimaldigit:
  4819 0000104C B90400                  	mov cx, 4
  4820                                  .lithex_loopshift:
  4821 0000104F D1E2                    	shl dx, 1
  4822 00001051 D1D3                    	rcl bx, 1
  4823 00001053 E2FA                    	loop .lithex_loopshift	; *16
  4824 00001055 08C2                    	or dl, al		; add in the new digit
  4825                                  .lithex_skip:
  4826 00001057 AC                      	lodsb
  4827 00001058 EBD2                    	jmp short .lithex_loopdigit
  4828                                  
  4829                                  .lit_end:
  4830 0000105A 3C23                    	cmp al, '#'		; base change specification?
  4831 0000105C 740A                    	je .lit_base		; yes -->
  4832                                  .lit_end_string:
  4833 0000105E E8CEF3                  	nearcall isseparator?	; after the number, there must be a separator
  4834 00001061 7570                    	jne .err2		; none here -->
  4835 00001063 B400                    	mov ah, 0		; type pointer=0 signed=0
  4836 00001065 E94202                  	jmp .term_end		; okay -->
  4837                                  .lit_base:
  4838 00001068 85DB                    	test bx, bx		; insure base <= 36
  4839 0000106A 7567                    	jnz .err2
  4840 0000106C 83FA24                  	cmp dx, byte 36
  4841 0000106F 7762                    	ja .err2
  4842 00001071 83FA02                  	cmp dx, byte 2		;  and >= 2
  4843 00001074 725D                    	jb .err2		; otherwise error -->
  4844                                  
  4845 00001076 AC                      	lodsb
  4846 00001077 80FA10                  	cmp dl, 16		; hexadecimal ?
  4847 0000107A 74A6                    	je .lithex_common	; yes, use specific handling -->
  4848                                  
  4849 0000107C 89D7                    	mov di, dx		; di = base
  4850 0000107E 88D1                    	mov cl, dl
  4851 00001080 80C12F                  	add cl, '0'-1
  4852 00001083 80F939                  	cmp cl, '9'
  4853 00001086 7602                    	jbe .lit_basebelow11
  4854 00001088 B139                    	mov cl, '9'
  4855                                  .lit_basebelow11:		; cl = highest decimal digit for base ('1'..'9')
  4856 0000108A 88D5                    	mov ch, dl
  4857 0000108C 80C536                  	add ch, 'A'-10-1	; ch = highest letter for base ('A'-x..'Z')
  4858                                  
  4859 0000108F E80104                  	call .lit_isdigit?	; first character must be a digit
  4860 00001092 723F                    	jc .err2
  4861 00001094 31D2                    	xor dx, dx		; initialize value
  4862                                  .lit_loopdigit:
  4863 00001096 3C5F                    	cmp al, '_'
  4864 00001098 7436                    	je .lit_skip
  4865 0000109A E8F603                  	call .lit_isdigit?	; was last character ?
  4866 0000109D 72BB                    	jc .lit_end		; yes -->
  4867 0000109F E8(0000)EB02[0000]      	nearcall capitalise
  4868 000010A6 2C30                    	sub al, '0'
  4869 000010A8 3C09                    	cmp al, 9		; was decimal digit ?
  4870 000010AA 7602                    	jbe .lit_decimaldigit	; yes -->
  4871 000010AC 2C07                    	sub al, 'A'-('9'+1)	; else adjust for hexadecimal digit
  4872                                  .lit_decimaldigit:
  4873 000010AE 50                      	push ax
  4874 000010AF 89D0                    	mov ax, dx
  4875 000010B1 53                      	push bx
  4876 000010B2 F7E7                    	mul di			; multiply low word with base
  4877 000010B4 89D3                    	mov bx, dx
  4878 000010B6 89C2                    	mov dx, ax
  4879 000010B8 58                      	pop ax
  4880 000010B9 52                      	push dx
  4881 000010BA F7E7                    	mul di			; multiply high word with base
  4882 000010BC 85D2                    	test dx, dx
  4883 000010BE 5A                      	pop dx
  4884 000010BF 7512                    	jnz .err2		; overflow -->
  4885 000010C1 01C3                    	add bx, ax		; add them
  4886 000010C3 58                      	pop ax
  4887 000010C4 720D                    	jc .err2		; overflow -->
  4888 000010C6 00C2                    	add dl, al		; add in the new digit
  4889 000010C8 80D600                  	adc dh, 0
  4890 000010CB 83D300                  	adc bx, byte 0
  4891 000010CE 7203                    	jc .err2		; overflow -->
  4892                                  ; The value 3#102002022201221111210 is exactly equal to ffffFFFFh
  4893                                  ;  so 3#102002022201221111211 (or ...2) overflows 32 bits and
  4894                                  ;  needs to be detected here when adding in the as yet least
  4895                                  ;  significant digit. This is why this jump is needed.
  4896                                  ; This also applies to decimal #4294967296.
  4897                                  
  4898                                  .lit_skip:
  4899 000010D0 AC                      	lodsb
  4900 000010D1 EBC3                    	jmp short .lit_loopdigit
  4901                                  
  4902                                  .err2:
  4903 000010D3 E92AEF                  	jmp error_expr
  4904                                  
  4905                                  
  4906                                  %if _PM
  4907                                  .desctype:
  4908 000010D6 58                      	pop ax			; discard unary operators counter
  4909                                  
  4910                                  %if _EXPRESSION_INDIRECTION_STACK_CHECK == _EXPRESSION_DESCTYPE_STACK_CHECK
  4911 000010D7 E80F05                  	call stack_check_indirection
  4912                                  %else
  4913                                  	mov ax, _EXPRESSION_DESCTYPE_STACK_CHECK
  4914                                  	call stack_check	; abort if deep recursion
  4915                                  %endif
  4916 000010DA A9[0000]                	test ax, msg.stack_overflow.desctype
  4917                                  
  4918 000010DD AC                      	lodsb
  4919 000010DE E8(0000)EB02[0000]      	nearcall ispm
  4920 000010E5 75EC                    	jnz short .err2
  4921 000010E7 E8(0000)EB02[0000]      	nearcall skipwh0
  4922 000010EE E84304                  	nearcall getword
  4923 000010F1 6652                    _386	push edx
  4924 000010F3 5A                      _386	pop dx
  4925 000010F4 660F02D2                _386	lar edx, edx
  4926 000010F8 7403                    _386	jz @F
  4927 000010FA 6631D2                  _386	xor edx, edx
  4928                                  @@:
  4929 000010FD 66C1EA08                _386	shr edx, 8
  4930 00001101 52                      _386	push dx
  4931 00001102 665A                    _386	pop edx
  4932                                  subcpu 286
  4933 00001104 0F02D2                  _no386	lar dx, dx
  4934 00001107 7402                    _no386	jz @F
  4935 00001109 31D2                    _no386	xor dx, dx
  4936                                  @@:
  4937 0000110B 86D6                    _no386	xchg dl, dh
  4938                                  subcpureset
  4939 0000110D 31DB                    	xor bx, bx
  4940 0000110F E8(0000)EB02[0000]      	nearcall skipcomm0
  4941 00001116 B400                    	mov ah, 0		; type pointer=0 signed=0
  4942 00001118 E98E01                  	jmp .term_end_recount
  4943                                  %endif
  4944                                  
  4945                                  
  4946                                  .linear:
  4947 0000111B 58                      	pop ax			; discard unary operators counter
  4948                                  
  4949                                  %if _EXPRESSION_INDIRECTION_STACK_CHECK == _EXPRESSION_LINEAR_STACK_CHECK
  4950 0000111C E8CA04                  	call stack_check_indirection
  4951                                  %else
  4952                                  	mov ax, _EXPRESSION_LINEAR_STACK_CHECK
  4953                                  	call stack_check	; abort if deep recursion
  4954                                  %endif
  4955 0000111F A9[0000]                	test ax, msg.stack_overflow.linear
  4956                                  
  4957 00001122 E8(0000)EB02[0000]      	nearcall skipwhite
  4958 00001129 FF36[0000]              _386_PM	push word [bAddr32]
  4959 0000112D 6652                    _386_PM	push edx
  4960 0000112F 5A                      _386_PM	pop dx
  4961 00001130 8B1E[0000]              	mov bx, word [reg_ds]
  4962 00001134 E8(0000)EB02[0000]      	nearcall getlinearaddr
  4963 0000113B 52                      _386_PM	push dx
  4964 0000113C 665A                    _386_PM	pop edx
  4965 0000113E 8F06[0000]              _386_PM	pop word [bAddr32]
  4966 00001142 728F                    	jc .err2
  4967                                  
  4968                                  %if !_LOADER
  4969 00001144 66                      	_386_PM_o32	; or dword
  4970 00001145 830E[0000]FF            	or word [bp_offset], strict byte -1
  4971                                  				; do not use a preferred offset
  4972                                  %endif
  4973                                  
  4974 0000114A E8(0000)EB02[0000]      	nearcall skipcomm0
  4975 00001151 B400                    	mov ah, 0		; type pointer=0 signed=0
  4976 00001153 E95301                  	jmp .term_end_recount
  4977                                  
  4978                                  
  4979                                  .value_in:
  4980 00001156 58                      	pop ax			; discard unary operators counter
  4981                                  
  4982                                  %if _EXPRESSION_INDIRECTION_STACK_CHECK == _EXPRESSION_VALUE_IN_STACK_CHECK
  4983 00001157 E88F04                  	call stack_check_indirection
  4984                                  %else
  4985                                  	mov ax, _EXPRESSION_VALUE_IN_STACK_CHECK
  4986                                  	call stack_check	; abort if deep recursion
  4987                                  %endif
  4988 0000115A A9[0000]                	test ax, msg.stack_overflow.value_in
  4989                                  
  4990 0000115D E8(0000)EB02[0000]      	nearcall skipcomma
  4991 00001164 4E                      	dec si
  4992 00001165 BA[0000]                	mov dx, msg.executing
  4993 00001168 E8(0000)EB02[0000]      	nearcall isstring?
  4994 0000116F 751C                    	jne @F
  4995 00001171 E8(0000)EB02[0000]      	nearcall skipcomma
  4996 00001178 56                      	push si
  4997 00001179 BE[0000]                	mov si, msg.executing_value_range
  4998 0000117C E8F903                  	nearcall get_value_range
  4999 0000117F 9C                      	pushf			; ! preserve CF
  5000 00001180 E8(0000)EB02[0000]      	nearcall chkeol
  5001 00001187 9D                      	popf
  5002 00001188 5E                      	pop si
  5003 00001189 4E                      	dec si			; preserves CF
  5004 0000118A AC                      	lodsb
  5005 0000118B EB03                    	jmp @FF
  5006                                  
  5007                                  @@:
  5008 0000118D E8E803                  	nearcall get_value_range; OUT:	cx:di = from, bx:dx = to
  5009                                  @@:
  5010 00001190 E8(0000)EB02[0000]      	nearcall skipcomm0
  5011                                  
  5012                                  		; If the VALUE is a not normal range (zero length
  5013                                  		;  or from > to) then we still have to parse the
  5014                                  		;  remaining input line to find the end of the
  5015                                  		;  VALUE x IN y construct. So we do this with a
  5016                                  		;  sort of hack: we take the invalid / unset
  5017                                  		;  range values, do all the (invalid) comparisons,
  5018                                  		;  but do not count any of the possible matches.
  5019                                  		; Look at .value_in.found for this hack.
  5020                                  	lframe none, nested
  5021 00001197 5589E5                  	lenter
  5022                                  	lvar word, bit0_do_not_match
  5023 0000119A 9C                      	 pushf
  5024                                  	lvar dword, value_from
  5025 0000119B 51                      	 push cx
  5026 0000119C 57                      	 push di
  5027                                  	lvar dword, value_to
  5028 0000119D 53                      	 push bx
  5029 0000119E 52                      	 push dx
  5030 0000119F 31C9                    	xor cx, cx
  5031                                  	lvar dword, found
  5032 000011A1 51                      	 push cx
  5033 000011A2 51                      	 push cx
  5034                                  
  5035 000011A3 51                      	push cx			; zero terminator of keyword remembered offsets
  5036 000011A4 4E                      	dec si
  5037 000011A5 BA[0000]                	mov dx, msg.in
  5038 000011A8 E8(0000)EB02[0000]      	nearcall isstring?
  5039                                  .err3_NZ:
  5040                                  .err4_NZ:
  5041 000011AF 7403E91FFF              	jne .err2
  5042                                  
  5043 000011B4 E8(0000)EB02[0000]      	nearcall skipcomma
  5044 000011BB 4E                      	dec si
  5045                                  
  5046                                  .value_in.loop:
  5047 000011BC E8(0000)EB02[0000]      	nearcall skipwhite
  5048 000011C3 4E                      	dec si
  5049 000011C4 BB[0000]                	mov bx, msgtable_value_range
  5050                                  				; -> table
  5051                                  
  5052                                  @@:
  5053 000011C7 8B17                    	mov dx, word [bx]
  5054 000011C9 85D2                    	test dx, dx
  5055 000011CB 7421                    	jz @F			; last checked, go get range -->
  5056 000011CD E8(0000)EB02[0000]      	nearcall isstring?
  5057 000011D4 7405                    	je .value_in.keyword	; found a keyword -->
  5058 000011D6 83C304                  	add bx, 4		; go to next table entry
  5059 000011D9 EBEC                    	jmp @B
  5060                                  
  5061                                  .value_in.keyword:
  5062                                  %if _EXPRESSION_INDIRECTION_STACK_CHECK == _EXPRESSION_VALUE_IN_STACK_CHECK
  5063 000011DB E80B04                  	call stack_check_indirection
  5064                                  %else
  5065                                  	mov ax, _EXPRESSION_VALUE_IN_STACK_CHECK
  5066                                  	call stack_check	; abort if deep recursion
  5067                                  %endif
  5068 000011DE A9[0000]                	test ax, msg.stack_overflow.value_in
  5069                                  
  5070 000011E1 E8(0000)EB02[0000]      	nearcall skipwhite	; skip past blanks
  5071 000011E8 56                      	push si			; remember offset after keyword
  5072 000011E9 8B7702                  	mov si, word [bx + 2]	; -> keyword replacement text
  5073 000011EC EBCE                    	jmp .value_in.loop	; handle replacement -->
  5074                                  
  5075                                  @@:
  5076 000011EE E88703                  	nearcall get_value_range; OUT:	cx:di = from, bx:dx = to
  5077 000011F1 7223                    	jc .value_in.next
  5078                                  
  5079                                  		; ! (StartVal > EndMatch)
  5080 000011F3 395EFC                  	cmp word [bp + ?value_from + 2], bx
  5081 000011F6 7503                    	jne @F
  5082 000011F8 3956FA                  	cmp word [bp + ?value_from], dx
  5083                                  @@:
  5084 000011FB 7719                    	ja .value_in.next
  5085                                  
  5086                                  		; ! (EndVal < StartMatch)
  5087 000011FD 394EF8                  	cmp word [bp + ?value_to + 2], cx
  5088 00001200 7503                    	jne @F
  5089 00001202 397EF6                  	cmp word [bp + ?value_to], di
  5090                                  @@:
  5091 00001205 720F                    	jb .value_in.next
  5092                                  
  5093                                  .value_in.found:
  5094 00001207 8B4EFE                  	mov cx, word [bp + ?bit0_do_not_match]
  5095 0000120A F7D1                    	not cx
  5096 0000120C 83E101                  	and cx, 1
  5097 0000120F 014EF2                  	add word [bp + ?found], cx
  5098 00001212 8356F200                	adc word [bp + ?found], 0
  5099                                  
  5100                                  .value_in.next:
  5101                                  @@:
  5102 00001216 E8(0000)EB02[0000]      	nearcall skipwh0
  5103 0000121D 3C2C                    	cmp al, ','
  5104 0000121F 749B                    	je .value_in.loop
  5105                                  
  5106 00001221 59                      	pop cx			; get next remembered offset
  5107 00001222 E306                    	jcxz @F			; if none -->
  5108 00001224 89CE                    	mov si, cx		; -> behind keyword
  5109 00001226 4E                      	dec si
  5110 00001227 AC                      	lodsb			; reload al
  5111 00001228 EBEC                    	jmp @B			; continue after the keyword -->
  5112                                  
  5113                                  @@:
  5114 0000122A 5A                      	pop dx
  5115 0000122B 5B                      	pop bx			; pop ?found counter variable
  5116 0000122C 89EC5D                  	lleave
  5117                                  
  5118 0000122F B400                    	mov ah, 0		; type pointer=0 signed=0
  5119 00001231 EB76                    	jmp .term_end_recount
  5120                                  
  5121                                  
  5122                                  %if _INDIRECTION
  5123                                  .indirection:
  5124 00001233 E8B303                  	call stack_check_indirection
  5125                                  				; abort if deep recursion
  5126 00001236 A9[0000]                	test ax, msg.stack_overflow.indirection
  5127                                  
  5128 00001239 FF36[0000]              _386_PM	push word [bAddr32]
  5129 0000123D 6652                    _386_PM	push edx
  5130 0000123F 5A                      _386_PM	pop dx
  5131                                  
  5132 00001240 E8(0000)EB02[0000]      	nearcall skipcomma	; also skips the '[' in al
  5133 00001247 8B1E[0000]              	mov bx, word [reg_ds]	; default segment/selector
  5134 0000124B 51                      	push cx			; save previous bit mask (ch)
  5135 0000124C E83CEF                  	nearcall getaddrX	; (recursively calls getexpression:)
  5136 0000124F 59                      	pop cx
  5137 00001250 B100                    	mov cl, 0
  5138 00001252 3C5D                    	cmp al, ']'		; verify this is the closing bracket
  5139                                  .err5_NZ:
  5140 00001254 7403E956FF              	jne .err4_NZ		;  if not -->
  5141 00001259 AC                      	lodsb			; get next character
  5142                                  		; bx:(e)dx-> data
  5143                                  		; ch = bit mask of required bytes
  5144                                  		; cl = 0
  5145                                  
  5146                                  ..@hh_indirection_memory_access_start:
  5147 0000125A 50                      	push ax
  5148 0000125B 55                      	push bp
  5149 0000125C 31ED                    	xor bp, bp
  5150 0000125E 55                      	push bp
  5151 0000125F 55                      	push bp
  5152 00001260 89E5                    	mov bp, sp		; -> buffer
  5153                                  
  5154 00001262 E8(0000)EB02[0000]      	nearcall prephack
  5155 00001269 E8(0000)EB02[0000]      	nearcall dohack
  5156                                  			; Regarding how this loop handles cx,
  5157                                  			;  remember that ch holds the flags for
  5158                                  			;  the required bytes.
  5159                                  			;  And cl is initialised to 0. In
  5160                                  			;  each iteration, cl is incremented.
  5161                                  			;  The loop instruction then decrements
  5162                                  			;  cl again, but the entire cx is only
  5163                                  			;  zero if no more bytes are required.
  5164                                  			; (This hack saves a single byte over
  5165                                  			;  the "test ch, ch \ jnz" alternative
  5166                                  			;  but it isn't very pretty. It
  5167                                  			;  also probably slows down a bit.)
  5168                                  .indirection_loop:
  5169 00001270 D0ED                    	shr ch, 1		; need to read this byte ?
  5170 00001272 730A                    	jnc .indirection_skip	; no -->
  5171                                  %if _DUALCODE && _EXPRDUALCODE
  5172                                  	usesection lDEBUG_CODE
  5172          ------------------       note: usesection lDEBUG_CODE
  5173                                  ..@hh_code1_indirection_memory_access_start:
  5174                                  
  5175                                  section_of ..@hh_readmem
  5176                                  	dualfunction
  5177                                  ..@hh_readmem:
  5178                                  	lframe dualdistance, nested
  5179                                  	lframe_needonlyregistered
  5180                                  	lenter
  5181 00000006 E8(0000)                	call readmem
  5182                                  	lleave
  5183 00000009 E8(0000)                	dualreturn
  5184 0000000C CB                      	lret
  5185                                  
  5186                                  ..@hh_code1_indirection_memory_access_end:
  5187                                  	usesection lDEBUG_CODE2
  5187          ------------------       note: usesection lDEBUG_CODE2
  5188 00001274 E8(0000)EB02[0600]      	dualcall ..@hh_readmem	; else read byte
  5189                                  %else
  5190                                  	nearcall readmem	; else read byte
  5191                                  %endif
  5192 0000127B 884600                  	mov byte [bp+0], al	; store byte
  5193                                  .indirection_skip:
  5194 0000127E 41                      	inc cx			; = 1 if no more to read
  5195 0000127F 45                      	inc bp			; increase buffer pointer
  5196 00001280 66                      	_386_PM_o32		; inc edx
  5197 00001281 42                      	inc dx			; increase offset
  5198 00001282 E2EC                    	loop .indirection_loop	; read next byte if any -->
  5199 00001284 E8(0000)EB02[0000]      	nearcall unhack
  5200                                  
  5201 0000128B 5A                      	pop dx
  5202 0000128C 5B                      	pop bx
  5203 0000128D 5D                      	pop bp
  5204 0000128E 58                      	pop ax
  5205                                  ..@hh_indirection_memory_access_end:
  5206                                  
  5207 0000128F 52                      _386_PM	push dx
  5208 00001290 665A                    _386_PM	pop edx
  5209 00001292 8F06[0000]              _386_PM	pop word [bAddr32]
  5210 00001296 B400                    	mov ah, 0		; type pointer=0 signed=0
  5211 00001298 EB0F                    	jmp short .term_end_recount
  5212                                  %endif
  5213                                  
  5214                                  
  5215                                  .parens:
  5216                                  %if _EXPRESSION_INDIRECTION_STACK_CHECK == _EXPRESSION_PARENS_STACK_CHECK
  5217 0000129A E84C03                  	call stack_check_indirection
  5218                                  %else
  5219                                  	mov ax, _EXPRESSION_PARENS_STACK_CHECK
  5220                                  	call stack_check	; abort if deep recursion
  5221                                  %endif
  5222 0000129D A9[0000]                	test ax, msg.stack_overflow.parens
  5223                                  
  5224 000012A0 AC                      	lodsb
  5225 000012A1 E8A7FC                  	nearcall getexpression	; (recursive) bx:dx = number, ah = type
  5226 000012A4 3C29                    	cmp al, ')'		; closing parens ?
  5227 000012A6 75AC                    	jne .err5_NZ		; no -->
  5228 000012A8 AC                      	lodsb
  5229                                  
  5230                                  .term_end_recount:
  5231 000012A9 A9                      	db __TEST_IMM16		; skip pop, stc; NC
  5232                                  .term_end:
  5233 000012AA 59                      	pop cx			; get count+1 of unary operators and type specifiers
  5234 000012AB F9                      	stc
  5235 000012AC 5F                      	pop di			; -> term
  5236 000012AD 87F7                    	xchg si, di
  5237 000012AF 57                      	push di			; save -> behind
  5238                                  		; si-> unary operators and types
  5239 000012B0 720B                    	jc .unary_processnext	; if we preserved the count -->
  5240                                  
  5241 000012B2 53                      	push bx
  5242 000012B3 52                      	push dx
  5243 000012B4 56                      	push si
  5244 000012B5 E83802                  	nearcall count_unary_operators
  5245 000012B8 89D1                    	mov cx, dx		; get count+1 again
  5246 000012BA 5E                      	pop si
  5247 000012BB 5A                      	pop dx
  5248 000012BC 5B                      	pop bx
  5249                                  
  5250                                  .unary_processnext:
  5251 000012BD E204                    	loop .unary_doprocess
  5252 000012BF 5E                      	pop si			; -> behind term
  5253 000012C0 4E                      	 dec si			; -> character to reload in skipwhite
  5254 000012C1 EB38                    	jmp short .term_done
  5255                                  
  5256                                  .unary_doprocess:
  5257 000012C3 56                      	push si
  5258 000012C4 51                      	push cx
  5259 000012C5 53                      	push bx
  5260 000012C6 52                      	push dx
  5261                                  
  5262 000012C7 89CF                    	mov di, cx		; count+1 of operators to skip
  5263 000012C9 E82602                  	nearcall count_unary_operators_restrict	; skip them
  5264 000012CC 752A                    	jnz .err		; if not enough --> (?!)
  5265                                  
  5266 000012CE E891F1                  	nearcall istype?	; get type info if it's a type
  5267 000012D1 7216                    	jc .unary_processnotype	; isn't a type -->
  5268 000012D3 86C4                    	xchg al, ah		; al = type input
  5269 000012D5 D1EB                    	shr bx, 1		; CF = signedness
  5270 000012D7 9F                      	lahf			; with CF = signedness
  5271 000012D8 8B8F[3200]              	mov cx, word [ typehandlers + bx ]	; function
  5272                                  .unary_processcall:
  5273 000012DC 5A                      	pop dx
  5274 000012DD 5B                      	pop bx
  5275                                  %if _HHDIVREMAIN
  5276 000012DE C606[A60C]00            	mov byte [hh_div_active], 0
  5277                                  %endif
  5278 000012E3 FFD1                    	call cx			; call type or unary operator handler
  5279                                  				;  bx:dx = output number, ah = type
  5280 000012E5 59                      	pop cx			; restore processing counter
  5281 000012E6 5E                      	pop si			; restore ->term
  5282 000012E7 EBD4                    	jmp short .unary_processnext
  5283                                  
  5284                                  .unary_processnotype:
  5285 000012E9 E828F1                  	nearcall isunaryoperator?; get unary operator index
  5286 000012EC 750A                    	jne .err		; if no unary operator --> (?!)
  5287 000012EE 89CB                    	mov bx, cx
  5288 000012F0 D1E3                    	shl bx, 1
  5289 000012F2 8B8F[6000]              	mov cx, word [ unaryoperatorhandlers + bx ]
  5290 000012F6 EBE4                    	jmp short .unary_processcall
  5291                                  
  5292                                  .err:
  5293 000012F8 E905ED                  	jmp error_expr
  5294                                  
  5295                                  .term_done:	; bx:dx = number, ah = type
  5296                                  		; get the operator following this number
  5297 000012FB E8(0000)EB02[0000]      	nearcall skipwhite
  5298 00001302 8956F2                  	mov word [bp+lB+0], dx
  5299 00001305 895EF4                  	mov word [bp+lB+2], bx		; store numeric value
  5300 00001308 8B1E[A20C]              	mov bx, word [hh_depth_of_single_term]
  5301 0000130C 3B1E[A00C]              	cmp bx, word [hh_depth]
  5302 00001310 746C                    	je .operator_invalid
  5303 00001312 E805F1                  	nearcall isoperator?		; cl = operator index (if any)
  5304 00001315 7454                    	je .operator_apparently_valid
  5305 00001317 E8(0000)EB02[0000]      	nearcall iseol?			; end of line follows ?
  5306 0000131E 745E                    	je .operator_invalid
  5307                                  .hh_twofold_check:
  5308                                  		; If we are processing a ?? :: conditional
  5309                                  		;  construct then we want the :: to end
  5310                                  		;  the parsing of the expression at that
  5311                                  		;  point, to then execute the OPERATOR_COND
  5312                                  		;  function of_cond. That means here we
  5313                                  		;  want to not apply the hh twofold case.
  5314                                  
  5315                                  		; The next check is for an ?? :: construct
  5316                                  		;  if the :: happens at hh depth == 1 and
  5317                                  		;  there is no nested ?? :: construct.
  5318 00001320 807EFC18                	cmp byte [bp + lA + 4], OPERATOR_COND
  5319 00001324 7458                    	je .operator_invalid		; special check for conditional operator
  5320                                  
  5321                                  		; The next check is for a nested ?? ::
  5322                                  		;  construct, or if the clause between
  5323                                  		;  ?? and :: contains any other operators
  5324                                  		;  than ??. (All operators have higher
  5325                                  		;  precedence than ??.)
  5326                                  		; If any ?? is waiting for its :: then we
  5327                                  		;  must accept the next :: as an invalid
  5328                                  		;  operator, thus not as a separator that
  5329                                  		;  activates the hh twofold operation.
  5330 00001326 8B4EFE                  	mov cx, word [bp + lCount]	; = how many operators waiting
  5331 00001329 E30C                    	jcxz @FF			; if none waiting --> (do hh twofold)
  5332 0000132B 89E3                    	mov bx, sp			; -> first waiting operator on stack
  5333                                  @@:
  5334 0000132D 803F18                  	cmp byte [bx], OPERATOR_COND	; is it a conditional operator ?
  5335 00001330 744C                    	je .operator_invalid		; yes, treat as invalid operator -->
  5336                                  					;  (it must be a :: to be valid)
  5337 00001332 83C306                  	add bx, 6			; -> next waiting operator on stack
  5338 00001335 E2F6                    	loop @B				; loop if any waiting operator left -->
  5339                                  @@:
  5340 00001337 833E[A00C]01            	cmp word [hh_depth], 1		; are we in first level expression ?
  5341 0000133C 7540                    	jne .operator_invalid		; no, do not do special H operation -->
  5342 0000133E F606[A40C]03            	test byte [hhflag], 1|2		; special H operation requested ?
  5343 00001343 7439                    	jz .operator_invalid		; no -->
  5344 00001345 B302                    	mov bl, OPERATOR_MINUS		; assume it's sub
  5345 00001347 F606[A40C]02            	test byte [hhflag], 2		; sub requested by H ?
  5346 0000134C 7501                    	jnz .hh_twofold_found		; yes -->
  5347 0000134E 4B                      	dec bx				; else it must be add
  5348                                  %if (OPERATOR_MINUS - 1) != OPERATOR_PLUS
  5349                                   %error Remove optimisation
  5350                                  %endif
  5351                                  .hh_twofold_found:
  5352 0000134F 800E[A40C]04            	or byte [hhflag], 4		; set flag for H twofold operation
  5353 00001354 4E                      	dec si
  5354 00001355 E8(0000)EB02[0000]      	nearcall skipcomma
  5355 0000135C EB22                    	jmp short .operator_done	; return this -->
  5356                                  
  5357                                  
  5358                                  		; INP:	bx = offset into operator dispatchers
  5359                                  		;	 = 2 * OUT:cx of isoperator? if ZR
  5360                                  		;	al = candidate operator text start
  5361                                  		;	si -> subsequent text
  5362                                  		; OUT:	bl = operator index, 0 if no valid operator
  5363                                  		;	 if valid: si -> after operator
  5364                                  		;	 if invalid: si unchanged (?)
  5365                                  		; CHG:	al, bh, dx
  5366                                  ..@call_operator_dispatchers: section_of_function
  5367 0000135E FFB7[6A00]              	push word [operatordispatchers + bx]
  5368                                  					; on stack: -> operator dispatcher
  5369 00001362 8B97[BE00]              	mov dx, word [operator_default_strings + bx]
  5370                                  					; dx = default operator string
  5371 00001366 8B9F[9400]              	mov bx, word [operator_default_indexes + bx]
  5372                                  					; bx = default operator index
  5373 0000136A C3                      	retn
  5374                                  
  5375                                  .operator_apparently_valid:
  5376 0000136B 89CB                    	mov bx, cx
  5377 0000136D 01DB                    	add bx, bx
  5378 0000136F E8ECFF                  	call ..@call_operator_dispatchers
  5379 00001372 84DB                    	test bl, bl			; valid ?
  5380 00001374 74AA                    	jz .hh_twofold_check		; no, check for H twofold operation -->
  5381 00001376 E8(0000)EB02[0000]      	nearcall skipwhite
  5382 0000137D A9                      	db __TEST_IMM16
  5383                                  .operator_invalid:
  5384 0000137E 31DB                    	xor bx, bx			; bl = 0 (no operator)
  5385                                  .operator_done:
  5386 00001380 88E7                    	mov bh, ah			; bh = type info
  5387 00001382 895EF6                  	mov word [bp+lB+4], bx		; store type and following operator
  5388                                  
  5389                                  %if _EXPRESSION_DEBUG
  5390                                  	push ax
  5391                                  	push bx
  5392                                  	push cx
  5393                                  	push dx
  5394                                  	push si
  5395                                  	push di
  5396                                  
  5397                                  	lea bx, [bp + lA]
  5398                                  	mov dx, .msgA
  5399                                  	call .debugdump
  5400                                  
  5401                                  	lea bx, [bp + lB]
  5402                                  	mov dx, .msgB
  5403                                  	call .debugdump
  5404                                  
  5405                                  	pop di
  5406                                  	pop si
  5407                                  	push si
  5408                                  	push di
  5409                                  	call .debugline
  5410                                  	jmp .debugend
  5411                                  
  5412                                  .debugline:
  5413                                  	call .debugpad
  5414                                  	mov dx, .msg_end1
  5415                                  	nearcall putsz
  5416                                  
  5417                                  	dec si
  5418                                  	mov dx, si
  5419                                  @@:
  5420                                  	lodsb
  5421                                  	nearcall iseol?
  5422                                  	jne @B
  5423                                  	mov cx, si
  5424                                  	dec cx
  5425                                  	sub cx, dx
  5426                                  	nearcall puts
  5427                                  
  5428                                  	mov dx, .msg_end2
  5429                                  	nearcall putsz
  5430                                  	retn
  5431                                  
  5432                                  	usesection lDEBUG_DATA_ENTRY
  5433                                  
  5434                                  .msgB:		asciz "B = "
  5435                                  .msgA:		asciz "A = "
  5436                                  .msg@:		asciz "@ = "
  5437                                  .msgPop:	asciz "Pop = "
  5438                                  .msg_opA:	asciz "(A) "
  5439                                  .msg_opB:	asciz " op (B)",13,10
  5440                                  .msg_none:	asciz "none"
  5441                                  .msg_op:	asciz ", "
  5442                                  .msg_end:	db " op"
  5443                                  .msg_linebreak:	asciz 13,10
  5444                                  .msg_end1:	asciz '"'
  5445                                  .msg_end2:	asciz '"',13,10,13,10
  5446                                  .msg_looping_cond:
  5447                                  		asciz "Looping for OPPREC_COND",13,10
  5448                                  
  5449                                  %if _EXPRDUALCODE && _DUALCODE
  5450                                  	usesection lDEBUG_CODE2
  5451                                  %else
  5452                                  	usesection lDEBUG_CODE
  5453                                  %endif
  5454                                  
  5455                                  .debugpad:
  5456                                  	mov cx, word [hh_depth]
  5457                                  	dec cx
  5458                                  	jz @FF
  5459                                  @@:
  5460                                  	mov al, 32
  5461                                  	nearcall putc
  5462                                  	loop @B
  5463                                  @@:
  5464                                  	retn
  5465                                  
  5466                                  .debugdump:
  5467                                  	call .debugpad
  5468                                  	nearcall putsz
  5469                                  
  5470                                  	cmp byte [bx + 4], OPERATOR_RIGHTOP
  5471                                  	jne @F
  5472                                  	mov dx, .msg_none
  5473                                  	nearcall putsz
  5474                                  	jmp .debugdump_none
  5475                                  
  5476                                  @@:
  5477                                  	sub sp, 8
  5478                                  	mov di, sp
  5479                                  	mov ax, word [bx + 2]
  5480                                  	nearcall hexword
  5481                                  	mov ax, word [bx]
  5482                                  	nearcall hexword
  5483                                  	mov cx, di
  5484                                  	mov di, sp
  5485                                  @@:
  5486                                  	cmp byte [di], '0'
  5487                                  	jne @F
  5488                                  	inc di
  5489                                  	cmp cx, di
  5490                                  	ja @B
  5491                                  	dec di
  5492                                  @@:
  5493                                  	sub cx, di
  5494                                  	mov dx, di
  5495                                  	push bx
  5496                                  	nearcall puts
  5497                                  	pop bx
  5498                                  	add sp, 8
  5499                                  
  5500                                  .debugdump_none:
  5501                                  	mov dx, .msg_op
  5502                                  	nearcall putsz
  5503                                  	mov si, word [bx + 4]
  5504                                  	and si, 00FFh
  5505                                  	add si, si
  5506                                  	mov dx, word [operatornames + si]
  5507                                  	nearcall putsz
  5508                                  	mov dx, .msg_end
  5509                                  	nearcall putsz
  5510                                  	retn
  5511                                  
  5512                                  .debugend:
  5513                                  	pop di
  5514                                  	pop si
  5515                                  	pop dx
  5516                                  	pop cx
  5517                                  	pop bx
  5518                                  	pop ax
  5519                                  %endif
  5520                                  
  5521 00001385 8A4EFC                  	mov cl, byte [bp+lA+4]
  5522 00001388 E8F300                  	call .compare_operators		; (cmp bl, cl = cmp Boprtr, Aoprtr)
  5523 0000138B 7249                    	jb .high_precedence_A		; compute the first operand first -->
  5524                                  					;  (jump taken for invalid Boprtr too)
  5525 0000138D 7505                    	jne @F
  5526                                  		; If we get the same operator precedence for
  5527                                  		;  Boprtr and Aoprtr we generally want to
  5528                                  		;  handle this as a high-precedence A.
  5529                                  		; This is not true for operator cond. If
  5530                                  		;  an expression like this is parsed:
  5531                                  		;  Acond ?? Bcond ?? Btrue :: Bfalse :: Afalse
  5532                                  		; Then we get first:
  5533                                  		;  A = none, right op
  5534                                  		;  B = Acond, cond op
  5535                                  		; After the right op is processed:
  5536                                  		;  A = Acond, cond op
  5537                                  		;  B = Bcond, cond op
  5538                                  		; Next we want:
  5539                                  		;  @ = Acond, cond op
  5540                                  		;  A = Bcond, cond op
  5541                                  		;  B = Btrue, invalid op (::)
  5542                                  		; If we did high precedence A here instead
  5543                                  		;  we would get:
  5544                                  		;  A = (Acond) cond op (Bcond)
  5545                                  		; At this point of_cond would parse "Btrue..."
  5546                                  		;  as the :: clause, failing because it doesn't
  5547                                  		;  start with a "::".
  5548 0000138F 83FB01                  	cmp bx, OPPREC_COND
  5549 00001392 7542                    	jne .high_precedence_A
  5550                                  
  5551                                  @@:
  5552 00001394 FF46FE                  	inc word [bp+lCount]		; increase loop count
  5553 00001397 FF76F8                  	push word [bp+lA+0]
  5554 0000139A FF76FA                  	push word [bp+lA+2]
  5555 0000139D FF76FC                  	push word [bp+lA+4]		; push A and its operator
  5556                                  
  5557                                  %if _EXPRESSION_DEBUG
  5558                                  	push ax
  5559                                  	push bx
  5560                                  	push cx
  5561                                  	push dx
  5562                                  	push si
  5563                                  	push di
  5564                                  
  5565                                  	lea bx, [bp + lA]
  5566                                  	mov dx, .msg@
  5567                                  	call .debugdump
  5568                                  	pop di
  5569                                  	pop si
  5570                                  	pop dx
  5571                                  	pop cx
  5572                                  	pop bx
  5573                                  	pop ax
  5574                                  %endif
  5575                                  
  5576 000013A0 FF76F6                  	push word [bp+lB+4]
  5577 000013A3 FF76F4                  	push word [bp+lB+2]
  5578 000013A6 FF76F2                  	push word [bp+lB+0]
  5579 000013A9 8F46F8                  	pop word [bp+lA+0]
  5580 000013AC 8F46FA                  	pop word [bp+lA+2]
  5581 000013AF 8F46FC                  	pop word [bp+lA+4]		; set A to B, including operator
  5582                                  
  5583                                  %if _EXPRESSION_INDIRECTION_STACK_CHECK == _EXPRESSION_PRECEDENCE_STACK_CHECK
  5584 000013B2 E83402                  	call stack_check_indirection
  5585                                  %else
  5586                                  	mov ax, _EXPRESSION_PRECEDENCE_STACK_CHECK
  5587                                  	call stack_check		; abort if deep recursion
  5588                                  %endif
  5589 000013B5 A9[0000]                	test ax, msg.stack_overflow.precedence
  5590                                  
  5591                                  d4	call expr_d4message
  5592                                  d4	asciz "getexpression: Entering loop/recursion",13,10
  5593                                  
  5594                                  .loop_j:
  5595 000013B8 E9A9FB                  	jmp .loop			; start again (former B as first term) -->
  5596                                  
  5597                                  .cont:
  5598                                  
  5599                                  d4	call expr_d4message
  5600                                  d4	asciz "getexpression: End of loop/recursion",13,10
  5601                                  
  5602 000013BB FF76FC                  	push word [bp+lA+4]
  5603 000013BE FF76FA                  	push word [bp+lA+2]
  5604 000013C1 FF76F8                  	push word [bp+lA+0]
  5605 000013C4 8F46F2                  	pop word [bp+lB+0]
  5606 000013C7 8F46F4                  	pop word [bp+lB+2]
  5607 000013CA 8F46F6                  	pop word [bp+lB+4]		; set B to A, including operator
  5608                                  
  5609 000013CD 8F46FC                  	pop word [bp+lA+4]
  5610 000013D0 8F46FA                  	pop word [bp+lA+2]
  5611 000013D3 8F46F8                  	pop word [bp+lA+0]		; pop A and its operator
  5612                                  
  5613                                  %if _EXPRESSION_DEBUG
  5614                                  	push ax
  5615                                  	push bx
  5616                                  	push cx
  5617                                  	push dx
  5618                                  	push si
  5619                                  	push di
  5620                                  
  5621                                  	lea bx, [bp + lA]
  5622                                  	mov dx, .msgPop
  5623                                  	call .debugdump
  5624                                  	lea bx, [bp + lB]
  5625                                  	mov dx, .msgB
  5626                                  	call .debugdump
  5627                                  
  5628                                  	pop di
  5629                                  	pop si
  5630                                  	push si
  5631                                  	push di
  5632                                  	call .debugline
  5633                                  
  5634                                  	pop di
  5635                                  	pop si
  5636                                  	pop dx
  5637                                  	pop cx
  5638                                  	pop bx
  5639                                  	pop ax
  5640                                  %endif
  5641                                  
  5642                                  .high_precedence_A:
  5643                                  
  5644                                  %if _EXPRESSION_DEBUG
  5645                                  	push ax
  5646                                  	push bx
  5647                                  	push cx
  5648                                  	push dx
  5649                                  	push si
  5650                                  	push di
  5651                                  
  5652                                  	call .debugpad
  5653                                  	mov dx, .msg_opA
  5654                                  	nearcall putsz
  5655                                  	lea bx, [bp + lA]
  5656                                  	mov si, word [bx + 4]
  5657                                  	and si, 00FFh
  5658                                  	add si, si
  5659                                  	mov dx, word [operatornames + si]
  5660                                  	nearcall putsz
  5661                                  	mov dx, .msg_opB
  5662                                  	nearcall putsz
  5663                                  
  5664                                  	pop di
  5665                                  	pop si
  5666                                  	pop dx
  5667                                  	pop cx
  5668                                  	pop bx
  5669                                  	pop ax
  5670                                  %endif
  5671                                  
  5672 000013D6 8B4EFC                  	mov cx, word [bp+lA+4]		; retrieve A's type info and operator
  5673 000013D9 FF76FA                  	push word [bp+lA+2]
  5674 000013DC FF76F8                  	push word [bp+lA+0]
  5675 000013DF 8B46F6                  	 mov ax, word [bp+lB+4]		;  retrieve B's type info and operator
  5676 000013E2 882E[A50C]              	  mov byte [hhtype], ch		;   set type info
  5677 000013E6 8F06[940C]              	pop word [hhvar]
  5678 000013EA B500                    	  mov ch, 0			;   cx = A's 1-based operator index
  5679 000013EC 8F06[960C]              	pop word [hhvar+2]		; retrieve A's number
  5680 000013F0 8B56F2                  	 mov dx, word [bp+lB+0]
  5681 000013F3 89CF                    	  mov di, cx
  5682 000013F5 8B5EF4                  	 mov bx, word [bp+lB+2]		;  retrieve B's number
  5683 000013F8 01FF                    	  add di, di			;   = offset into dispatch table
  5684 000013FA 50                      	 push ax			;  preserve B's operator
  5685                                  %if _HHDIVREMAIN
  5686 000013FB C606[A60C]00            	mov byte [hh_div_active], 0
  5687                                  %endif
  5688 00001400 FF95[EA00]              	call near [operatorfunctions+di]; compute: (A) operatorA (B)
  5689 00001404 59                      	 pop cx				; cl = B's operator
  5690                                  
  5691 00001405 8956F8                  	mov word [bp+lA+0], dx
  5692 00001408 88C8                    	mov al, cl			; B's operator
  5693 0000140A 895EFA                  	mov word [bp+lA+2], bx
  5694 0000140D 8946FC                  	mov word [bp+lA+4], ax		; store result in A, with B's operator
  5695                                  
  5696                                  %if OPERATOR_INVALID != 0
  5697                                   %error Remove optimisation
  5698                                  %endif
  5699 00001410 84C0                    	test al, al			; (previous B's) operator valid ?
  5700 00001412 7412                    	jz .end				; no, end of sequence -->
  5701                                  
  5702 00001414 837EFE00                	cmp word [bp+lCount], byte 0	; in recursion ?
  5703 00001418 749E                    	je .loop_j			; no, loop -->
  5704                                  
  5705 0000141A 5B                      	pop bx
  5706 0000141B 53                      	push bx				; retrieve saved ('@') operator
  5707                                  
  5708 0000141C E85F00                  	call .compare_operators		; (cmp bl, cl = cmp @oprtr, Aoprtr)
  5709 0000141F 7297                    	jb .loop_j			; A's operator's precedence higher -->
  5710                                  
  5711                                  %if _EXPRESSION_DEBUG
  5712                                  	push ax
  5713                                  	push bx
  5714                                  	push cx
  5715                                  	push dx
  5716                                  	push si
  5717                                  	push di
  5718                                  
  5719                                  	cmp bx, OPPREC_COND
  5720                                  	jne @F
  5721                                  	mov dx, .msg_looping_cond
  5722                                  	nearcall putsz
  5723                                  @@:
  5724                                  
  5725                                  	pop di
  5726                                  	pop si
  5727                                  	pop dx
  5728                                  	pop cx
  5729                                  	pop bx
  5730                                  	pop ax
  5731                                  %endif
  5732                                  
  5733 00001421 83FB01                  	cmp bx, OPPREC_COND
  5734 00001424 7492                    	je .loop_j
  5735                                  
  5736                                  d4	call expr_d4message
  5737                                  d4	asciz "getexpression: Loop/recursion found to be not necessary anymore",13,10
  5738                                  
  5739                                  ;	dec word [bp+lCount]
  5740                                  ;	jmp .cont			; return to previous level -->
  5741                                  
  5742                                  .end:
  5743 00001426 FF4EFE                  	dec word [bp+lCount]		; decrease loop count
  5744 00001429 7990                    	jns .cont			; process next operand from stack -->
  5745                                  
  5746 0000142B 8B56F8                  	mov dx, word [bp+lA+0]
  5747 0000142E 8B5EFA                  	mov bx, word [bp+lA+2]		; retrieve A
  5748 00001431 8B46FC                  	mov ax, word [bp+lA+4]		;  (discard (invalid) operator)
  5749                                  
  5750 00001434 89EC5D                  	lleave code			; remove the stack frame
  5751                                  
  5752 00001437 5F                      	pop di
  5753 00001438 59                      	pop cx				; restore registers
  5754                                  
  5755 00001439 FF0E[A00C]              	dec word [hh_depth]
  5756 0000143D 4E                      	 dec si
  5757 0000143E AC                      	 lodsb				; (restore al)
  5758                                  
  5759                                  .countsignificantbits: section_of_function getexpression
  5760 0000143F 51                      	push cx
  5761 00001440 52                      	push dx
  5762 00001441 53                      	push bx
  5763 00001442 B90100                  	mov cx, 1
  5764 00001445 53                      	 push bx
  5765 00001446 F6C440                  	test ah, 40h			; signed type ?
  5766 00001449 7416                    	jz .unsigned			; no -->
  5767 0000144B F6C780                  	test bh, 80h			; negative value ?
  5768 0000144E 7411                    	jz .unsigned			; no -->
  5769                                  .signed:
  5770 00001450 21D3                    	and bx, dx
  5771 00001452 43                      	inc bx				; = 0 if -1 (all bits set)
  5772 00001453 5B                      	 pop bx
  5773 00001454 741F                    	jz .done			; is -1, 1 significant bit -->
  5774 00001456 B122                    	mov cl, 32+1+1			; number of significant bits is 1 + 1-based index of highest clear bit
  5775                                  .signedloop:
  5776 00001458 D1E2                    	shl dx, 1
  5777 0000145A D1D3                    	rcl bx, 1			; shift up the number
  5778 0000145C 49                      	dec cx				; maintain index
  5779 0000145D 72F9                    	jc .signedloop			; still a set bit -->
  5780 0000145F EB14                    	jmp short .done
  5781                                  .unsigned:
  5782 00001461 09D3                    	or bx, dx			; = 0 if 0 (all bits cleared)
  5783 00001463 5B                      	 pop bx
  5784 00001464 740F                    	jz .done			; is 0, 1 significant bit -->
  5785 00001466 B121                    	mov cl, 32+1			; number of significant bits is 1-based index of highest set bit
  5786                                  .unsignedloop:
  5787 00001468 D1E2                    	shl dx, 1
  5788 0000146A D1D3                    	rcl bx, 1
  5789 0000146C 49                      	dec cx
  5790 0000146D 73F9                    	jnc .unsignedloop
  5791 0000146F F6C440                  	test ah, 40h			; positive signed value ?
  5792 00001472 7401                    	jz .done			; no -->
  5793 00001474 41                      	inc cx				; then the following zero bit is required too
  5794                                  .done:
  5795 00001475 80E4C0                  	and ah, 1100_0000b
  5796                                  		; insure we only pass the top two type bits
  5797 00001478 08CC                    	or ah, cl
  5798                                  		; low 6 bits = number of significant bits
  5799 0000147A 5B                      	pop bx
  5800 0000147B 5A                      	pop dx
  5801 0000147C 59                      	pop cx
  5802 0000147D C3                      	retn
  5803                                  
  5804                                  
  5805                                  		; INP:	bl = operator index 1
  5806                                  		;	cl = operator index 2
  5807                                  		; OUT:	flags as for "cmp precedence1, precedence2"
  5808                                  		; CHG:	bx, cx
  5809                                  .compare_operators:
  5810 0000147E E80600                  	call .getprecedence
  5811 00001481 E80300                  	call .getprecedence
  5812 00001484 39CB                    	cmp bx, cx
  5813 00001486 C3                      	retn
  5814                                  
  5815                                  .getprecedence:
  5816 00001487 30FF                    	xor bh, bh
  5817 00001489 8A9F[D000]              	mov bl, byte [operatorprecedences+bx]
  5818 0000148D 87D9                    	xchg bx, cx
  5819 0000148F C3                      	retn
  5820                                  
  5821                                  getexpression.lit_ishexdigit?: section_of_function
  5822 00001490 B93946                  	mov cx, "9F"
  5823                                  getexpression.lit_isdigit?: section_of_function
  5824 00001493 3C30                    	cmp al, '0'
  5825 00001495 7218                    	jb .no
  5826 00001497 38C8                    	cmp al, cl
  5827 00001499 7611                    	jbe .yes
  5828 0000149B 50                      	push ax
  5829 0000149C E8(0000)EB02[0000]      	nearcall capitalise
  5830 000014A3 38E8                    	cmp al, ch
  5831 000014A5 7707                    	ja .no_p
  5832 000014A7 3C41                    	cmp al, 'A'
  5833 000014A9 7203                    	jb .no_p
  5834 000014AB 58                      	pop ax
  5835                                  .yes:
  5836 000014AC F8                      	clc
  5837 000014AD C3                      	retn
  5838                                  
  5839                                  .no_p:
  5840 000014AE 58                      	pop ax
  5841                                  .no:
  5842 000014AF F9                      	stc
  5843 000014B0 C3                      	retn
  5844                                  
  5845                                  
  5846                                  of_cond: section_of_function
  5847 000014B1 50                      	push ax			; second operand type
  5848 000014B2 4E                      	dec si
  5849 000014B3 AD                      	lodsw
  5850 000014B4 3D3A3A                  	cmp ax, "::"
  5851 000014B7 7534                    	jne short .error
  5852                                  %if _EXPRESSION_INDIRECTION_STACK_CHECK == _EXPRESSION_COND_STACK_CHECK
  5853 000014B9 E82D01                  	call stack_check_indirection
  5854                                  %else
  5855                                  	mov ax, _EXPRESSION_COND_STACK_CHECK
  5856                                  	call stack_check	; abort if deep recursion
  5857                                  %endif
  5858 000014BC A9[0000]                	test ax, msg.stack_overflow.cond
  5859                                  
  5860 000014BF A1[940C]                	mov ax, word [hhvar]
  5861 000014C2 0B06[960C]              	or ax, word [hhvar + 2]	; ax = flag (zero if to take third operand)
  5862 000014C6 53                      	push bx
  5863 000014C7 52                      	push dx
  5864 000014C8 50                      	push ax			; preserve stack
  5865 000014C9 AC                      	lodsb
  5866 000014CA E87EFA                  	nearcall getexpression	; parse third operand
  5867 000014CD E8(0000)EB02[0000]      	nearcall skipcomm0	; allow comma afterwards
  5868 000014D4 59                      	pop cx
  5869 000014D5 E309                    	jcxz @F			; if to take third operand -->
  5870 000014D7 5A                      	pop dx
  5871 000014D8 5B                      	pop bx			; take second operand
  5872 000014D9 88C1                    	mov cl, al
  5873 000014DB 58                      	pop ax			; ah = second operand type
  5874 000014DC 88C8                    	mov al, cl		; preserve al
  5875 000014DE EB03                    	jmp @FF
  5876                                  
  5877                                  @@:
  5878 000014E0 59                      	pop cx
  5879 000014E1 59                      	pop cx			; discard second operand value
  5880 000014E2 59                      	pop cx			; discard second operand type
  5881                                  @@:
  5882 000014E3 59                      	pop cx			; discard near return address
  5883 000014E4 59                      	pop cx			; discard cx on stack
  5884                                  
  5885 000014E5 C646FC19                	mov byte [bp+lA+4], OPERATOR_RIGHTOP
  5886 000014E9 4E                      	dec si
  5887 000014EA E90EFE                  	jmp getexpression.term_done
  5888                                  
  5889                                  .error:
  5890 000014ED E910EB                  	jmp error_expr
  5891                                  
  5892                                  	lleave ctx
  5893                                  
  5894                                  
  5895                                  		; INP:	si-> possible unary operators
  5896                                  		; OUT:	dx = 1 + count of unary operators
  5897                                  		;	al, si-> behind identified unary operators
  5898                                  		;	ch = bit mask of required bytes,
  5899                                  		;	 bits 0..3 represent one byte of a dword each
  5900                                  		;	 bits 4..7 are clear
  5901                                  		; CHG:	bx, ch, di
  5902                                  		;
  5903                                  		; Type specifications are parsed as unary operators
  5904                                  		; here. (Elsewhere, "unary operators" refers only to
  5905                                  		; the unary operators specified as one of "+-~!?".)
  5906                                  count_unary_operators: section_of_function
  5907 000014F0 31FF                    	xor di, di
  5908                                  		; INP:	si-> possible unary operators
  5909                                  		;	di = maximum count+1 of unary operators to process,
  5910                                  		;	      zero means unlimited
  5911                                  		; OUT:	dx = 1 + count of unary operators,
  5912                                  		;	      at most di
  5913                                  		;	al, si-> behind identified unary operators
  5914                                  		;	ch = bit mask of required bytes,
  5915                                  		;	 bits 0..3 represent one byte of a dword each
  5916                                  		;	 bits 4..7 are clear
  5917                                  		;	ZR if maximum reached
  5918                                  		;	NZ if maximum not reached
  5919                                  		; CHG:	bx, ch
  5920                                  count_unary_operators_restrict: section_of_function
  5921 000014F2 B50F                    	mov ch, 1111b		; default to access a full dword
  5922 000014F4 31D2                    	xor dx, dx		; initialize counter to zero
  5923 000014F6 EB09                    	jmp @F
  5924                                  
  5925                                  .loop:
  5926 000014F8 E8(0000)EB02[0000]      	nearcall skipcomma
  5927 000014FF 4E                      	dec si
  5928 00001500 5F                      	pop di			; get maximum count
  5929                                  @@:
  5930 00001501 42                      	inc dx			; count unary operators and type specifiers
  5931 00001502 57                      	push di			; save maximum count again
  5932 00001503 E8(0000)EB02[0000]      	nearcall skipwhite	; load next character and skip blanks
  5933 0000150A 39FA                    	cmp dx, di		; reached maximum ?
  5934 0000150C 741B                    	je .end			; yes --> (ZR)
  5935 0000150E 51                      	 push cx
  5936 0000150F E850EF                  	nearcall istype?	; check for type and if so retrieve info
  5937 00001512 720F                    	jc .notype		; not a type -->
  5938 00001514 59                      	 pop cx
  5939                                  
  5940 00001515 D1EB                    	shr bx, 1		; discard signedness bit
  5941 00001517 89FE                    	mov si, di		; -> behind the type specifier
  5942 00001519 B11F                    	mov cl, 01Fh		; prepare shift count register
  5943 0000151B 238F[2400]              	and cx,[typebitmasks+bx]; apply mask and get shift count register
  5944 0000151F D2E5                    	shl ch, cl		; apply shift
  5945 00001521 EBD5                    	jmp short .loop		; check for more -->
  5946                                  
  5947                                  .notype:
  5948 00001523 E8EEEE                  	nearcall isunaryoperator?; is it a unary operator?
  5949 00001526 59                      	 pop cx
  5950 00001527 74CF                    	je .loop		; yes, check for more -->
  5951                                  				; (NZ)
  5952                                  .end:
  5953 00001529 5F                      	pop di			; discard
  5954 0000152A C3                      	retn
  5955                                  
  5956                                  
  5957                                  get3byte.checksignificantbits: section_of_function
  5958 0000152B 50                      	push ax
  5959 0000152C 80E43F                  	and ah, 3Fh
  5960 0000152F 80FC18                  	cmp ah, 24
  5961 00001532 EB1E                    	jmp checksignificantbitscommon
  5962                                  
  5963                                  getword: section_of_function
  5964 00001534 53                      	push bx
  5965 00001535 E813FA                  	nearcall getexpression
  5966 00001538 5B                      	pop bx
  5967                                  .checksignificantbits: section_of_function getword
  5968 00001539 50                      	push ax
  5969 0000153A 80E43F                  	and ah, 3Fh
  5970 0000153D 80FC10                  	cmp ah, 16
  5971 00001540 EB10                    	jmp checksignificantbitscommon
  5972                                  
  5973                                  getbyte: section_of_function
  5974 00001542 53                      	push bx
  5975 00001543 52                      	push dx
  5976 00001544 E804FA                  	nearcall getexpression
  5977 00001547 5B                      	pop bx
  5978 00001548 88FE                    	mov dh, bh
  5979 0000154A 5B                      	pop bx
  5980                                  .checksignificantbits: section_of_function getbyte
  5981 0000154B 50                      	push ax
  5982 0000154C 80E43F                  	and ah, 3Fh
  5983 0000154F 80FC08                  	cmp ah, 8
  5984                                  checksignificantbitscommon: section_of_function
  5985 00001552 58                      	pop ax
  5986 00001553 7701                    	ja short errorj6	; if error
  5987 00001555 C3                      	retn
  5988                                  
  5989                                  errorj6:
  5990 00001556 E9A7EA                  	jmp error_expr
  5991                                  
  5992                                  
  5993                                  ;	GETNYB - Convert the hex character in AL into a nybble.  Return
  5994                                  ;	carry set in case of error.
  5995                                  
  5996                                  getnyb: section_of_function
  5997 00001559 50                      	push ax
  5998 0000155A 2C30                    	sub al, '0'
  5999 0000155C 3C09                    	cmp al, 9
  6000 0000155E 7611                    	jbe .return		; if normal digit
  6001 00001560 58                      	pop ax
  6002 00001561 50                      	push ax
  6003 00001562 E8(0000)EB02[0000]      	nearcall capitalise
  6004 00001569 2C41                    	sub al, 'A'
  6005 0000156B 3C05                    	cmp al, 'F'-'A'
  6006 0000156D 7706                    	ja .error		; if not A..F
  6007 0000156F 040A                    	add al, 10
  6008                                  .return:
  6009 00001571 44                      	inc sp			; normal return (first pop old AX)
  6010 00001572 44                      	inc sp
  6011 00001573 F8                      	clc
  6012 00001574 C3                      	retn
  6013                                  .error:
  6014 00001575 58                      	pop ax			; error return
  6015 00001576 F9                      	stc
  6016 00001577 C3                      	retn
  6017                                  
  6018                                  
  6019                                  		; INP:	si -> input line
  6020                                  		; OUT:	NC if normal range (nonzero, upper >= lower),
  6021                                  		;	 bx:dx = TO value (upper bound)
  6022                                  		;	 cx:di = FROM value (lower bound)
  6023                                  		;	CY if not normal,
  6024                                  		;	 bx:dx and cx:di may be invalid
  6025                                  		;	 ZR if FROM LENGTH with zero length, cx:di valid
  6026                                  		;	al = first character
  6027                                  		;	si -> next character
  6028                                  		;	jumps to error if invalid input
  6029                                  get_value_range: section_of_function
  6030 00001578 E8(0000)EB02[0000]      	nearcall skipwhite
  6031 0000157F 4E                      	dec si
  6032 00001580 BA[0000]                	mov dx, msg.from
  6033 00001583 E8(0000)EB02[0000]      	nearcall isstring?
  6034 0000158A AC                      	lodsb
  6035 0000158B 754C                    	jne .not_from
  6036                                  
  6037                                  .from:
  6038 0000158D E8BBF9                  	nearcall getexpression	; (recursive)
  6039 00001590 89D7                    	mov di, dx
  6040 00001592 89D9                    	mov cx, bx		; cx:di = from
  6041                                  
  6042 00001594 E8(0000)EB02[0000]      	nearcall skipcomm0
  6043 0000159B 4E                      	dec si
  6044 0000159C BA[0000]                	mov dx, msg.to
  6045 0000159F E8(0000)EB02[0000]      	nearcall isstring?
  6046 000015A6 742B                    	je .from_to
  6047 000015A8 BA[0000]                	mov dx, msg.length
  6048 000015AB E8(0000)EB02[0000]      	nearcall isstring?
  6049 000015B2 7510                    	jne short .error
  6050                                  
  6051                                  .from_length:
  6052 000015B4 AC                      	lodsb
  6053 000015B5 51                      	push cx
  6054 000015B6 E8E4ED                  	nearcall get_length	; (recursive call to getexpression)
  6055 000015B9 59                      	pop cx
  6056 000015BA 85DB                    	test bx, bx
  6057 000015BC 7509                    	jnz @F
  6058 000015BE 85D2                    	test dx, dx
  6059 000015C0 7505                    	jnz @F
  6060                                  				; ZR = length is zero, cx:di = from
  6061                                  .notnormal:
  6062 000015C2 F9                      	stc
  6063 000015C3 C3                      	retn
  6064                                  
  6065                                  .error:
  6066 000015C4 E939EA                  	jmp error_expr
  6067                                  
  6068                                  @@:
  6069                                  				; bx:dx = length
  6070 000015C7 01FA                    	add dx, di
  6071 000015C9 11CB                    	adc bx, cx		; bx:dx = from + length
  6072 000015CB 83EA01                  	sub dx, 1
  6073 000015CE 83DB00                  	sbb bx, 0		; bx:dx = from + length - 1
  6074 000015D1 EB0D                    	jmp @F
  6075                                  
  6076                                  .from_to:
  6077 000015D3 AC                      	lodsb
  6078                                  
  6079 000015D4 E874F9                  	nearcall getexpression	; (recursive)
  6080                                  				; bx:dx = to
  6081                                  				; cx:di = from
  6082 000015D7 EB07                    	jmp @F
  6083                                  
  6084                                  .not_from:
  6085 000015D9 E86FF9                  	nearcall getexpression	; (recursive)
  6086 000015DC 89D7                    	mov di, dx
  6087 000015DE 89D9                    	mov cx, bx		; bx:dx = cx:ax = value
  6088                                  
  6089                                  @@:
  6090 000015E0 39CB                    	cmp bx, cx
  6091 000015E2 7502                    	jne @F
  6092 000015E4 39FA                    	cmp dx, di
  6093                                  @@:
  6094 000015E6 72DA                    	jb .notnormal		; NZ = length overflow or not normal FROM TO
  6095 000015E8 C3                      	retn			; (NC)
  6096                                  
  6097                                  
  6098                                  stack_check_indirection:
  6099 000015E9 B88000                  	mov ax, _EXPRESSION_INDIRECTION_STACK_CHECK
  6100                                  
  6101                                  		; INP:	ax = how much stack should be left
  6102                                  		;	word [cs:ip + 1] = message for location
  6103                                  		; OUT:	doesn't return if stack overflow
  6104                                  		; CHG:	ax
  6105                                  		; STT:	ds = ss
  6106                                  stack_check:
  6107                                  %if _SYMBOLIC
  6108                                  	call .internal
  6109                                  %else
  6110 000015EC 05[0000]                	add ax, stack
  6111 000015EF 39C4                    	cmp sp, ax
  6112                                  %endif
  6113 000015F1 7201                    	jb @F
  6114 000015F3 C3                      	retn
  6115                                  
  6116                                  @@:
  6117 000015F4 58                      	pop ax
  6118                                  
  6119 000015F5 16                      	push ss
  6120 000015F6 07                      	pop es
  6121 000015F7 8B26[0000]              	mov sp, [throwsp]
  6122                                  
  6123 000015FB BF[0000]                	mov di, msg.stack_overflow.caller
  6124 000015FE E8(0000)EB02[0000]      	nearcall hexword
  6125 00001605 BA[0000]                	mov dx, msg.stack_overflow
  6126 00001608 E8(0000)EB02[0000]      	nearcall putsz
  6127 0000160F 93                      	xchg ax, bx
  6128 00001610 2E8B5701                	mov dx, [cs:bx + 1]
  6129 00001614 E8(0000)EB02[0000]      	nearcall putsz
  6130 0000161B B83801                  	mov ax, 0138h
  6131 0000161E E8(0000)EB02[0000]      	nearcall setrc
  6132                                  
  6133                                  %if _EXPRDUALCODE && _DUALCODE
  6134 00001625 E8(0000)EB02[0D00]      	nearcall to_errret_pop
  6135                                  	usesection lDEBUG_CODE
  6135          ------------------       note: usesection lDEBUG_CODE
  6136                                  
  6137                                  to_errret_pop: equ $
  6138 0000000D 83C406                  	add sp, 6
  6139 00000010 FF26[0000]              	jmp near [errret]
  6140                                  	usesection lDEBUG_CODE2
  6140          ------------------       note: usesection lDEBUG_CODE2
  6141                                  %else
  6142                                  	jmp near [errret]
  6143                                  %endif
  6144                                  
  6145                                  
  6146                                  %if _SYMBOLIC
  6147                                  		; INP:	ax = how much stack should be left
  6148                                  		; OUT:	CY if stack overflow
  6149                                  		; CHG:	ax
  6150                                  		; STT:	ds = ss
  6151                                  .internal: section_of_function stack_check
  6152                                  	add ax, word [stack_low_address]
  6153                                  	cmp sp, ax
  6154                                  	retn
  6155                                  %endif
  6156                                  
  6157                                  %if _PM
  6158                                  		; INP:	ss:sp -> 8-byte save area
  6159                                  		; OUT:	in PM: save area filled
  6160                                  		;	save area left on stack
  6161                                  		; CHG:	-
  6162                                  		; STT:	es = ds = debugger data selector
  6163                                  save_scratchsel:
  6164                                  	lframe near
  6165                                  	lpar qword, savearea
  6166                                  	lpar_return
  6167 0000162C 5589E5                  	lenter
  6168 0000162F E8(0000)EB02[0000]      	nearcall ispm
  6169 00001636 7517                    	jnz .ret
  6170 00001638 50                      	push ax
  6171 00001639 53                      	push bx
  6172 0000163A 66                      	_386_o32
  6173 0000163B 57                      	push di
  6174 0000163C 6631FF                  _386	xor edi, edi
  6175 0000163F 8D7E04                  	lea di, [bp + ?savearea]
  6176 00001642 8B1E[0000]              	mov bx, word [scratchsel]
  6177 00001646 B80B00                  	mov ax, 000Bh
  6178 00001649 CD31                    	int 31h			; get descriptor
  6179 0000164B 66                      	_386_o32
  6180 0000164C 5F                      	pop di
  6181 0000164D 5B                      	pop bx
  6182 0000164E 58                      	pop ax
  6183                                  .ret:
  6184 0000164F 5D                      	lleave
  6185 00001650 C3                      	lret
  6186                                  
  6187                                  		; INP:	ss:sp -> 8-byte save area
  6188                                  		; OUT:	in PM: save area used
  6189                                  		;	save area popped from stack
  6190                                  		; CHG:	-
  6191                                  		; STT:	es = ds = debugger data selector
  6192                                  restore_scratchsel:
  6193                                  	lframe near
  6194                                  	lpar qword, savearea
  6195 00001651 5589E5                  	lenter
  6196 00001654 E8(0000)EB02[0000]      	nearcall ispm
  6197 0000165B 7517                    	jnz .ret
  6198 0000165D 50                      	push ax
  6199 0000165E 53                      	push bx
  6200 0000165F 66                      	_386_o32
  6201 00001660 57                      	push di
  6202 00001661 6631FF                  _386	xor edi, edi
  6203 00001664 8D7E04                  	lea di, [bp + ?savearea]
  6204 00001667 8B1E[0000]              	mov bx, word [scratchsel]
  6205 0000166B B80C00                  	mov ax, 000Ch
  6206 0000166E CD31                    	int 31h			; set descriptor
  6207 00001670 66                      	_386_o32
  6208 00001671 5F                      	pop di
  6209 00001672 5B                      	pop bx
  6210 00001673 58                      	pop ax
  6211                                  .ret:
  6212 00001674 5D                      	lleave
  6213 00001675 C20800                  	lret
  6214                                  %endif
