Advertisement
Guest User

edlinas

a guest
Apr 5th, 2018
521
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 181.46 KB | None | 0 0
  1. #!/usr/bin/python
  2. try:
  3.     from tkinter import *
  4. except:
  5.     print("No tkinter? This must not be Python 3!")
  6.     raise SystemExit
  7. import random,re,array,os,sys
  8. from tkinter.filedialog import askopenfilename, asksaveasfilename
  9. ###############################################################
  10. #
  11. #              Edlinas
  12. #
  13. ###############################################################
  14. #
  15. #  This program is an x86 simulator which is intended for
  16. #  instructional use.  It is an updated version of a program
  17. #  originally written in QBasic to support the book
  18. #
  19. #       Linux Assembly Language Programming
  20. #
  21. #  In addition to simulating an x86 processor, it also
  22. #  functions as an assembler and an editor.  Much of the
  23. #  code for the program is based on the pseudo-C code in
  24. #  Rakesh Agarwal's, "x86 Architecture and Programming."
  25. #  In fact it should be possible to use that book as
  26. #  documentation for this program, and vice versa.
  27. #
  28. #  Much of the Tkinter code was adapted from examples
  29. #  in John Grayson's book "Python and Tkinter Programming".
  30. #
  31. #  The VerticalScrolledFrame class was taken from
  32. #
  33. #      tkinter.unpy.net/wiki
  34. #
  35. #  Thanks to John Stoddart for bringing in tkinter.filedialog.
  36. #
  37. #  Bug and other error reports are welcome and may
  38. #  be sent to Bob Neveln at:
  39. #
  40. #      neveln@cs.widener.edu
  41. #
  42. ###############################################################
  43. #
  44. #   ParseInit:
  45. #
  46. ###############################################################
  47. #
  48. #
  49. binary_mnemonics = ["ADD","OR","ADC","SBB","AND","SUB","XOR","CMP","MOV","ROL","ROR","RCL",
  50. "RCR","SHL","SHR","LDS","SAR","SAL","XCHG","TEST","IN","OUT","LES","LEA"]
  51.  
  52. unary_mnemonics = ["JO","JNO","JB","JAE","JE","JNE","JBE","JA","JS","JNS","JP","JNP","JL",
  53. "JGE","JLE","JG","INC","DEC","JNAE","JNB","JZ","JNZ","JNA","JNBE","JO","JO","JO","JO",
  54. "JNGE","JNL","JNG","JNLE","NOT","NEG","JC","JNC","PUSH","POP","CALL","RET","RETF","RETN","INT","MUL","DIV","IDIV","LOOP","LOOPZ","LOOPNZ","LOOPE","LOOPNE","JCXZ","JECXZ","JMP","JMPF","CALLF","IMUL"]
  55.  
  56. zrary_mnemonics = ["AAA","AAD","AAM","AAS","DAA","DAS","NOP","HLT","CLC","STC","CMC","CLD","CLI","STD","STI","INTO","IRET","IRETD","LAHF","POPF","POPFD","POPA","POPAD","PUSHF","PUSHFD","PUSHA","PUSHAD","SAHF","WAIT","CBW","CWD","XLATB","INSB","INSW","INSD","OUTSB","OUTSW","OUTSD","CMPSB","CMPSW","CMPSD","MOVSB","MOVSD","MOVSW","SCASB","SCASW","SCASD","STOSB","STOSW","STOSD","LODSB","LODSW","LODSD"]
  57.  
  58.  
  59. identifp = re.compile("([A-Za-z][\w_]*)")
  60.  
  61. Arity = {}
  62. Archlev = {}
  63. for x in binary_mnemonics:
  64.     Arity[x] = 2
  65.     Archlev[x] = 0
  66. for x in unary_mnemonics:
  67.     Arity[x] = 1
  68.     Archlev[x] = 0
  69. for x in zrary_mnemonics:
  70.     Arity[x] = 0
  71.     Archlev[x] = 0
  72. Arity["RET"]= [0,1]
  73. Arity["RETF"] = [0,1]  
  74. Arity["JMPF"] = [1,2]  
  75. Arity["CALLF"] = [1,2] 
  76. Arity["IMUL"] = [1,2,3]
  77.  
  78. list_286 = ["LGDT","LIDT","LLDT","LTR","STR","SLDT","SGDT","SIDT","LMSW","SMSW","VERR","VERW","LEAVE","ARPL","LAR","LSL","BOUND","ENTER"]
  79. for x in list_286:
  80.     Archlev[x] = 2
  81.     Arity[x] = 1
  82. Arity["ARPL"] = 2
  83. Arity["LAR"] = 2
  84. Arity["LSL"] = 2
  85. Arity["BOUND"] = 2
  86. Arity["ENTER"] = 2
  87. Arity["LEAVE"] = 0
  88.  
  89. list_386 =["BSF","BSR","BT","BTS","BTR","BTC","MOVZX","MOVSX","CWDE","CDQ","SETO","SETNO","SETB","SETAE","SETE","SETNE","SETBE","SETA","SETS","SETNS","SETP","SETNP","SETL","SETGE","SETLE","SETG","SHLD","SHRD","SETNAE","SETNB","SETZ","SETNZ","SETNA","SETNBE","LFS","LGS","LSS","CLTS","SETNGE","SETNL","SETNG","SETNLE"]
  90. for x in list_386:
  91.     Archlev[x] = 3
  92.     if x.startswith("S"):
  93.         Arity[x] = 1
  94.     else:
  95.         Arity[x] = 2
  96. Arity["SHLD"] = 3
  97. Arity["SHRD"] = 3
  98. Arity["LFS"] = 2
  99. Arity["LGS"] = 2
  100. Arity["LSS"] = 2
  101. Arity["CLTS"] = 0
  102. Arity["CWDE"] = 0
  103. Arity["CDQ"] = 0
  104.  
  105. list_486=["XADD","CMPXCHG","INVLPG","WBINVD","BSWAP","INVLPG","INVD"]
  106. for x in list_486:
  107.     Archlev[x] = 4
  108. Arity["XADD"] = 2
  109. Arity["CMPXCHG"] = 2
  110. Arity["INVLPG"] = [0,1]
  111. Arity["WBINVD"] = 0
  112. Arity["BSWAP"] = 1
  113.  
  114. list_586=["CMPXCHG8B","CPUID","RDTSC","RDMSR","WRMSR"]
  115. for x in list_586:
  116.     Archlev[x] = 5
  117.     Arity[x] = 0
  118. Arity["CMPXCHG8B"]=1
  119.  
  120. mnemonic_list = ['place_holder'] + binary_mnemonics + unary_mnemonics + zrary_mnemonics + \
  121. list_286 + list_386 + list_486 + list_586
  122.  
  123. index_insb = mnemonic_list.index("INSB")
  124. index_jo = mnemonic_list.index("JO")
  125. index_bt = mnemonic_list.index("BT")
  126. index_seto=mnemonic_list.index("SETO")
  127. index_rol=mnemonic_list.index("ROL")
  128.  
  129. #Bits#(x,hi,lo) is the numerical value of x in binary reading digits [lo:hi+1] 
  130.  
  131. use_size = 32
  132. program_env = {}
  133.  
  134. def build_line(source_line, line_num = ":"):
  135.     lp = LineParse(source_line)
  136.     if line_num == ":":
  137.         error_string = "Error: "
  138.     else:
  139.         error_string = "Error line " + str(line_num) + ": "
  140.     if type(lp) is str:
  141.         message = error_string + lp + " "
  142. #       print_feedback(message)
  143.         return message
  144.     (index, label, prefix,mnemonic, code, comment) = lp
  145.     if label == '':
  146.         rebuilt_source = prog.tabwidth * " " + source_line.lstrip() + "\n"
  147.     elif len(label) < prog.tabwidth:
  148.         rebuilt_source = (label + ":" + (prog.tabwidth * " "))[:prog.tabwidth] \
  149.                              + mnemonic + " " + code + comment + "\n"
  150.     else: # Give up.  Let the user deal with it.
  151.         rebuilt_source = source_line
  152.     if index < 0:
  153.         message = error_string + "not ready for directives.  "
  154.         print_feedback(message)
  155.         return message
  156.     if index == 0:
  157.         line = Line(rebuilt_source, '')
  158.         line.label = label
  159.         line.mnemonic = mnemonic
  160.     else:
  161.         ia = InstAssemble(code,index,prefix)
  162.         if type(ia) is str:
  163.             message = error_string  + ia  + " "
  164. #           print_feedback(message)
  165.             return message
  166. #
  167. #  Here is the line to uncomment for debugging execution vs assembly errors:
  168. #
  169.         print_feedback(ia)
  170. #       print_feedback(" ", True)  # Blanks entry box
  171.         (op, displabel, dispcode, hx) = ia
  172.         line = Line(rebuilt_source, hx)
  173.         line.label = label
  174.         line.mnemonic = mnemonic
  175.         line.displabel = displabel
  176.         line.dispcode = dispcode
  177.         line.dispwidth = 1 << ((dispcode& 7) >> 1)
  178.     return line
  179.  
  180. def LineParse(code):   
  181.     """ Return [index, label, prefix, mnemonic, code, comment] or an error-message"""
  182.     index   = 0
  183.     label   = ''
  184.     prefix  = ''
  185.     mnemonic= ''
  186.  
  187.     code = code.lstrip()
  188.     semicolon_spot = code.find(';')
  189.     if semicolon_spot != -1:
  190.         comment = code[semicolon_spot:]
  191.         code = code[:semicolon_spot]
  192.     else:
  193.         comment = ''
  194.  
  195.     while code and not mnemonic:
  196.         if code[0] == '.':
  197.             return 'Not ready for directives'
  198.                
  199.         identifm = identifp.match(code)
  200.         if identifm:
  201.             identif = identifm.group(1)
  202.             code = code[identifm.end(1):].lstrip()
  203.             upper_case = identif.upper()
  204.             if upper_case in mnemonic_list:
  205.                 index = mnemonic_list.index(upper_case)
  206.                 if prefix :
  207.                     if prefix != "LOCK" and (index < index_insb or index > index_insb + 20):
  208.                         return "Can't repeat " + upper_case
  209.                     else:
  210.                         mnemonic = prefix + ' ' + identif
  211.                 elif code.startswith(':'):
  212.                     return identif + ' is a reserved word'
  213.                 else:
  214.                     mnemonic = identif
  215.             elif upper_case in ['LOCK','REP','REPE','REPNE','REPZ','REPNZ']:
  216.                 if prefix:
  217.                     return  'Only one prefix allowed'
  218.                 elif upper_case == 'REPZ':
  219.                     prefix = 'REPE'
  220.                 elif upper_case == 'REPNZ':
  221.                     prefix = 'REPNE'
  222.                 else:
  223.                     prefix = upper_case
  224.             else:
  225.                 if prefix:
  226.                         return 'Mis-spelling?'
  227.                 elif code.startswith(':'):
  228.                     code = code[1:].lstrip()
  229.                 else:
  230.                     code = code.lstrip()
  231.                 label = identif
  232.         else:
  233.             return 'Not a valid identifier'
  234.     return [index, label, prefix, mnemonic, code, comment]
  235.  
  236. def InstAssemble(code,index,prefix):
  237.     displabel = ''
  238.     dispcode = 0
  239.     immc = ''
  240.     size8_bit = 0
  241.     if prefix == '':
  242.         rlpf = ''
  243.     elif prefix == "REP":  
  244.         rlpf = 'F3'
  245.     elif prefix == "REPE"
  246.         rlpf = 'F3'
  247.     elif prefix == "REPNE":
  248.         rlpf = 'F2'
  249.     elif prefix == "LOCK"
  250.         rlpf = 'F0'
  251.     else:
  252.         raise ValueError("Bad prefix: "+ prefix)
  253.    
  254.     if code:
  255.         arglist = [x.strip() for x in code.split(',')]
  256.     else:
  257.         arglist = []
  258.     n_args = len(arglist)
  259.  
  260.     mnemonic = mnemonic_list[index]
  261.     if type(Arity[mnemonic]) is int:
  262.         arity = Arity[mnemonic]
  263.         if arity != n_args:
  264.             if arity == 1:
  265.                 return mnemonic + ' takes 1 operand'
  266.             else:
  267.                 return mnemonic + ' takes ' + str(arity) + ' operands'
  268.     elif n_args in Arity[mnemonic]:
  269.         arity = n_args
  270.     else:
  271.         return mnemonic + ': number of operands is in '+ str(Arity[mnemonic])
  272.  
  273. # Stub values only:
  274.     opc = ''
  275.     op_code = -1
  276.     mpf = ''   
  277.     ospf = ''
  278.  
  279.     if arity == 3:
  280.         op3 = arglist[2]   
  281.         if op3 == '':
  282.             return 'Third argument missing'
  283.         op3_parse = OperandParse(op3)
  284.         if type(op3_parse) is str:
  285.             return op3_parse
  286.         [op3_type, op3_tail, reg3_num, size3] = op3_parse
  287.         if op3_type == 'imm':
  288.             op3_imp = Immparse(op3)
  289.             if type(op3_imp) is str:
  290.                 return op3_imp
  291.             else:
  292.                 [label, oneb3, value3] = op3_imp
  293.     if arity >= 2:
  294.         op2 = arglist[1]
  295.         if op2 == '':
  296.             return 'Second argument missing'
  297.         if mnemonic == "IN" and op2.startswith('[') and op2.endswith(']'):
  298.             op2 = op2[1:-1].strip()
  299.         elif mnemonic == "LEA" and op2.find('[')==-1:
  300.             op2 = "[" + op2 + "]"  
  301.         op2_parse = OperandParse(op2)
  302.         if type(op2_parse) is str:
  303.             return op_parse2
  304.         [op2_type,op2_tail,reg2_num,size2] = op2_parse
  305.         if op2_type == 'imm':
  306.             op2_imp = Immparse(op2)
  307.             if type(op2_imp) is str:
  308.                 return op2_imp
  309.             else:
  310.                 [label2, oneb2, value2] = op2_imp
  311.         elif op2_type == 'reg':
  312.             if size2 == 1:
  313.                 size2_bit = 1
  314.             else:  
  315.                 size2_bit = 0
  316.     if arity >= 1:
  317.         op1 = arglist[0]
  318.         if op1 == '':
  319.             return 'First argument missing'
  320.         if mnemonic == "OUT" and op1.startswith('[') and op1.endswith(']'):
  321.             op1 = op1[1:-1].strip()
  322.         op1_parse = OperandParse(op1)
  323.         if type(op1_parse) is str:
  324.             return op_parse1
  325.         [op1_type,op1_tail,reg1_num,size1] = op1_parse
  326.         if op1_type == 'imm':
  327.             op1_imp = Immparse(op1)
  328.             if type(op1_imp) is str:
  329.                 return op1_imp
  330.             else:
  331.                 [label1, oneb1, value1] = op1_imp
  332.                 displabel = label1
  333.         elif size1 == 1:
  334.             size8_bit = 1
  335.         elif op1_type == 'reg':
  336.             size8_bit = 0
  337.  
  338. #       return [op1_parse, op2_parse]
  339.        
  340.     if arity == 3:
  341.         if size1 > 4 or size2 > 4 or size3 > 4:
  342.             return 'General registers only'
  343.         if mnemonic == "IMUL":
  344.             if op3_type != "imm":
  345.                 return 'Third operand must be immediate'
  346.             if op1_type != "reg":
  347.                 return 'First operand must be a register'
  348.             if op2_type == "imm":
  349.                 return 'Second operand must be memory or a register'
  350.             if size2 > 0 and size2 != size1:
  351.                 return 'Operand size mismatch'
  352.             if size1 != (use_size >> 3):
  353.                 ospf = "66"
  354.             if oneb3 == 1:
  355.                 op_code = 0x6b
  356.                 immc = ImmEncode(value3,-1)
  357.             else:
  358.                 op_code = 0x69
  359.                 immc = ImmEncode(value3,-4)
  360.             rmenc = RegMemEncode(reg1_num,size1,op2_type,op2_tail,reg2_num)
  361.             if type(rmenc) is str:
  362.                 return rmenc
  363.             [mpf, mx, displabel, dispcode] = rmenc
  364.         if mnemonic in ["SHRD","SHLD"]:
  365.             if mnemonic == "SHRD":
  366.                 op_code = 0xac
  367.             else:
  368.                 op_code = 0xa4
  369.             if op2_type != "reg":
  370.                 return 'Second operand must be a register'
  371.             if op1_type == "imm":
  372.                 return 'First operand must be memory or a register'
  373.             if size2 == 1:
  374.                 return 'One byte operand not allowed'
  375.             if size1 > 0 and size1 != size2:
  376.                 return 'Operand size mismatch'
  377.             if op3_type == "imm" and oneb3:
  378.                 immc = ImmEncode(value3,-1)
  379.             elif op3_type == "imm" :
  380.                 return 'Third operand must be one byte'
  381.             elif op3_type == "reg" and reg3_num == 1 and size3 ==1:
  382.                 op_code = op_code + 1
  383.             else:
  384.                 return 'Third operand is CL or an immediate byte'
  385.             opc = "0F"
  386.             rmenc = RegMemEncode(reg2_num,size2,op1_type,op1_tail,reg1_num)
  387.             if type(rmenc) is str:
  388.                 return rmenc
  389.             [mpf, mx, displabel, dispcode] = rmenc
  390.     elif arity == 2 and op1_type == 'imm':
  391.         if mnemonic == "OUT":
  392.             if op2_type != "reg" or reg2_num != 0:
  393.                 return 'Second argument must be AL, AX, or EAX'
  394.             if 0 <= value1 < 256:
  395.                 op_code = 0xe7 - size2_bit
  396.                 immc = ImmEncode(value1,1)
  397.                 reg1_num = -1
  398.             else:
  399.                 return 'Immediate port must be one byte'
  400.             if size2 > 1 and size2 != (use_size>>3):
  401.                 ospf = "66"
  402.         elif mnemonic == "ENTER":
  403.             if op2_type != "imm":
  404.                 return 'Second argument must be immediate'
  405.             elif oneb1:
  406.                 op_code = 0xc8
  407.                 immc = ImmEncode(value1, 1) + ImmEncode(value2,2)
  408.                 reg1_num = -1
  409.             else:
  410.                 return 'Frame size is one byte'
  411.         elif mnemonic == "JMPF":
  412.             if op2_type != "imm":
  413.                 return 'Second argument must be immediate'
  414.             else:
  415.                 op_code = 0xea
  416.                 immc = ImmEncode(value1, use_size>>3) + ImmEncode(value2,2)
  417.                 reg1_num = -1
  418.         elif mnemonic == "CALLF":
  419.             if op2_type != "imm":
  420.                 return 'Second argument must be immediate'
  421.             else:
  422.                 op_code = 0x9a
  423.                 immc = ImmEncode(value1, use_size>>3) + ImmEncode(value2,2)
  424.                 reg1_num = -1
  425.         else:
  426.             return 'First operand cannot be immediate'
  427.         mx = ''    
  428.     elif arity == 2 and op1_type == 'reg' and size1 > 4:
  429.         if mnemonic == "MOV":
  430.             if op2_type == "imm":
  431.                 return "Can't use an immediate"
  432.             if size2 == 1:
  433.                 return op1_tail + " can't be one byte"
  434.             if size2 > 4:
  435.                 return 'Second operand must be a general register'
  436.             if size1 == 5:   # Load Segment Register
  437.                 op_code = 0x8e
  438.             elif size2 != 4 or op2_type != "reg" :
  439.                 return 'Need a 32 bit operand' 
  440.             elif size1 == 6: # Load Debug Register
  441.                 opc = "0F"
  442.                 op_code = 0x23
  443.             elif size1 == 7: # Load Test Register
  444.                 opc = "0F"
  445.                 op_code = 0x26
  446.             elif size1 == 8:  # Load Control Register
  447.                 opc = "0F"
  448.                 op_code = 0x22
  449.         elif size1 == 5:
  450.             return 'Works only with MOV, PUSH or POP'
  451.         else:
  452.             return 'Try MOV'
  453.         rmenc = RegMemEncode(reg1_num,size1,op2_type,op2_tail,reg2_num)
  454.         if type(rmenc) is str:
  455.             return rmenc
  456.         [mpf, mx, displabel, dispcode] = rmenc
  457.     elif arity == 2 and op2_type == 'reg' and size2 > 4:
  458.         if mnemonic == "MOV":
  459.             if size1 == 1:
  460.                 return op1_tail + " can't be one byte"
  461.             if size1 > 4:
  462.                 return 'First operand must be a general register'
  463.             if size2 == 5:  # Store Segment Register
  464.                 op_code = 0x8c
  465.             elif size1 != 4 or op1_type != "reg" :
  466.                 return 'Need a 32 bit operand' 
  467.             elif size2 == 6: # Store Debug Register
  468.                 opc = "0F"
  469.                 op_code = 0x21
  470.             elif size2 == 7: # Store Test Register
  471.                 opc = "0F"
  472.                 op_code = 0x24
  473.             elif size2 == 8: # Store Control Register
  474.                 opc = "0F"
  475.                 op_code = 0x20
  476.         elif size2 == 5:
  477.             return 'Works only with MOV, PUSH or POP'
  478.         else:
  479.             return 'Try MOV'
  480.         rmenc = RegMemEncode(reg2_num,size2,op1_type,op1_tail,reg1_num)
  481.         if type(rmenc) is str:
  482.             return rmenc
  483.         [mpf, mx, displabel, dispcode] = rmenc
  484.     elif arity == 2 and op1_type == 'mem' and op2_type == 'mem':
  485.         return 'Two memory operands not allowed'
  486.     elif arity == 2 and op2_type == 'imm':
  487. #       print "size1 = ",  size1
  488.         if mnemonic == "IN" and value2 < 256:
  489.             pass
  490.         elif size1 == 1 and oneb2 == 0:
  491.             return "Immediate operand won't fit"
  492.         if size1 == 1:
  493.             size8_bit = 1
  494.         else:
  495.             size8_bit = 0
  496. #           size1 = use_size >> 3
  497. #       print "size1 = ",  size1
  498.         immc = ImmEncode(value2, -size1)
  499.         if size1 != 1 and size1 != (use_size >> 3):
  500.             ospf = "66"
  501. #           print "size1 = ",  size1
  502. #           print "ospf =", ospf
  503.         if mnemonic == "MOV":
  504.             if op1_type == "reg":
  505.                 op_code = 0xb8 + reg1_num - (size8_bit<<3)
  506.                 reg2_num = -1
  507.             else:
  508.                 op_code = 0xc7 - size8_bit
  509.                 reg2_num = 0
  510.         elif mnemonic in ["ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"]:
  511.             oper_code = index - 1          
  512.             assert oper_code in range(8)
  513.             if op1_type == "reg" and reg1_num == 0:
  514.                 op_code = (oper_code << 3) + 5 - size8_bit
  515.                 reg2_num = -1
  516.             else:
  517.                 op_code = 0x81 - size8_bit
  518.                 reg2_num = oper_code
  519.         elif mnemonic in ["ROL","ROR","RCL","RCR","SHL","SHR","SAR","SAL"]:
  520.             if mnemonic == "SAL":
  521.                 reg2_num = 7
  522.             else:
  523.                 reg2_num = index - index_rol
  524.             if value2 == 1:
  525.                 op_code = 0xd1 - size8_bit
  526.                 immc = ''                       # Override default
  527.             elif oneb2:
  528.                 op_code = 0xc1  - size8_bit
  529.                 immc = ImmEncode(value2, -1)
  530.             else:
  531.                 return 'Shift count must be just one byte'
  532.         elif mnemonic == "TEST":
  533.             if op1_type == "reg" and reg1_num == 0:
  534.                 op_code = 0xa9 - size8_bit
  535.                 reg2_num = -1
  536.             else:
  537.                 op_code = 0xf7 - size8_bit
  538.                 reg2_num = 0
  539.         elif mnemonic in ["BT","BTS","BTR","BTC"]:
  540.             if oneb2 and size1 != 1:
  541.                 opc = "0F"
  542.                 op_code = 0xba
  543.                 reg2_num = index - index_bt + 4
  544.                 immc = ImmEncode(value2, 1)
  545.             elif size1 == 1:
  546.                 return 'Register cannot be one byte'
  547.             else:
  548.                 return 'Immediate argument must be one byte'
  549.         elif mnemonic == "IN":
  550.             if op1_type != "reg" or reg1_num != 0:
  551.                 return 'First argument must be AL, AX, or EAX'
  552.             elif 0 <= value2 < 256:
  553.                 immc = ImmEncode(value2, 1)
  554.             else:
  555.                 return 'Immediate port must be one byte (Use DX)'
  556.             op_code = 0xe5 - size8_bit
  557.             reg2_num = -1
  558.         elif mnemonic == "OUT":
  559.             return 'Second argument must be AL, AX, or EAX'
  560.         elif mnemonic == "IMUL":
  561.             if op1_type != "reg":
  562.                 return 'First operand must be a register'
  563.             elif size1 == 1:
  564.                 return 'One byte register not allowed'
  565.             elif oneb2 == 1 :
  566.                 op_code = 0x6b
  567.                 immc = ImmEncode(value2, -1)
  568.             else:
  569.                 op_cde = 0x69
  570.                 immc = ImmEncode(value2, -4)
  571.                 reg2_num = reg1_num
  572.                 op2_tail = op1_tail
  573.                 op2_type = op1_type
  574.         else:
  575.                 return 'Second argument cannot be immediate'
  576.         rmenc = RegMemEncode(reg2_num,size1,op1_type,op1_tail,reg1_num)
  577.         if type(rmenc) is str:
  578.             return rmenc
  579.         [mpf, mx, displabel, dispcode] = rmenc
  580.     elif arity == 2 and mnemonic in ["BSF","BSR","IMUL","LAR","LSL","MOVSX","MOVZX"]:
  581.         if op1_type != "reg":
  582.             return 'First operand must be a register'
  583.         opc = "0F"
  584.         if mnemonic == "LAR":
  585.             op_code = 2
  586.         elif mnemonic == "LSL":
  587.             op_code = 3
  588.         elif mnemonic == "BSF":
  589.             op_code = 0xbc
  590.         elif mnemonic == "BSR":
  591.             op_code = 0xbd
  592.         elif mnemonic == "IMUL":
  593.             op_code = 0xaf
  594.         elif mnemonic == "MOVSX":
  595.             if size2 >= size1:
  596.                 return 'Second argment must be smaller than the first'
  597.             elif size2 == -1:
  598.                 size2_bit = 0
  599.             else:
  600.                 size2_bit = 1
  601.             op_code = 0xbf - size2_bit
  602.         elif mnemonic == "MOVZX":
  603.             if size2 >= size1:
  604.                 return 'Second argment must be smaller than the first'
  605.             elif size2 == -1:
  606.                 size2_bit = 0
  607.             else:
  608.                 size2_bit = 1
  609.             op_code = 0xb7 - size2_bit
  610.         if size1 == 1:
  611.             return 'First argument cannot be one byte'
  612.         if size2 > -1 and size2 != size1 and mnemonic not in ["MOVZX","MOVSX"]:
  613.             return 'Argument size mismatch'
  614.         if size1 != (use_size>>3):
  615.             ospf = "66"
  616.         rmenc = RegMemEncode(reg1_num,size2,op2_type,op2_tail,reg2_num)
  617.         if type(rmenc) is str:
  618.             return rmenc
  619.         [mpf, mx, displabel, dispcode] = rmenc
  620.     elif arity == 2 and op2_type == 'reg':
  621.         if mnemonic == "MOV":
  622.             op_code = 0x89 - size2_bit
  623.         elif mnemonic in ["ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"]:
  624.             oper_code = index - 1          
  625.             op_code = (oper_code << 3) + 1 - size2_bit
  626.         elif mnemonic in ["ROL","ROR","RCL","RCR","SHL","SHR","SAR","SAL"]:
  627.             if reg2_num != 1 or size2 != 1:
  628.                 return 'Shift count must be CL or an immediate'
  629.             else:
  630.                 op_code = 0xd3 - size8_bit
  631.                 reg2_num = index- index_rol
  632.                 size2 = size1
  633.                 size1 = -1
  634.             if mnemonic == "SAL": reg2_num = 4
  635.         elif mnemonic in ["XCH","XCHG"]:
  636.             if op1_type == "reg" and reg1_num == 0 and size8_bit==0 :
  637.                 op_code = 0x90 + reg2_num
  638.                 reg2_num = -1
  639.             else:
  640.                 op_code = 0x87 - size8_bit
  641.         elif mnemonic in ["BT","BTS","BTR","BTC"]:
  642.             opc = "0F"
  643.             op_code = 0xa3 + ((index - index_bt) << 3)
  644.         elif  mnemonic == "TEST":
  645.             op_code = 0x85 - size2_bit
  646.         elif  mnemonic == "XADD":
  647.             opc = "0F"
  648.             op_code = 0xc1 - size2_bit
  649.         elif  mnemonic == "CMPXCHG":
  650.             opc = "0F"
  651.             op_code = 0xa7 - size2_bit
  652.         elif  mnemonic == "IN":
  653.             if reg2_num != 2 or size2 != 2: # DX
  654.                 return 'Port must be DX or an immediate byte'
  655.             elif op1_type != "reg" or reg1_num != 0:
  656.                 return 'First argument is AL, AX, or EAX'
  657.             else:
  658.                 op_code = 0xed - size8_bit
  659.                 reg2_num = -1
  660.                 size2 = size1
  661.                 size1 = -1
  662.         elif  mnemonic == "OUT":
  663.             if reg2_num != 0:               # EAX
  664.                 return 'Second argument is AL, AX, or EAX'
  665.             elif op1_type != "reg" or reg1_num != 2 or size1 != 2: # DX
  666.                 return 'Port must be DX or an immediate byte'
  667.             else:
  668.                 op_code = 0xef - size2_bit
  669.                 reg2_num = -1
  670.                 size1 = -1
  671.         elif mnemonic == "ARPL":
  672.             if size2 != 2:
  673.                 return '16 bit arguments needed'
  674.             else:
  675.                 op_code = 0x63
  676.                 size2 = -1
  677.         else:
  678.             return 'Register not allowed as second argument'
  679.         if size1 > 0 and size2 > 0 and size1 != size2:
  680.             return 'Operand size mismatch'
  681.         if size2 > 1 and size2 != (use_size >> 3):
  682.             ospf = "66"
  683.         rmenc = RegMemEncode(reg2_num,size1,op1_type,op1_tail,reg1_num)
  684.         if type(rmenc) is str:
  685.             return rmenc
  686.         [mpf, mx, displabel, dispcode] = rmenc
  687.     elif arity == 2:        #op2_type == 'mem'
  688.         if mnemonic == "MOV":
  689.             op_code = 0x8b - size8_bit
  690.         elif mnemonic in ["ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"]:
  691.             oper_code = index - 1          
  692.             op_code = (oper_code << 3) + 3 - size8_bit
  693.         elif mnemonic in ["ROL","ROR","RCL","RCR","SHL","SHR","SAR","SAL"]:
  694.             return 'Shift count must be CL or an immediate'
  695.         elif mnemonic in ["XCH","XCHG"]:
  696.             if op1_type != "reg":
  697.                 return 'First operand must be a register'
  698.             op_code = 0x87 - size8_bit
  699.         elif mnemonic == "LEA":
  700.             if size8_bit == 1:
  701.                 return "Addresses can't be 8 bits"
  702.             op_code = 0x8d
  703.         elif mnemonic == "TEST":
  704.             op_code = 0xf6
  705.         elif mnemonic == "BOUND":
  706.             op_code = 0x62
  707.         elif mnemonic == "LDS":
  708.             op_code = 0xc5
  709.         elif mnemonic == "LES":
  710.             op_code = 0xc4
  711.         elif mnemonic == "LFS":
  712.             op_code = 0xb4
  713.         elif mnemonic == "LGS":
  714.             op_code = 0xb5
  715.         elif mnemonic == "LSS":
  716.             op_code = 0xb2
  717.         elif mnemonic == "IN":
  718.             return 'Port must be DX or an immediate byte'
  719.         elif mnemonic == "OUT":
  720.             return 'Second operand must be AL,AX, or EAX'
  721.         else:
  722.             return "Second operand can't be memory"
  723.         if size2 > 0 and size1 != size2:
  724.             return 'Operand size mismatch'
  725.         if size1 > 1 and size1 != (use_size >> 3):
  726.             ospf = "66"
  727.         rmenc = RegMemEncode(reg1_num,size2,op2_type,op2_tail,reg2_num)
  728.         if type(rmenc) is str:
  729.             return rmenc
  730.         [mpf, mx, displabel, dispcode] = rmenc
  731.     elif arity == 1 and op1_type == "reg" and size1 == 5:
  732.         if mnemonic == "PUSH":
  733.             if op1_tail == "DS":
  734.                 op_code = 0x1e
  735.             elif op1_tail == "ES":
  736.                 op_code = 0x6
  737.             elif op1_tail == "CS":
  738.                 op_code = 0xe
  739.             elif op1_tail == "SS":
  740.                 op_code = 0x16
  741.             elif op1_tail == "FS":
  742.                 opc = "0F"
  743.                 op_code = 0xa0
  744.             elif op1_tail == "GS":
  745.                 opc = "0F"
  746.                 op_code = 0xa8
  747.         elif mnemonic == "POP":
  748.             if op1_tail == "DS":
  749.                 op_code = 0x1f
  750.             elif op1_tail == "ES":
  751.                 op_code = 0x7
  752.             elif op1_tail == "CS":
  753.                 return "Can't pop CS"
  754.             elif op1_tail == "SS":
  755.                 op_code = 0x17
  756.             elif op1_tail == "FS":
  757.                 opc = "0F"
  758.                 op_code = 0xa1
  759.             elif op1_tail == "GS":
  760.                 opc = "0F"
  761.                 op_code = 0xa9
  762.     elif arity == 1 and op1_type == 'reg' and size1 > 1 and\
  763.         mnemonic in ["INC","DEC","POP","PUSH","BSWAP"]:
  764.         if mnemonic == "INC":
  765.             op_code = 0x40 + reg1_num
  766.         elif mnemonic == "DEC":
  767.             op_code = 0x48 + reg1_num
  768.         elif mnemonic == "PUSH":
  769.             op_code = 0x50 + reg1_num
  770.         elif mnemonic == "POP":
  771.             op_code = 0x58 + reg1_num
  772.         elif mnemonic == "BSWAP":
  773.             opc = "0F"
  774.             op_code = 0xc8 + reg1_num
  775.             if size1 < 4:
  776.                 return '32 bits only'
  777.         if size1 != (use_size >> 3):
  778.             ospf = "66"
  779.         mx = ''
  780.     elif arity == 1 and mnemonic.startswith("SET"):
  781.         if op1_type == "imm":
  782.             return 'First operand must be register or memory'
  783.         if size1 > 1:
  784.             return 'Set just one byte'
  785.         opc = "0F"
  786.         op_code = 0x90 + index - index_seto
  787.         if op_code > 0xa0:
  788.             op_code = op_code - 0x10
  789.         reg_bits = 0
  790.         rmenc = RegMemEncode(reg_bits,size1,op1_type,op1_tail,reg1_num)
  791.         if type(rmenc) is str:
  792.             return rmenc
  793.         [mpf, mx, displabel, dispcode] = rmenc
  794.     elif arity == 1 and op1_type == 'imm':
  795.         if label1 == '' :
  796.             if mnemonic == "PUSH":
  797.                 if oneb1:
  798.                     op_code = 0x6a
  799.                     immc = ImmEncode(value1,-1)
  800.                 elif use_size == 16:
  801.                     op_code = 0x68
  802.                     immc = ImmEncode(value1,2)
  803.                 else:
  804.                     op_code = 0x68
  805.                     immc = ImmEncode(value1,4)
  806.             elif mnemonic in ["RET","RETN"]:
  807.                     op_code = 0xc2
  808.                     immc = ImmEncode(value1,2)
  809.             elif mnemonic == "RETF":
  810.                     op_code = 0xca
  811.                     immc = ImmEncode(value1,2)
  812.             elif mnemonic == "INT":
  813.                 if value1 == 3:
  814.                     op_code = 0xcc
  815.                     immc = ''
  816.                 else:
  817.                     op_code = 0xcd
  818.                     immc = ImmEncode(value1,1)
  819.             elif mnemonic in ["MUL","DIV","IDIV","POP","INC","DEC","NOT","NEG"]:
  820.                 return 'Argument must be register or memory'
  821.             else:
  822.                 return 'Label needed'
  823.         else:
  824.             if use_size == 32:
  825.                 immc = ImmEncode(value1,-4)
  826.                 dispcode = 0xd
  827.             elif use_size == 16:
  828.                 immc = ImmEncode(value1,-2)
  829.                 dispcode = 0xb
  830.             displabel = label1
  831.             if mnemonic == "PUSH":
  832.                 op_code = 0x68
  833.                 if use_size == 16:
  834.                     dispcode = 2
  835.                 elif use_size == 32:
  836.                     dispcode = 4
  837.             elif mnemonic in  ["JO", "JNO", "JB", "JAE", "JE", "JNE", "JBE", "JA", "JS", "JNS", "JL", "JGE", "JLE", "JG"]:
  838.                 op_code = 0x80 + index  - index_jo
  839.                 opc = "0F"
  840.             elif mnemonic in ["JNAE", "JNB", "JZ", "JNZ", "JNA", "JNBE", "JNGE", "JNL", "JNG", "JNLE"]:
  841.                 op_code = 0x80 + index  - index_jo - 16
  842.                 opc = "0F"
  843.             elif mnemonic in ["JC","JNC"]:
  844.                 op_code = 0x80 + index  - index_jo - 32
  845.                 opc = "0F"
  846.             elif mnemonic == "JMP":
  847.                 op_code = 0xe9
  848.             elif mnemonic == "CALL":
  849.                 op_code = 0xe8
  850.             elif mnemonic == "JMPF":
  851.                 op_code = 0xea
  852.             elif mnemonic == "CALLF":
  853.                 op_code = 0x9a
  854.             elif mnemonic in ["RET", "RETN", "RETF", "INT"]:
  855.                 return 'Argument may be an immediate but not a label'
  856.             elif mnemonic in ["LOOPNZ", "LOOPNE"]:
  857.                 op_code = 0xe0
  858.                 immc  = '00'
  859.                 dispcode = 9
  860.             elif mnemonic in ["LOOPZ", "LOOPE"]:
  861.                 op_code = 0xe1
  862.                 immc  = '00'
  863.                 dispcode = 9
  864.             elif mnemonic  == "LOOP":
  865.                 op_code = 0xe2
  866.                 immc  = '00'
  867.                 dispcode = 9
  868.             elif mnemonic == "JECXZ":
  869.                 op_code = 0xe3
  870.                 if use_size == 16:
  871.                     opc = "66"
  872.                 immc  = '00'
  873.                 dispcode = 9
  874.             elif mnemonic == "JCXZ":
  875.                 op_code = 0xe3
  876.                 if use_size == 32:
  877.                     opc = "66"
  878.                 immc  = '00'
  879.                 dispcode = 9
  880.             else:
  881.                 return 'Argument must be register or memory'
  882.         mx = ''
  883.     elif arity == 1:
  884.         if size1 > 1 and size1 != (use_size >> 3):
  885.             ospf = "66"
  886.         if mnemonic == "INC":
  887.             reg_bits = 0
  888.             op_code = 0xff - size8_bit
  889.         elif mnemonic == "DEC":
  890.             reg_bits = 1
  891.             op_code = 0xff - size8_bit
  892.         elif mnemonic == "NOT":
  893.             reg_bits = 2
  894.             op_code = 0xf7 - size8_bit
  895.         elif mnemonic == "NEG":
  896.             reg_bits = 3
  897.             op_code = 0xf7 - size8_bit
  898.         elif mnemonic == "MUL":
  899.             reg_bits = 4
  900.             op_code = 0xf7 - size8_bit
  901.         elif mnemonic == "IMUL":
  902.             reg_bits = 5
  903.             op_code = 0xf7 - size8_bit
  904.         elif mnemonic == "DIV":
  905.             reg_bits = 6
  906.             op_code = 0xf7 - size8_bit
  907.         elif mnemonic == "IDIV":
  908.             reg_bits = 7
  909.             op_code = 0xf7 - size8_bit
  910.         elif mnemonic == "PUSH":
  911.             reg_bits = 6
  912.             op_code = 0xff
  913.         elif mnemonic == "POP":
  914.             reg_bits = 0
  915.             op_code = 0x8f
  916.         elif mnemonic == "JMP":
  917.             reg_bits = 4
  918.             op_code = 0xff
  919.         elif mnemonic == "CALL":
  920.             reg_bits = 2
  921.             op_code = 0xff
  922.         elif mnemonic == "JMPF":
  923.             reg_bits = 5
  924.             op_code = 0xff
  925.         elif mnemonic == "CALLF":
  926.             reg_bits = 3
  927.             op_code = 0xff
  928.         # The following op codes get prefixed by 0F
  929.         elif mnemonic == "SLDT":
  930.             reg_bits = 0
  931.             op_code = 0
  932.         elif mnemonic == "STR":
  933.             reg_bits = 1
  934.             op_code = 0
  935.         elif mnemonic == "LLDT":
  936.             reg_bits = 2
  937.             op_code = 0
  938.         elif mnemonic == "LTR":
  939.             reg_bits = 3
  940.             op_code = 0
  941.         elif mnemonic == "VERR":
  942.             reg_bits = 4
  943.             op_code = 0
  944.         elif mnemonic == "VERW":
  945.             reg_bits = 5
  946.             op_code = 0
  947.         elif mnemonic == "SGDT":
  948.             reg_bits = 0
  949.             op_code = 1
  950.         elif mnemonic == "SIDT":
  951.             reg_bits = 1
  952.             op_code = 1
  953.         elif mnemonic == "LGDT":
  954.             reg_bits = 2
  955.             op_code = 1
  956.         elif mnemonic == "LIDT":
  957.             reg_bits = 3
  958.             op_code = 1
  959.         elif mnemonic == "SMSW":
  960.             reg_bits = 4
  961.             op_code = 1
  962.         elif mnemonic == "LMSW":
  963.             reg_bits = 6
  964.             op_code = 1
  965.         elif mnemonic == "INVLPG":
  966.             reg_bits = 7
  967.             op_code = 1
  968.         if op_code in [0,1]:
  969.             opc = "0F"
  970.             if size1 != 2:
  971.                 return 'Operand must be 2 bytes'
  972.             else:
  973.                 ospf = ''
  974.         if size1 == 1 and mnemonic in ["PUSH","POP"]:
  975.             return "Can't push or pop single bytes"
  976.         if op1_type == "reg" and mnemonic in ["SGDT", "SIDT","LIDT", "LGDT"]:
  977.             return 'Takes memory operand only'
  978.         if reg_bits > -1:
  979.             rmenc = RegMemEncode(reg_bits,size1,op1_type,op1_tail,reg1_num)
  980.             if type(rmenc) is str:
  981.                 return rmenc
  982.             [mpf, mx, displabel, dispcode] = rmenc
  983.         else:
  984.             mx = ''
  985.     elif arity == 0:
  986.         if code:
  987.             return "argument '" + code + "' given to " + mnemonic
  988.  
  989.         if  prefix == "REP":
  990.             if mnemonic[:3] in ["CMP","SCA"]:
  991.                 return prefix + mnemonic + ' invalid combination'  
  992.         elif prefix in ["REPE","REPNE"]:
  993.             if mnemonic[:3] not in ["CMP","SCA"]:
  994.                 return prefix + mnemonic + ' invalid combination'  
  995.  
  996.         if mnemonic == "AAA":
  997.             op_code = 0x37
  998.         elif mnemonic == "AAD":
  999.             opc = "D5"
  1000.             op_code = 0xa
  1001.         elif mnemonic == "AAM":
  1002.             opc = "D4"
  1003.             op_code = 0xa
  1004.         elif mnemonic == "AAS":
  1005.             op_code = 0x3f
  1006.         elif mnemonic == "CBW":
  1007.             op_code = 0x98
  1008.             if use_size == 32:
  1009.                 opc = "66"
  1010.         elif mnemonic == "CWDE":
  1011.             op_code = 0x98
  1012.             if use_size == 16:
  1013.                 opc = "66"
  1014.         elif mnemonic == "CDQ":
  1015.             op_code = 0x99
  1016.             if use_size == 16:
  1017.                 opc = "66"
  1018.         elif mnemonic == "CWD":
  1019.             op_code = 0x99
  1020.             if use_size == 32:
  1021.                 opc = "66"
  1022.         elif mnemonic == "CLC":
  1023.             op_code = 0xf8
  1024.         elif mnemonic == "CLD":
  1025.             op_code = 0xfc
  1026.         elif mnemonic == "CLI":
  1027.             op_code = 0xfa
  1028.         elif mnemonic == "CLTS":
  1029.             opc = "0F"
  1030.             op_code = 0x6
  1031.         elif mnemonic == "CMC":
  1032.             op_code = 0xf5
  1033.         elif mnemonic == "CMPSB":
  1034.             op_code = 0xa6
  1035.         elif mnemonic == "CMPSW":
  1036.             op_code = 0xa7
  1037.             if use_size == 32:
  1038.                 opc = "66"
  1039.         elif mnemonic == "CMPSD":
  1040.             op_code = 0xa7
  1041.             if use_size == 16:
  1042.                 opc = "66"
  1043.         elif mnemonic == "CWD":
  1044.             op_code = 0x99
  1045.             if use_size == 32:
  1046.                 opc = "66"
  1047.         elif mnemonic == "CWDE":
  1048.             op_code = 0x98
  1049.             if use_size == 16:
  1050.                 opc = "66"
  1051.         elif mnemonic == "DAA":
  1052.             op_code = 0x27
  1053.         elif mnemonic == "DAS":
  1054.             op_code = 0x2f
  1055.         elif mnemonic == "HLT":
  1056.             op_code = 0xf4
  1057.         elif mnemonic == "INSB":
  1058.             op_code = 0x6c
  1059.         elif mnemonic == "INSW":
  1060.             op_code = 0x6d
  1061.             if use_size == 32:
  1062.                 opc = "66"
  1063.         elif mnemonic == "INSD":
  1064.             op_code = 0x6d
  1065.             if use_size == 16:
  1066.                 opc = "66"
  1067.         elif mnemonic == "INTO":
  1068.             op_code = 0xce
  1069.         elif mnemonic == "INVD":
  1070.             opc = "0F"
  1071.             op_code = 0x8
  1072.         elif mnemonic in ["IRET","IRETD"]:
  1073.             op_code = 0xcf
  1074.         elif mnemonic == "LAHF":
  1075.             op_code = 0x9f
  1076.         elif mnemonic == "LEAVE":
  1077.             op_code = 0x9
  1078.         elif mnemonic == "LOADALL286":
  1079.             opc = "0F"
  1080.             op_code = 0x5
  1081.         elif mnemonic == "LODSB":
  1082.             op_code = 0xac
  1083.         elif mnemonic == "LODSW":
  1084.             op_code = 0xad
  1085.             if use_size == 32:
  1086.                 opc = "66"
  1087.         elif mnemonic == "LODSD":
  1088.             op_code = 0xad
  1089.             if use_size == 16:
  1090.                 opc = "66"
  1091.         elif mnemonic == "MOVSB":
  1092.             op_code = 0xa4
  1093.         elif mnemonic == "MOVSW":
  1094.             op_code = 0xa5
  1095.             if use_size == 32:
  1096.                 opc = "66"
  1097.         elif mnemonic == "MOVSD":
  1098.             op_code = 0xa5
  1099.             if use_size == 16:
  1100.                 opc = "66"
  1101.         elif mnemonic == "NOP":
  1102.             op_code = 0x90
  1103.         elif mnemonic == "OUTSB":
  1104.             op_code = 0x6e
  1105.         elif mnemonic == "OUTSW":
  1106.             op_code = 0x6f
  1107.             if use_size == 32:
  1108.                 opc = "66"
  1109.         elif mnemonic == "OUTSD":
  1110.             op_code = 0x6f
  1111.             if use_size == 16:
  1112.                 opc = "66"
  1113.         elif mnemonic in ["POPA","POPD"]:
  1114.             op_code = 0x61
  1115.         elif mnemonic == "POPF":
  1116.             op_code = 0x9d
  1117.             if use_size == 32:
  1118.                 oc = "66"
  1119.         elif mnemonic == "POPFD":
  1120.             op_code = 0x9d
  1121.             if use_size == 16:
  1122.                 oc = "66"
  1123.         elif mnemonic in ["PUSHA","PUSHAD"]:
  1124.             op_code = 0x60
  1125.         elif mnemonic == "PUSHF":
  1126.             op_code = 0x9c
  1127.             if use_size == 32:
  1128.                 oc = "66"
  1129.         elif mnemonic == "PUSHFD":
  1130.             op_code = 0x9c
  1131.             if use_size == 16:
  1132.                 oc = "66"
  1133.         elif mnemonic in ["RET","RETN"]:
  1134.             op_code = 0xc3
  1135.         elif mnemonic == "RETF":
  1136.             op_code = 0xcb
  1137.         elif mnemonic == "SAHF":
  1138.             op_code = 0x9e
  1139.         elif mnemonic == "SCASB":
  1140.             op_code = 0xae
  1141.         elif mnemonic == "SCASW":
  1142.             op_code = 0xaf
  1143.             if use_size == 32:
  1144.                 oc = "66"
  1145.         elif mnemonic == "SCASD":
  1146.             op_code = 0xaf
  1147.             if use_size == 16:
  1148.                 oc = "66"
  1149.         elif mnemonic == "STC":
  1150.             op_code = 0xf9
  1151.         elif mnemonic == "STD":
  1152.             op_code = 0xfd
  1153.         elif mnemonic == "STI":
  1154.             op_code = 0xfb
  1155.         elif mnemonic == "STOSB":
  1156.             op_code = 0xaa
  1157.         elif mnemonic == "STOSW":
  1158.             op_code = 0xab
  1159.             if use_size == 32:
  1160.                 oc = "66"
  1161.         elif mnemonic == "STOSD":
  1162.             op_code = 0xab
  1163.             if use_size == 16:
  1164.                 oc = "66"
  1165.         elif mnemonic == "WAIT":
  1166.             op_code = 0x9b
  1167.         elif mnemonic == "WBINVD":
  1168.             opc = "0F"
  1169.             op_code = 0x9
  1170.         elif mnemonic == "XLATB":
  1171.             op_code = 0xd7
  1172.         mx = ''
  1173.        
  1174.        
  1175.     if op_code > -1:
  1176.         opc = opc + "%02X" % op_code
  1177.     else:
  1178.         opc = ''
  1179.     if displabel:
  1180.         dispcode = (len(immc)<< 3) + dispcode
  1181.         dispcode = dispcode | 8
  1182.     else:
  1183.         dispcode = 0
  1184.    
  1185.     packed_op = '' 
  1186.     hx = rlpf + ospf  + mpf + opc + mx + immc
  1187.     return (packed_op, displabel, dispcode, hx)
  1188.  
  1189. register_list = ["EAX","ECX","EDX","EBX","ESP","EBP","ESI","EDI","AX","CX","DX","BX","SP","BP","SI","DI","AL","CL","DL","BL","AH","CH","DH","BH","ES","CS","SS","DS","FS","GS","LDT","TSS","DR0","DR1","DR2","DR3","DR4","DR5","DR6","DR7","TR0","TR1","TR2","TR3","TR4","TR5","TR6","TR7","CR0","CR1","CR2","CR3","CR4"]
  1190.  
  1191. def OperandParse(op):
  1192.     op = op.strip()
  1193.    
  1194.     n_bytes = -1
  1195.     if op.upper() in register_list:
  1196.         reg_num = register_list.index(op.upper())
  1197.     else:
  1198.         reg_num = -1
  1199.  
  1200.     if reg_num > -1:
  1201.         optype = "reg"
  1202.         if reg_num < 8:
  1203.             n_bytes = 4
  1204.         elif reg_num < 16:
  1205.             n_bytes = 2
  1206.         elif reg_num < 24:
  1207.             n_bytes = 1
  1208.         else:
  1209.             n_bytes = ((reg_num - 24) >> 3) + 5 # Just a code, not really a size.
  1210.         reg_num = reg_num & 7
  1211.         if reg_num > 5 and n_bytes == 5:            # LDT and TSS
  1212.             return op + ' not addressable'
  1213.     elif "[" in op:
  1214.         optype = "mem"
  1215.         if op.upper().startswith('BYTE'):
  1216.             n_bytes = 1
  1217.             op = op[4:].lstrip()
  1218.         elif op.upper().startswith('2BYTE'):
  1219.             n_bytes = 2
  1220.             op = op[5:].lstrip()
  1221.         elif op.upper().startswith('WORD'):
  1222.             n_bytes = 2
  1223.             op = op[4:].lstrip()
  1224.         elif op.upper().startswith('4BYTE'):
  1225.             n_bytes = 4
  1226.             op = op[5:].lstrip()
  1227.         elif op.upper().startswith('DWORD'):
  1228.             n_bytes = 4
  1229.             op = op[5:].lstrip()
  1230.         if op.upper().startswith('PTR'):
  1231.             op = op[4:].lstrip()
  1232.         if op.find(':') == 2:
  1233.             sreg = op[:2].upper()
  1234.             if sreg in register_list:
  1235.                 sreg_num =  register_list.index(sreg)
  1236.                 if 24 <= sreg_num < 30:
  1237.                     reg_num = sreg_num - 24
  1238.                     op = op[3:].lstrip()
  1239.                 else:
  1240.                     return sreg + ' not a segment register'
  1241.             else:
  1242.                 return sreg + ' not a segment register'
  1243.     else:
  1244.         optype = "imm"
  1245.     return [optype,op,reg_num,n_bytes]
  1246.  
  1247. def RegMemEncode(reg_bits, reg_size, rm_type, rm, mem_bits):
  1248.     label = ''
  1249.     dispcode = 0
  1250.     if reg_bits == -1:
  1251.         pf = ''
  1252.         mx = ''
  1253.     elif rm_type == "reg":
  1254.         pf = ''
  1255.         mx = "%02X" % (0xc0 + (reg_bits<<3) + mem_bits)
  1256.     else:
  1257.         ma = MemAssemble(reg_bits, reg_size, rm_type, rm, mem_bits)
  1258.         if type(ma) is str:
  1259. #           print ma + ' is a string'
  1260. #           raise SystemExit   
  1261.             return ma
  1262.         [pf, mx, label, dispcode, sreg] = ma
  1263. #       print "mem_bits = ",mem_bits
  1264. #       print "sreg = ",sreg
  1265.         pf = pf + SegPref(mem_bits, sreg)
  1266.     return [pf, mx, label, dispcode]
  1267.  
  1268. def MemAssemble(reg_bits, reg_size, rm_type, rm, sgreg):
  1269.     left_end = rm.find("[")
  1270.     right_end = rm.rfind("]")
  1271.     rm = rm[left_end + 1:right_end]
  1272.  
  1273.     scale = 1
  1274.     ind_reg = -1
  1275.     base_reg1 = -1
  1276.     base_reg2 = -1
  1277.     additive_constant = 0
  1278.     lbl = ''
  1279.  
  1280.     start = 0
  1281.     paren_depth = 0
  1282.     term_in_midst = False
  1283.     sign_is_negative  = False
  1284.     old_sign_is_negative  = False
  1285.    
  1286.     while start < len(rm):
  1287. #       print "neg", sign_is_negative
  1288.         k = start
  1289.         c = ''
  1290.         while c not in ['+','-','*'] and k < len(rm):
  1291.             c = rm[k]
  1292.             k = k + 1
  1293.             if c == '(':
  1294.                 paren_depth = paren_depth + 1
  1295.             elif c == ')':
  1296.                 paren_depth = paren_depth - 1
  1297.             if paren_depth > 0:
  1298.                 c = ''
  1299.  
  1300.         if paren_depth != 0:
  1301.             return 'Unbalanced parentheses'
  1302.  
  1303.         if k == len(rm):
  1304.             x = rm[start:k].strip()
  1305.         else:
  1306.             x = rm[start:k-1].strip()
  1307.  
  1308.         start = k
  1309.    
  1310.         if x.upper() in register_list:
  1311.             reg_num = register_list.index(x.upper())
  1312.         else:
  1313.             reg_num = -1           
  1314.  
  1315.         if reg_num > 15:
  1316.             return 'Register must be 16 or 32 bit general register'
  1317.  
  1318.         if term_in_midst:  
  1319.             if reg_num >= 0 and ind_reg >= 0:
  1320.                 return "Registers can't be multiplied"
  1321.             elif reg_num >= 0:
  1322.                 ind_reg = reg_num
  1323.             else:
  1324.                 imp = Immparse(x)
  1325.                 if type(imp) is str:
  1326.                     return imp
  1327.                 inlbl, one_byte, value = imp
  1328.                 if inlbl:
  1329.                     return 'Labels not allowed in scale factor'
  1330.                 else:
  1331.                     scale = scale * value
  1332.             if c != '*':
  1333.                 if ind_reg < 0 and sign_is_negative:
  1334.                     additive_constant = additive_constant - scale
  1335.                     scale = 1
  1336.                 elif ind_reg < 0:
  1337.                     additive_constant = additive_constant + scale
  1338.                     scale = 1
  1339.                 elif scale not in [1,2,4,8]:
  1340.                     return 'Scale must be 1,2,4, or 8'
  1341.                 elif scale == 1:
  1342.                     if base_reg1 < 0:
  1343.                         base_reg1 = ind_reg
  1344.                         ind_reg = -1
  1345.                     elif base_reg2 < 0:
  1346.                         base_reg2 = ind_reg
  1347.                         ind_reg = -1
  1348.                     else:
  1349.                         return 'Maximum 2 registers'
  1350.                 term_in_midst = False
  1351.                 if c == '-':
  1352.                     return "Can't subtract products"
  1353.        
  1354.         elif c == '*':
  1355.             if reg_num >= 0 and ind_reg >= 0:
  1356.                 return 'Only 1 register can be scaled'
  1357.             elif reg_num >= 0:
  1358.                 ind_reg = reg_num
  1359.             else:
  1360.                 imp = Immparse(x)
  1361.                 if type(imp) is str:
  1362.                     return imp
  1363.                 inlbl, one_byte, value = imp
  1364.                 if inlbl:
  1365.                     return 'Labels not allowed in scale factor'
  1366.                 scale = scale * value
  1367.             term_in_midst = True
  1368.         else:
  1369.             if reg_num >= 0:
  1370.                 if base_reg1 < 0:
  1371.                     base_reg1 = reg_num
  1372.                 elif base_reg2 < 0:
  1373.                     base_reg2 = reg_num
  1374.                 else:
  1375.                     return 'Maximum 2 registers'
  1376.                 if sign_is_negative:
  1377.                     return "Can't subtract a register"
  1378.             else:
  1379.                 imp = Immparse(x)
  1380.                 if type(imp) is str:
  1381.                     return imp
  1382.                 inlbl, one_byte, value = imp
  1383. #               print("imp = ", imp)
  1384.                 if inlbl == '' and sign_is_negative:
  1385.                     additive_constant = additive_constant - value
  1386.                 elif inlbl == '':
  1387.                     additive_constant = additive_constant + value
  1388.                 elif lbl == '':
  1389.                     lbl = inlbl
  1390.             sign_is_negative = (c == '-')
  1391.                    
  1392. #
  1393. #   Check results
  1394. #
  1395.  
  1396.     if ind_reg >= 0 and base_reg1 >= 0 and base_reg2 >= 0:
  1397.         return 'At most two registers allowed'
  1398.     if ind_reg >= 16 or base_reg1 >= 16 or base_reg2 >= 16:
  1399.         return 'No one byte addresses'
  1400.     if ind_reg >= 0 and (base_reg1 >= 8 or base_reg2 >= 8):
  1401.         return 'Scaling used only in 32 bit addresses'
  1402.     if (0 <= base_reg1 < 8 and base_reg2 >= 8) or (0 <= base_reg2 < 8 and base_reg1 >= 8):
  1403.         return 'Conflicting address sizes'
  1404.     if 0 <= base_reg2 < 8:
  1405.         if sgreg == 2 and base_reg2 in [4,5]:  # SS and [ESP,EBP]
  1406.             base_reg1, base_reg2 = base_reg2, base_reg1
  1407.         elif sgreg == 3 and base_reg2 not in [4,5]: # DS and not [ESP,EBP]
  1408.             base_reg1, base_reg2 = base_reg2, base_reg1
  1409.         ind_reg, base_reg2 = base_reg2, ind_reg
  1410.         adlen = 32
  1411.     elif ind_reg >= 0:
  1412.         adlen = 32
  1413.     elif 0 <= base_reg1 < 8:
  1414.         adlen = 32
  1415.     elif 0 <= base_reg2:
  1416.         if base_reg2 in [11,13]:                # [BX, BP]
  1417.             base_reg1, base_reg2 = base_reg2, base_reg1
  1418.         if base_reg1 not in [11,13]:        # [BX, BP]
  1419.             return '16 bit base must be BX or BP'
  1420.         if base_reg2 not in [14,15]:        # [SI, DI]
  1421.             return '16 bit index must be SI or DI'
  1422.         ind_reg, base_reg2 = base_reg2, ind_reg
  1423.         adlen = 16
  1424.     elif base_reg1 >= 8:
  1425.         if base_reg1 < 11 or base_reg1 == 12:
  1426.             return 'Need BX, BP, SI, or DI'
  1427.         if base_reg1 in [14,15]:            #[SI,DI]
  1428.             ind_reg, base_reg1 = base_reg1, ind_reg
  1429.         adlen = 16
  1430.     elif base_reg1 >= 0:
  1431.         adlen = 32
  1432.     else:
  1433.         adlen = use_size
  1434.  
  1435.     if adlen != use_size:
  1436.         pf = "67"
  1437.     else:  
  1438.         pf = ''
  1439.  
  1440.     if additive_constant < -(1<<31) or additive_constant >= 1<< 32:
  1441.         return '32 bits Maximum'
  1442.     if adlen == 32:
  1443.         if lbl != '' or base_reg1 < 0:
  1444.             n_dbytes = 4
  1445.         elif additive_constant < -128 or additive_constant >= 128:
  1446.             n_dbytes = 4
  1447.         elif additive_constant != 0 or base_reg1 == 5:          # EBP
  1448.             n_dbytes = 1
  1449.         else:
  1450.             n_dbytes = 0
  1451.         if base_reg1 in [4,5]:                                          # ESP or EBP
  1452.             sreg = 2                                                            # SS
  1453.         else:
  1454.             sreg = 3                                                            # DS
  1455.         if ind_reg == 4:
  1456.             return "Index register can't be ESP"
  1457.         memb = MemEncode32(reg_bits, scale, base_reg1, ind_reg, n_dbytes)
  1458.     elif adlen == 16:
  1459.         if lbl != '' or base_reg1 < 0:
  1460.             n_dbytes = 2
  1461.         elif additive_constant < -128 or additive_constant >= 128:
  1462.             n_dbytes = 2
  1463.         elif additive_constant != 0 or (base_reg1 == 13 and ind_reg < 0):           # BP
  1464.             n_dbytes = 1
  1465.         else:
  1466.             n_dbytes = 0
  1467.         if base_reg1 == 13:                                             # BP
  1468.             sreg = 2                                                            # SS
  1469.         else:
  1470.             sreg = 3                                                            # DS
  1471.         memb = MemEncode16(reg_bits, base_reg1, ind_reg, n_dbytes)
  1472.  
  1473.     assert n_dbytes in [0,1,2,4]
  1474.  
  1475.     if n_dbytes != 0:
  1476.         disp = ImmEncode(additive_constant,- n_dbytes)
  1477.     else:
  1478.         disp = ''
  1479.  
  1480.     if n_dbytes == 0:
  1481.         dispcode = 0
  1482.     elif n_dbytes == 1:
  1483.         dispcode = 0
  1484.     elif n_dbytes == 2:
  1485.         dispcode = 2
  1486.     elif n_dbytes == 4:
  1487.         dispcode = 4
  1488.    
  1489.     dispcode = dispcode + (n_dbytes<<4)
  1490.     mx = memb + disp
  1491.  
  1492.     return [pf, mx, lbl, dispcode, sreg]
  1493.        
  1494. def SegPref(specified, encoded):
  1495.     if specified == -1 or specified == encoded:
  1496.         return ''
  1497.     if specified == 1:          # CS
  1498.         return "2E"
  1499.     if specified == 3:          # DS
  1500.         return "1E"
  1501.     if specified == 0:          # ES
  1502.         return "26"
  1503.     if specified == 4:          # FS
  1504.         return "64"
  1505.     if specified == 5:          # GS
  1506.         return "65"
  1507.     if specified == 2:          # SS
  1508.         return "36"
  1509.     raise ValueError("specified, encoded = " + str(specified) + str(encoded))
  1510.  
  1511. def Immparse(op):
  1512.    
  1513.     if identifp.match(op):
  1514.         if op in program_env:
  1515.             value = program_env[op]
  1516.             if type(value) is str:
  1517.                 return op + ' must be defined as an integer'
  1518.             if -128 <= value < 128:
  1519.                 return ['',1,value]
  1520.             else:
  1521.                 return ['',0,value]
  1522.         else:
  1523.             return [op,0,0]
  1524.  
  1525.     if op.startswith('(') and op.endswith(')'):
  1526.         return Immparse(op[1:-1])
  1527.  
  1528.     nump = Numparse(op)
  1529.     if type(nump) is int:  
  1530.         if -128 <= nump < 256:
  1531. #       if -128 <= nump < 128:
  1532.             return ['',1,nump]
  1533.         else:
  1534.             return ['',0,nump]
  1535.     elif type(nump) is int:
  1536.         if -0x80000000 <= nump < 0x100000000:
  1537.             return ['',0,nump]
  1538.         else:
  1539.             return op + ' not a valid 4 byte number'
  1540.  
  1541.     if '+' not in op and '-' not in op and '*' not in op:
  1542.         return op + ' not a valid immediate expression'
  1543.  
  1544.     m = mainsplit(op,['+','-'])
  1545.     label = ''
  1546.     if len(m) > 2:
  1547.         eval_list = []
  1548.         for k in range(0,len(m),2):
  1549.             if m[k]:
  1550.                 imp = Immparse(m[k])
  1551.                 if type(imp) is str:
  1552.                     return imp
  1553.                 outlabel,single_byte,val = imp
  1554.                 if label and outlabel:
  1555.                     return 'Only one label allowed'
  1556.                 if outlabel:
  1557.                     label = outlabel
  1558.                 eval_list.append(str(val))
  1559.                 eval_list.append(m[k+1])
  1560.             else:
  1561.                 eval_list.append(m[k+1])
  1562.         eval_list.pop()
  1563.         try:
  1564.             retval = eval(''.join(eval_list))
  1565.         except:
  1566.             return 'Bad expression'
  1567.         if -128 <= retval < 128:
  1568.             return [label,1,retval]
  1569.         else:
  1570.             return [label,0,retval]
  1571.     m = mainsplit(op,['*'])
  1572.        
  1573.     if len(m) > 1
  1574.         retval = 1
  1575.         for k in range(0,len(m),2):
  1576.             if m[k] == '':
  1577.                 return 'Bad multiplicative expression'
  1578.             imp = Immparse(m[k])
  1579.             if type(imp) is str:
  1580.                 return imp
  1581.             outlabel,single_byte,val = imp
  1582.             if outlabel:
  1583.                 return 'No multiplicative labels'
  1584.             retval = val * retval
  1585.         if -128 <= retval < 128:
  1586.             return ['',1,retval]
  1587.         else:
  1588.             return ['',0,retval]
  1589.  
  1590. def Numparse(num_string):
  1591.     if num_string.startswith('-'):
  1592.         num_string= num_string[1:]
  1593.         sign = -1
  1594.     else:
  1595.         sign = 1
  1596.     if num_string.endswith('H') or num_string.endswith('h'):
  1597.         num_string= num_string[:-1]
  1598.         try:
  1599.             val = int(num_string,16)
  1600.         except:
  1601.             return 'Invalid integer'
  1602.     elif num_string.startswith('0x') or num_string.startswith('0X'):
  1603.         try:
  1604.             val = int(num_string,16)
  1605.         except:
  1606.             return 'Invalid integer'
  1607.     elif num_string.startswith('0'):
  1608.         try:
  1609.             val = int(num_string,8)
  1610.         except:
  1611.             return 'Invalid integer'
  1612.     elif num_string.isdigit():
  1613.         val = int(num_string)
  1614.     else:
  1615.         return 'Invalid integer'
  1616.     val = sign * val
  1617.     return val
  1618.  
  1619. def mainsplit(expression,oplist):
  1620.     paren_depth = 0
  1621.     retlist = []
  1622.    
  1623.     last_i = -1
  1624.     for i,x in enumerate(expression + oplist[0]):
  1625.         if x == '(':
  1626.             paren_depth = paren_depth + 1
  1627.         elif x == ')':
  1628.             paren_depth = paren_depth - 1
  1629.         if paren_depth  == 0 and x in oplist:
  1630.             y = expression[last_i + 1:i].strip()
  1631.             last_i = i
  1632.             retlist.append(y)
  1633.             retlist.append(x)
  1634.     return retlist
  1635.    
  1636. def MemEncode32(reg_num, scale, base_reg, ind_reg, n_dbytes):
  1637.  
  1638. #     REG.NUM is /r.   This may or may not code a register.
  1639. #     BASE.REG is the base register.  -1 if there is none.
  1640. #     IND.REG is the index register.  -1 if there is none.
  1641. #     N.DBYTES is the number of displacement bytes to follow.
  1642. #   print (reg_num, scale, base_reg, ind_reg, n_dbytes)
  1643.     sib = -1            # Default for no SIB byte.
  1644.    
  1645.     if n_dbytes == 4:
  1646.         disp_bits = 2
  1647.     elif n_dbytes == 1:
  1648.         disp_bits = 1
  1649.     elif n_dbytes == 0:
  1650.         disp_bits = 0
  1651.  
  1652.     if scale == 8:
  1653.         scale_bits = 3
  1654.     elif scale == 4:
  1655.         scale_bits = 2
  1656.     elif scale == 2:
  1657.         scale_bits = 1
  1658.     elif scale == 1:
  1659.         scale_bits = 0
  1660.  
  1661.     assert ind_reg != 4                 # 4 = ESP  
  1662.     assert base_reg != 5 or n_dbytes != 0 #5 = EBP
  1663.     assert base_reg != -1 or not(n_dbytes == 0 or n_dbytes == 1)
  1664.     # This case should be blocked in MemAssemble
  1665.  
  1666.     if ind_reg >= 0 and base_reg >= 0:
  1667.         rm = (disp_bits << 6) + (reg_num << 3) + 4      #4 = ESP
  1668.         sib = (scale_bits << 6) + (ind_reg << 3) + base_reg
  1669.     elif base_reg == 4:                                 #4 = EBP
  1670.         rm = (disp_bits << 6) + (reg_num << 3) + base_reg
  1671.         sib = 0x24
  1672.     elif ind_reg >= 0:
  1673.         rm = (0 << 6) + (reg_num << 3) +  4     # 4 = ESP
  1674.         sib = (scale_bits << 6) + (ind_reg << 3) +  5               #5 = EBP
  1675.     elif base_reg >= 0:
  1676.         rm = (disp_bits << 6) + (reg_num << 3) + base_reg
  1677.     else:
  1678.         rm = (0 << 6) + (reg_num << 3) + 5              #5 = EBP
  1679.  
  1680.     if sib == -1:
  1681.         return "%02X" % rm
  1682.     else:  
  1683.         return "%02X" % rm + "%02X" % sib
  1684.  
  1685. def MemEncode16(reg_num, base_reg, ind_reg, n_dbytes):
  1686.  
  1687.     disp_bits = n_dbytes
  1688.     assert n_dbytes != 0 or base_reg != 13 or ind_reg >= 0
  1689.  
  1690.     if ind_reg < 0:         # BX or BP
  1691.         parity = (13 - base_reg) >> 1       # 13 = BP
  1692.     else:
  1693.         parity = ind_reg - 14               # 14 = SI
  1694.  
  1695.     if ind_reg < 0 and base_reg < 0:
  1696.         mem_bits = 6
  1697.         rm = (reg_num << 3) + mem_bits
  1698.     else:
  1699.         if ind_reg < 0:
  1700.             mid_num = 3
  1701.         elif base_reg < 0:
  1702.             mid_num = 2
  1703.         else:
  1704.             mid_num = (base_reg - 11)>>1    # 11 = BX
  1705.         mem_bits = (mid_num << 1)  + parity
  1706.         rm = (disp_bits << 6) + (reg_num << 3) + mem_bits
  1707.  
  1708.     return "%02X" % rm
  1709.  
  1710. def ImmEncode(value, n_bytes):
  1711.  
  1712.     if n_bytes < 0:
  1713.         n_bytes = -n_bytes
  1714.         if value < 0:
  1715.             if n_bytes == 1:
  1716.                 value = value + 256
  1717.             elif n_bytes == 2:
  1718.                 value = value + 65536
  1719.             else:
  1720.                 value = value + 0x100000000
  1721.     if n_bytes == 1:
  1722.         return "%02X" % value
  1723.     elif n_bytes == 2:
  1724.         return "%02X" % (value & 255) + "%02X" % (value >> 8)
  1725.     else:
  1726.         return "%02X" % (value & 255) + "%02X" % (255 &(value >> 8)) + "%02X" % (255 &(value >> 16)) + "%02X" % (value >> 24)
  1727.  
  1728.  
  1729. ##################################################################
  1730. #
  1731. # Fetch Execute Section
  1732. #
  1733. ##################################################################
  1734.  
  1735. #
  1736. #  Reading and Writing to Memory
  1737. #
  1738.  
  1739. def lg_read(segment_register, offset, n_bytes):
  1740. # See Agarwal pp 73-74
  1741.     desc = descrVec[segment_register]
  1742.     if desc.Valid.getValue() and desc.Readable.getValue() and in_limits(desc, offset, n_bytes):
  1743.         return LA_read((desc.Base.getValue() + offset) & 0xffffffff , n_bytes)
  1744.     elif segment_register == SS:
  1745.         raise x86exception('fault', 12, 0, "Stack Fault")
  1746.     else:
  1747.         raise x86exception('fault', 13, 0, "General Protection Fault A")
  1748.  
  1749. def lg_write(sreg,offset,value,n_bytes):
  1750. # See Agarwal pp 79-80
  1751.     desc = descrVec[sreg]
  1752.     if desc.Valid.getValue() and desc.Writable.getValue() and in_limits(desc, offset, n_bytes):
  1753.         LA_write((desc.Base.getValue() + offset) & 0xffffffff, value, n_bytes)
  1754.     elif sreg == SS:
  1755.         raise x86exception('fault', 12, 0, "Stack Fault")
  1756.     else:
  1757.         raise x86exception('fault', 13, 0, "General Protection Fault B")
  1758.     mem.refresh()
  1759.  
  1760. def in_limits(desc, offset, size):
  1761. # See Agarwal p 78
  1762.     size = abs(size)
  1763.     if desc.ExpandDown.getValue():
  1764.         if desc.DefaultAttr.getValue():
  1765.             edLimit = 0xffffffff
  1766.         else:
  1767.             edLimit = 0xffff
  1768.         return offset > desc.Limit.getValue() and offset + size - 1 <= edLimit
  1769.     else:
  1770.         return offset + size - 1 <= desc.Limit.getValue()
  1771.  
  1772.  
  1773. def LA_wrChk(laddr):
  1774.    
  1775. # Not implemented yet
  1776.  
  1777.     return laddr
  1778.  
  1779. def LA_rdChk(laddr):
  1780. #  p 93
  1781. # Virtual to physical address translation occurs here
  1782. #
  1783.     if laddr < 0 or laddr >= mem.length:
  1784.         print_feedback("Address: " + str(laddr))
  1785.         raise x86exception('fault', 100, -1,"Edlinas memory exceeded.")
  1786.     if ctrlReg[0].getValue() & 0x80000000 == 0:  # PG flag
  1787.         return laddr
  1788.     else:
  1789.         raise x86exception('fault', 103, -1, "Not ready for paging.")
  1790.    
  1791.     err_code = int((CPL == 3) and 4)
  1792.  
  1793.     dir_table = ctrlReg[3].getValue() & 0xfffff000
  1794.     dir_table_offset = ((laddr >> 20) & 0xffc)
  1795.     dte = mem.read(dir_table + dir_table_offset, 4)
  1796.     if not dte & 1:  # Present bit
  1797.         ctrlReg[2].setValue(laddr)
  1798.         raise x86exception('fault', 14,  err_code, "page table not present")
  1799.     if CPL == 3 and dte & 4 == 0: # U_S bit
  1800.         ctrlReg[2].setValue(laddr)
  1801.         raise x86exception('fault', 14, err_code, "user supervisor bit") # PAGE
  1802.  
  1803.     if dte & 32 == 0:             # Accessed bit
  1804.             mem.write(dir_table + dir_table_offset, dte | 32, 4)
  1805.  
  1806.     page_table = dte & 0xfffff000
  1807.     page_table_offset = (laddr >> 10) & 0xffc
  1808.     pte = mem.read(page_table + page_table_offset, 4)
  1809.     if not pte & 1: # Present bit
  1810.         ctrlReg[2].setValue(laddr)
  1811.         raise x86exception('fault', 14, err_code, "page not present") # PAGE
  1812.     if CPL == 3 and pte & 4 == 0: # U_S bit
  1813.         ctrlReg[2].setValue(laddr)
  1814.         raise x86exception('fault', 14, err_code, "user supervisor bit")
  1815.  
  1816.     if pte & 32 == 0:             # Accessed bit
  1817.             mem.write(page_table + page_table_offset, dte | 32, 4)
  1818.  
  1819.     return (pte & 0xfffff000) | (laddr  & 0xfff)
  1820.  
  1821.  
  1822. def check_brkpt(btype, addr):
  1823.    
  1824. # Not implemented yet
  1825. # Code in TRAP.BAS
  1826.  
  1827.     return
  1828.  
  1829. def LA_read(laddr, n_bytes):
  1830.    
  1831. # Alignment check goes here.
  1832.  
  1833. #   print "LA_read(laddr = ", laddr
  1834.  
  1835.     m = abs(n_bytes)
  1836.     retv = 0
  1837.     for k in range(m):
  1838.         check_brkpt(3,laddr + k)
  1839.         phys_addr = LA_rdChk(laddr + k)
  1840.         retv = retv + (1 << (k<<3))* mem.read(phys_addr,1)
  1841.    
  1842.     modsize = 1 << (m << 3)
  1843.     if n_bytes < 0 and retv >= (modsize >> 1):
  1844.         retv = retv - modsize
  1845.  
  1846.     return retv
  1847.  
  1848. def LA_write(laddr, value, n_bytes):
  1849.  
  1850.     assert laddr >= 0
  1851.  
  1852.     m = abs(n_bytes)
  1853.  
  1854.     assert m < 5
  1855.  
  1856.     if value < 0:
  1857.         value = (1<< (m << 3)) + value 
  1858.  
  1859.     for k in range(m):
  1860.         check_brkpt(1,laddr + k)
  1861.         phys_addr = LA_rdChk(laddr + k)
  1862.         mem.write(phys_addr, value & 255, 1)
  1863.         value >>= 8
  1864.  
  1865.  
  1866. def byte_swap(hex_string):
  1867.     assert type(hex_string) is str
  1868.     assert len(hex_string) % 2 == 0
  1869.     retval = ""
  1870.     for k in range(0,len(hex_string),2):
  1871.         retval = hex_string[k:k+2] + retval
  1872.     return retval
  1873.  
  1874. def operand_size(n_bits, byte_flag):
  1875.     if byte_flag == 0:
  1876.         return 1
  1877.     if n_bits == 16:
  1878.         return 2
  1879.     return 4
  1880.  
  1881. #####################################################################
  1882. #
  1883. #       Segments
  1884. #
  1885. #####################################################################
  1886.  
  1887. PROTECTED = 0
  1888. REAL = 1
  1889. VM86 = 2
  1890.  
  1891.  
  1892. def mode():
  1893.     if ctrlReg[0].getValue() & 1 == 0 or archnum <= 2:
  1894.         return REAL
  1895.     else:  
  1896.         return PROTECTED
  1897.  
  1898. def in_limits(desc,off,size):
  1899.     if desc.ExpandDown.getValue():
  1900.         if desc.DefaultAttr.getValue():
  1901.             edLimit = 0xffffffff
  1902.         else:
  1903.             edLimit = 0xffff
  1904.         return (off > desc.Limit.getValue()) and (off + size - 1 <= edLimit)
  1905.     else:
  1906.         return (off + size - 1<= desc.Limit.getValue())
  1907.  
  1908. def DTAB_write(err_code, desc, off, value):
  1909.     #p 81
  1910.     global CPL
  1911.     saveCPL = CPL
  1912.     if not desc.Valid or not in_limits(desc, off, 1):
  1913.         raise x86exception('fault', 13, (err_code & -4))  # GP
  1914.    
  1915.     CPL = 0
  1916.     LA_write(desc.Base.getValue() + off, value,1 )
  1917.     CPL = saveCPL
  1918.        
  1919. def DTAB_read(err_code, desc, offset, TSS_load, n_bytes):
  1920.     # pp 74-75
  1921.     global CPL
  1922.     if not desc.Valid or not desc.Readable or not in_limits(desc, offset, n_bytes):
  1923.         if TSS_load:
  1924.             raise x86exception('fault', 10, (err_code & -4))  # TASK
  1925.         else:
  1926.             raise x86exception('fault', 13, (err_code & -4))  # GP
  1927.     saveCPL = CPL
  1928.     CPL = 0
  1929.     retval = LA_read(desc.Base.getValue() + offset, n_bytes)
  1930.     CPL = saveCPL
  1931.     return retval
  1932.  
  1933. def mark_accessed(sel):
  1934.     # p 66
  1935.     if sel & 4 == 0:
  1936.         tableDesc = descrVec[GDT]
  1937.     else:
  1938.         tableDesc = descrVec[LDT]
  1939.    
  1940.     d2 = DTAB_read(sel, tableDesc, sel & 0xfff8 + 5, False,1)
  1941.     DTAB_write(sel, tableDesc, sel & 0xfff8 + 5, d2|1, False, 1)
  1942.  
  1943. #def nullSel(sel):
  1944. #   p 67
  1945. #   return (sel < 4)
  1946.  
  1947. def load_data_seg(sel, desc, TSS_load):
  1948.     #  Data segment descriptor desc is written into.
  1949.     #  p 71
  1950.  
  1951.     if  sel < 4 :  # nullSel(sel)
  1952.         desc.Valid.setValue(False)  #See p67
  1953.         return
  1954.     #lock Descriptor Table
  1955.     desc.read_descr(sel, TSS_load)
  1956.  
  1957.     if(((desc.Readable.getValue() or desc.Writable.getValue()) and \
  1958.        not desc.Conforming.getValue() and desc.DPL.getValue()>=CPL and \
  1959.              desc.DPL.getValue() >= (sel & 3))or \
  1960.       (desc.Readable.getValue() and desc.Conforming.getValue())):
  1961.         if not desc.Valid.getValue():
  1962.             raise x86exception('fault',11, sel & 0xFFFC)
  1963.     elif TSS_load:
  1964.             raise x86exception('fault',10, sel & 0xFFFC)  # TASK
  1965.     else:
  1966.             raise x86exception('fault',13, sel & 0xFFFC)  # GP
  1967.  
  1968.     mark_accessed(sel)
  1969.  
  1970. class x86exception(Exception):
  1971.     def __init__(self,xcpclass, interrupt_number,error_code,error_message):
  1972. #
  1973. # Python user defined exceptions are used in place of "signal_fault", etc.
  1974. # The xcpclass is either 'fault', 'trap', 'imprecise', or 'abort'.
  1975. #
  1976. # x86 Exceptions are listed on page 154.
  1977. # The name of the exception is included in the error_message.
  1978. # An error_code of -1 is used if there is no error code.
  1979. #
  1980. # An interrupt number of 100 is used when the edlinas machine has an error.
  1981. #
  1982.         self.args = (xcpclass, interrupt_number,error_code,error_message)
  1983.         self.xcpclass = xcpclass
  1984.         self.interrupt_number = interrupt_number
  1985.         self.error_code = error_code
  1986.         self.error_message = error_message
  1987. #
  1988. #
  1989. #  This is the processor's Fetch and Execute definition  
  1990. #
  1991.  
  1992. def fetchexec():
  1993.     byte = fetch_code(1)
  1994.     prefix = {}
  1995.     while prefixcheck(byte,prefix):
  1996.         byte = fetch_code(1)
  1997.    
  1998.     sreg = prefix.get('segmentoverride', -1)   
  1999.    
  2000.     if "OS" in prefix:
  2001.         os = 48 - Use_size.get()
  2002.     else:
  2003.         os = Use_size.get()
  2004.     if "AS" in prefix:
  2005.         ads = 48 - Use_size.get()
  2006.     else:
  2007.         ads = Use_size.get()
  2008.  
  2009.     if sreg == FS or sreg == GS and archnum < 3:
  2010.         raise x86exception('fault', 6, -1,"Invalid prefix")
  2011.     if 'lock' in prefix:
  2012.         lock_flag = 1
  2013.     else:
  2014.         lock_flag = 0
  2015.        
  2016.     hb1 = byte >> 4
  2017.     hb2 = byte & 15
  2018.     instruction_recognized = True
  2019.     if hb1 < 4 and (hb2 & 7) < 6:
  2020.         DoAlu(byte>>3,byte & 7,sreg,ads,os,lock_flag)
  2021.     elif hb1 == 8 and hb2 < 4:
  2022.         if hb2 == 2:
  2023.             raise x86exception('fault', 6, -1,"Invalid instruction")
  2024.         AluMI(byte, sreg, ads, os,lock_flag)
  2025.     elif hb1 == 8 and (hb2 >> 1) == 3:
  2026.         DoXch(byte,sreg,ads,os, lock_flag)
  2027.     elif byte == 0x0f:
  2028.         Do0F(sreg,ads,os,lock_flag)
  2029.     elif lock_flag == 1:
  2030.         raise x86exception('fault', 6, -1,"Instruction not lockable")
  2031.     elif hb1 < 2 and byte & 7 == 6:
  2032.         DoPush(byte,os)
  2033.     elif hb1 < 2 and byte & 7 == 7:
  2034.         DoPop(byte,sreg,ads,os)
  2035.     elif hb1 < 4 and byte & 7 == 7:
  2036.         DoAacrap(byte)
  2037.     elif hb1 == 4 :
  2038.         DoIncDec(byte,os)      
  2039.     elif hb1 == 5:
  2040.         if hb2 < 8:
  2041.             DoPush(byte,os)
  2042.         else:
  2043.             DoPop(byte,sreg,ads,os)
  2044.     elif hb1 == 6 and hb2 == 0:
  2045.         DoPusha(os)
  2046.     elif hb1 == 6 and hb2 == 1:
  2047.         Popa(os)
  2048.     elif hb1 == 6 and hb2 == 2:
  2049.         DoBound(sreg,ads,os)
  2050.     elif hb1 == 6 and hb2 == 3:
  2051.         DoArpl(sreg,ads,os)
  2052.     elif hb1 == 6 and (hb2 == 8 or hb2 == 0xa):
  2053.         DoPush(byte,os)
  2054.     elif hb1 == 6 and (hb2 == 9 or hb2 == 0xb):
  2055.         DoImul3(byte,sreg,ads,os)
  2056.     elif hb1 == 6 and hb2 > 0xb:
  2057.         DoString(byte,ads,os)
  2058.     elif hb1 == 7:
  2059.         DoJcond(byte,os)
  2060.     elif hb1 == 8 and  hb2 < 6:
  2061.         DoTest(byte,sreg,ads,os)
  2062.     elif hb1 == 8 and 7 < hb2 < 0xc:
  2063.         DoMov(byte,sreg,ads,os)
  2064.     elif hb1 == 8 and hb2 == 0xd:
  2065.         DoLea(sreg,ads,os)
  2066.     elif hb1 == 8 and (hb2 == 0xc or hb2 == 0xe):
  2067.         DoMovs(byte,sreg,ads,os)
  2068.     elif byte == 0x8f:
  2069.         DoPop(byte,sreg,ads,os)
  2070.     elif hb1 == 9 and hb2 == 0:
  2071.         pass
  2072.     elif hb1 == 9 and hb2 < 8:
  2073.         DoXch(byte,sreg,ads,os, lock_flag)
  2074.     elif hb1 == 9 and hb2 < 0xa:
  2075.         DoConv(byte, os)
  2076.     elif byte == 0x9a or byte == 0xe8:
  2077.         DoCall(byte,os)
  2078.     elif byte == 0x9c:
  2079.         Pushf(os)
  2080.     elif byte == 0x9d:
  2081.         Popf(os)
  2082.     elif byte == 0x9e:
  2083.         DoSahf()
  2084.     elif byte == 0x9f:
  2085.         DoLahf()
  2086.     elif hb1 == 0xa and hb2 < 4:
  2087.         DoMovaI(byte, sreg, os)
  2088.     elif hb1 == 0xa and 7 < hb2 < 0xa:
  2089.         DoTest(byte,sreg,ads,os)
  2090.     elif hb1 == 0xa:
  2091.         if 'repeat' in prefix:
  2092.             signal.pending_repeat = prefix['repeat']
  2093.         DoString(byte,ads,os)
  2094.     elif hb1 == 0xb:
  2095.         DoMovrI(byte,os)
  2096.     elif hb1 == 0xc and 3 < hb2 < 6:
  2097.         DoLodSeg(byte, os)
  2098.     elif hb1 == 0xc and 5 < hb2 < 8:
  2099.         DoMovmI(byte, ads, os)
  2100.     elif hb1 == 0xc and hb2 == 8:
  2101.         DoEnter(os)
  2102.     elif hb1 == 0xc and hb2 == 9:
  2103.         DoLeave(os)
  2104.     elif hb1 == 0xc and hb2 == 0xc:
  2105.         raise x86exception('trap', 3, -1,"Breakpoint interrupt")
  2106.     elif hb1 == 0xc and hb2 == 0xd:
  2107.         DoInt()
  2108.     elif hb1 == 0xc and hb2 == 0xe:
  2109.         DoInto()
  2110.     elif hb1 == 0xe and hb2 < 4:
  2111.         raise x86exception('fault', 101, -1,"Instruction not implemented")
  2112.         DoLoop()
  2113.     elif hb1 == 0xe and hb2&7 > 3:
  2114.         DoInOut(byte,ads, os)
  2115.     elif hb1 == 0xe:
  2116.         DoJmp(byte, os)
  2117.     elif (hb1 == 0xc and hb2 < 2) or (hb1 == 0xd and hb2 < 4):
  2118.         DoShift(byte,sreg,ads,os)
  2119.     elif hb1 == 0xc and (hb2 & 6) == 2:
  2120.         if prog.call_depth == 0:
  2121.             print_feedback("Program finished.   ")
  2122.             prog.set_execstate('interpreting')
  2123.             save_EIP = EIP.getvalue()
  2124.             prog.set_current_inst(instoffset = save_EIP)
  2125.             return
  2126.         else:
  2127.             prog.call_depth = prog.call_depth -1
  2128.             DoRet(byte, os)
  2129.     elif hb1 == 0xd and 3 < hb2 < 6:
  2130.         DoAacrap(byte)
  2131.     elif hb1 == 0xd and hb2 == 7:
  2132.         Xlat(byte, ads)
  2133.     elif byte == 0xf4:
  2134.         if CPL == 0:
  2135.             prog.set_execstate('stepping')  # Supposed to wait here for interrupts
  2136.         else:
  2137.             raise x86exception('fault', 13, 0, "General Protection Fault Y")
  2138.     elif byte == 0xf5:                # CMC
  2139.         Flags["CF"].setValue(1 - Flags["CF"].getValue())
  2140.     elif hb1 == 0xf and (hb2 >> 1) == 3:
  2141.         DoUnM(byte,sreg,ads,os)
  2142.     elif byte == 0xf8:
  2143.         Flags["CF"].setValue(0)
  2144.     elif byte == 0xf9:
  2145.         Flags["CF"].setValue(1)
  2146.     elif byte == 0xfa:
  2147.         if mode() == REAL:
  2148.             Flags["IF"].setValue(0)
  2149.         elif mode() == PROTECTED and CPL.getValue() <= IOPL.getValue():
  2150.             Flags["IF"].setValue(0)
  2151.         elif mode() == VM86 and IOPL.getValue() == 3:
  2152.             Flags["IF"].setValue(0)
  2153.         else:
  2154.             raise x86exception('fault', 13, 0, "General Protection Fault X")
  2155.     elif byte == 0xfb:
  2156.         if mode() == REAL:
  2157.             Flags["IF"].setValue(1)
  2158.         elif mode() == PROTECTED and CPL.getValue() <= IOPL.getValue():
  2159.             Flags["IF"].setValue(1)
  2160.         elif mode() == VM86 and IOPL.getValue() == 3:
  2161.             Flags["IF"].setValue(1)
  2162.         else:
  2163.             raise x86exception('fault', 13, 0, "General Protection Fault X")
  2164.     elif byte == 0xfc:
  2165.         Flags["DF"].setValue(0)
  2166.     elif byte == 0xfd:
  2167.         Flags["DF"].setValue(1)
  2168.     elif hb1 == 0xf and (hb2 == 0xe or hb2 == 0xf):
  2169.         DoFEFF(byte,sreg,ads,os,lock_flag)
  2170.     else:
  2171.         print("byte = ", "%02X" % byte)
  2172.         raise x86exception('fault', 101, -1,"Instruction not implemented")
  2173. #       raise x86exception('fault', 6, -1,"Invalid instruction")
  2174.     if prog.execstate != 'blocked':
  2175.         prog.set_current_inst(instoffset = EIP.getvalue() - prog.load_origin)
  2176.     return
  2177.  
  2178. def Do0F(sreg,ads,os,lock_flag):
  2179. #   Second Hop  Op Codes 0F
  2180.     byte2 = fetch_code(1)
  2181.     hb1 = byte2 >> 4
  2182.     hb2 = byte2 & 15
  2183.  
  2184.     if hb1 == 0xc and hb2 < 2:
  2185.         DoXadd(byte2,sreg,ads,os,lock_flag)
  2186.     elif lock_flag:
  2187.         raise x86exception('fault', 101, -1,"Instruction not implemented")
  2188.     elif hb1 == 0 and hb2 < 2:
  2189.         Do0F01(byte2,ads,os)
  2190.     elif hb1 == 0 and hb2 == 6:  # CLTS
  2191.         if CPL != 0:
  2192.             raise x86exception('fault', 13, 0, "General Protection Fault C")
  2193.         ctrlReg[0].setValue(ctrlReg[0].getValue() & 0xfffffff7)
  2194.     elif hb1 == 0 and hb2 == 8:  # INVD
  2195.         pass
  2196.     elif hb1 == 0 and hb2 == 9:  # WBINVD
  2197.         pass
  2198.     elif hb1 == 2 and hb2 < 7:
  2199.         DoMovt(byte2)
  2200.     elif hb1 == 6:
  2201.         pass
  2202.     elif hb1 == 8 and archnum > 2:
  2203.         DoJcond(byte2, os)
  2204.     elif hb1 == 9:
  2205.         Setcond(hb2,sreg,ads)
  2206.     elif hb1 == 0xa and hb2 & 7 == 0:
  2207.         DoPush(byte2,sreg,ads,os)
  2208.     elif hb1 == 0xa and hb2 & 7 == 1:
  2209.         DoPop(byte2,sreg,ads,os)
  2210.     elif hb1 == 0xa and hb2 == 0xf:
  2211.         DoImul3(byte2,sreg,ads,os)
  2212.     elif hb1 == 0xa and hb2 == 2:
  2213.         DoCpuid()
  2214.     elif hb1 == 0xa and hb2 < 4:
  2215.         raise x86exception('fault', 101, -1,"Instruction not implemented")
  2216.     elif hb1 == 0xa and (hb2 == 4 or hb2 == 5 or hb2 == 0xc or hb2 == 0xd):
  2217.         DoShift(byte2,sreg,ads,os)
  2218.     elif hb1 == 0xa and (hb2 == 3 or hb2 == 0xb):
  2219.         DoBits(byte2,sreg,ads,os,lock_flag)
  2220.     elif hb1 == 0xb and hb2 < 2:
  2221.         raise x86exception('fault', 101, -1,"Instruction not implemented")
  2222.         DoCmpXch(byte2,sreg,ads,os)
  2223.     elif hb1 == 0xb and (hb2 == 4 or hb2 == 5):
  2224.         DoLodSeg(byte2, os)
  2225.     elif hb1 == 0xb and hb2 & 7 > 5:
  2226.         DoMovx(byte2,sreg,ads,os)
  2227.     elif hb1 == 0xb and (hb2 == 3 or hb2 == 0xa or hb2 == 0xb):
  2228.         DoBits(byte2,sreg,ads,os,lock_flag)
  2229.     elif hb1 == 0xb and (0xb < hb2 < 0xe):
  2230.         DoBitScan(byte2,sreg,ads,os,lock_flag)
  2231.     elif hb1 == 0xc and hb2 > 7:
  2232.         DoBswap(byte2)
  2233.     else:
  2234.         raise x86exception('fault', 101, -1,"Instruction not implemented")
  2235.  
  2236. def Do0F01(byte2,ads,os):
  2237.     n_bytes = operand_size(os, byte & 1)
  2238.     modrm_byte = fetch_code(1)
  2239.     reg_bits = (modrm_byte >> 3)&7
  2240.     rm_bits = modrm_byte & 7
  2241.     source = regCode(reg_bits, n_bytes)
  2242.     op2 = regFetch(source)
  2243.     temp = op2
  2244.     if modrm_byte >= 0xc0:
  2245.         dest = regCode(rm_bits, n_bytes)
  2246.         op1 = regFetch(dest)
  2247.     else:
  2248.         (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  2249.         op1 = lg_read(sreg, offset, n_bytes)
  2250.     if byte2 == 0 and reg_bits == 0:  # SLDT
  2251.         if mode() != PROTECTED:
  2252.             raise x86exception('fault', 6, -1,"Invalid instruction")
  2253.         sel = segReg[LDT].getValue()
  2254.         if modrm_byte >= 0xc0:
  2255.             regStore(dest,sel)
  2256.         else:
  2257.             lg_write(sreg, offset, sel, 2)
  2258.     elif byte2 == 0 and reg_bits == 1:  # STR
  2259.         if mode() != PROTECTED:
  2260.             raise x86exception('fault', 6, -1,"Invalid instruction")
  2261.         sel = segReg[TSS].getValue()
  2262.         if modrm_byte >= 0xc0:
  2263.             regStore(dest,sel)
  2264.         else:
  2265.             lg_write(sreg, offset, sel, 2)
  2266.     elif byte2 == 0 and reg_bits == 2:  # LLDT
  2267.         if mode() != PROTECTED:
  2268.             raise x86exception('fault', 6, -1,"Invalid instruction")
  2269.         if CPL != 0:
  2270.             raise x86exception('fault', 13, 0, "General Protection Fault D")
  2271.         if modrm_byte >= 0xc0:
  2272.             sel = regFetch(dest)
  2273.         else:
  2274.             sel = lg_read(sreg, offset, 2)
  2275.         if sel & 4:
  2276.             raise x86exception('fault', 13, sel & 0xFFFC, "General Protection FaultE")
  2277.         if sel < 4:  # Is it the Null selector
  2278.             descrVec[LDT].Valid = False
  2279.         else:
  2280.             descrVec[LDT].read_descr(sel, False)
  2281.             if descrVec[LDT].Type != 2:  # LDT_SEG type
  2282.                 raise x86exception('fault', 13, sel & 0xFFFC, "General Protection FaultF")
  2283.             if not descrVec[LDT].Valid:
  2284.                 raise x86exception('fault', 13, sel & 0xFFFC, "General Protection FaultG")
  2285.         segReg[LDT].setValue(sel)
  2286.     elif byte2 == 0 and reg_bits == 3:  # LTR
  2287.         if mode() != PROTECTED:
  2288.             raise x86exception('fault', 6, -1,"Invalid instruction")
  2289.         if CPL != 0:
  2290.             raise x86exception('fault', 13, 0, "General Protection Fault H")
  2291.         if modrm_byte >= 0xc0:
  2292.             sel = regFetch(dest)
  2293.         else:
  2294.             sel = lg_read(sreg, offset, 2)
  2295.         if sel < 4 or sel & 4 :
  2296.             raise x86exception('fault', 13, sel & 0xFFFC, "General Protection Fault I")
  2297.         descrVec[TSS].read_descr(sel, False)
  2298.         if descrVec[TSS].Type == 1 or descrVec[TSS] == 9:  # Not Busy 16 or 32 bit TSS
  2299.             if not descrVec[TSS].Valid:
  2300.                 raise x86exception('fault', 11, sel & 0xFFFC, "Not Present Fault")
  2301.             temp = DTAB_read(sel,descrVec[GDT],(sel & 0xfff8 + 5), False, 1)
  2302.             DTAB_write(sel,descrVec[GDT],(sel & 0xfff8 + 5), temp | 2, False, 1)
  2303.         segReg[TSS].setValue(sel)
  2304.     elif byte2 == 0 and reg_bits == 4:  # VERR
  2305.         if mode() != PROTECTED:
  2306.             raise x86exception('fault', 6, -1,"Invalid instruction")
  2307.         if modrm_byte >= 0xc0:
  2308.             sel = regFetch(dest)
  2309.         else:
  2310.             sel = lg_read(sreg, offset, 2)
  2311.         if sel < 4 or not in_limits(tab_desc, sel & 0xfff8, 8):
  2312.             Flags["ZF"].setValue(0)
  2313.         else:
  2314.             dsc = Descr()
  2315.             dsc.read_descr(sel, False)
  2316.             if(((dsc.Readable or dsc.Writable) and CPL <= dsc.DPL and (sel & 3)<= dsc.DPL)or
  2317.                (dsc.Executable and dsc.Readable and CPL <= dsc.DPL and (sel & 3)<= dsc.DPL)or
  2318.                 (dsc.Conforming and dsc.Readable)):
  2319.                 Flags["ZF"].setValue(1)
  2320.             else:
  2321.                 Flags["ZF"].setValue(0)
  2322.     elif byte2 == 0 and reg_bits == 5:  # VERW
  2323.         if mode() != PROTECTED:
  2324.             raise x86exception('fault', 6, -1,"Invalid instruction")
  2325.         if modrm_byte >= 0xc0:
  2326.             sel = regFetch(dest)
  2327.         else:
  2328.             sel = lg_read(sreg, offset, 2)
  2329.         if sel & 4:
  2330.             tab_desc = descrVec[LDT]
  2331.         else:
  2332.             tab_desc = descrVec[GDT]
  2333.         if sel < 4 or not in_limits(tab_desc, sel & 0xfff8, 8):
  2334.             Flags["ZF"].setValue(0)
  2335.         else:
  2336.             dsc = Descr()
  2337.             dsc.read_descr(sel, False)
  2338.             if dsc.Writable and CPL <= dsc.DPL and (sel & 3)<= dsc.DPL:
  2339.                 Flags["ZF"].setValue(1)
  2340.             else:
  2341.                 Flags["ZF"].setValue(0)
  2342.     elif byte2 == 0:  
  2343.         raise x86exception('fault', 6, -1,"Invalid instruction")
  2344.     elif byte2 == 1 and reg_bits == 0:  # SGDT
  2345.         lg_write(sreg, offset, descrVec[GDT].Limit.getValue(), 2)
  2346.         if os == 32:
  2347.             lg_write(sreg, offset + 2, descrVec[GDT].Base.getValue() , 4)
  2348.         else:
  2349.             lg_write(sreg, offset + 2, descrVec[GDT].Base.getValue() & 0xffffff, 2)
  2350.     elif byte2 == 1 and reg_bits == 1:  # SIDT
  2351.         lg_write(sreg, offset, descrVec[IDT].Limit.getValue(), 2)
  2352.         if os == 32:
  2353.             lg_write(sreg, offset + 2, descrVec[IDT].Base.getValue() , 4)
  2354.         else:
  2355.             lg_write(sreg, offset + 2, descrVec[IDT].Base.getValue() & 0xffffff, 2)
  2356.     elif byte2 == 1 and reg_bits == 2:  # LGDT
  2357.         if CPL != 0:
  2358.             raise x86exception('fault', 13, 0, "General Protection Fault J")
  2359.         if modrm_byte >= 0xc0:
  2360.             raise x86exception('fault', 6, -1,"Invalid instruction")
  2361.         descrVec[GDT].Limit.setValue(lg_read(sreg, offset,2))
  2362.         if os == 32:
  2363.             descrVec[GDT].Base.setValue(lg_read(sreg, offset + 2, 4))
  2364.         else:
  2365.             descrVec[GDT].Base.setValue(lg_read(sreg, offset + 2, 2) & 0xFFFFFF)
  2366.         descrVec[GDT].Valid.setValue(True)
  2367.     elif byte2 == 1 and reg_bits == 3:  # LIDT
  2368.         if CPL != 0:
  2369.             raise x86exception('fault', 13, 0, "General Protection Fault K")
  2370.         descrVec[IDT].Limit.setValue(lg_read(sreg, offset,2))
  2371.         if os == 32:
  2372.             descrVec[IDT].Base.setValue(lg_read(sreg, offset + 2, 4))
  2373.         else:
  2374.             descrVec[IDT].Base.setValue(lg_read(sreg, offset + 2, 2) & 0xffffff)
  2375. #       descrVec[IDT].Valid = True
  2376.     elif byte2 == 1 and reg_bits == 5:  # SMSW
  2377.         msw = ctrlReg[0].getValue() & 31
  2378.         if modrm_byte >= 0xc0:
  2379.             regStore(dest, msw)
  2380.         else:
  2381.             lg_write(sreg, offset, msw, 2)
  2382.     elif byte2 == 1 and reg_bits == 6:  # LMSW
  2383.         if CPL != 0:
  2384.             raise x86exception('fault', 13, 0, "General Protection Fault L")
  2385.         if modrm_byte >= 0xc0:
  2386.             msm = regFetch(dest)
  2387.         else:
  2388.             msm = lg_read(sreg, offset, 2)
  2389.         msw = msm & 31
  2390.         if ctrlReg[0].getValue() & 1 == 0:
  2391.             ctrlReg[0].setValue(msm)
  2392.         else:
  2393.             msm = msm | 1
  2394.             ctrlReg[0].setValue(msm)
  2395.     elif byte2 == 1 and reg_bits == 7:  # INVPLG
  2396.         pass
  2397.     else:
  2398.         raise x86exception('fault', 6, -1,"Invalid instruction")
  2399.  
  2400.  
  2401. def fetch_code(n_bytes):
  2402.     n = abs(n_bytes)
  2403.     if EIP.getvalue() < -1:
  2404.         b = 2*(EIP.getvalue() - prog.store_origin)
  2405.         retval= int(byte_swap(prog.stored_command[b:b+2*n]),16)
  2406.         if n_bytes < 0 and retval >= (1 << ((n << 3) - 1)):
  2407.             retval = retval - (1 << (n << 3))
  2408.     else:
  2409.         retval = LA_read(EIP.getvalue(), n_bytes)
  2410.     EIP.setvalue(EIP.getvalue() + n)
  2411.     return retval
  2412.  
  2413. def prefixcheck(byte, prefdict={}):
  2414.     if byte == 0x2e:   
  2415.         prefdict['segmentoverride'] = CS
  2416.     elif byte == 0x3e
  2417.         prefdict['segmentoverride'] = DS
  2418.     elif byte == 0x26:
  2419.         prefdict['segmentoverride'] = ES
  2420.     elif byte == 0x64
  2421.         prefdict['segmentoverride'] = FS
  2422.     elif byte == 0x65:
  2423.         prefdict['segmentoverride'] = GS
  2424.     elif byte == 0x36
  2425.         prefdict['segmentoverride'] = SS
  2426.     elif byte == 0x66:
  2427.         prefdict["OS"] = "OS"
  2428.     elif byte == 0x67:
  2429.         prefdict["AS"] = "AS"
  2430.     elif byte == 0xf3:
  2431.         prefdict['repeat'] = 'REPE'                     #REPE
  2432.     elif byte == 0xf2:
  2433.         prefdict['repeat'] = 'REPNE'                    #REPNE
  2434.     elif byte == 0xf0:
  2435.         prefdict['lock'] = "LOCK"
  2436.     else:
  2437.         return False
  2438.  
  2439. def regStore(reg_num, value):
  2440.     assert value >= 0
  2441.     if reg_num < 8:
  2442.         genReg[reg_num].setValue(value)
  2443.     elif reg_num < 16:
  2444.         full_value = genReg[reg_num - 8].getValue()
  2445.         genReg[reg_num - 8].setValue((full_value&-65536)|value)
  2446.     elif reg_num < 20:
  2447.         full_value = genReg[reg_num - 16].getValue()
  2448.         genReg[reg_num - 16].setValue((full_value&-256)|value) 
  2449.     elif reg_num < 24:
  2450.         full_value = genReg[reg_num - 20].getValue()
  2451.         genReg[reg_num - 20].setValue((full_value & (-65536|255))|(value<<8))
  2452.     elif reg_num < 32:
  2453.         segReg[reg_num - 24].setValue(value)
  2454.     elif reg_num < 40:
  2455.         debReg[reg_num - 32].setValue(value)
  2456.     elif reg_num < 48:
  2457.         testReg[reg_num - 40].setValue(value)
  2458.     elif reg_num < 52:
  2459.         ctrlReg[reg_num - 48].setValue(value)
  2460.     else:
  2461.         raise ValueError("Bad register number: " + str(reg_num))
  2462.     if reg_num == 4 or reg_num == 12:
  2463.         try:
  2464.             stackWindow
  2465.             isdefined = True
  2466.         except:
  2467.             isdefined = False
  2468.         if isdefined and stackWindow.winfo_exists():
  2469.             stackView.refresh()
  2470.  
  2471. def regFetch(reg_num):
  2472.     if reg_num < 8:
  2473.         retval = genReg[reg_num].getValue()
  2474.     elif reg_num < 16:
  2475.         retval = 0xffff & genReg[reg_num - 8].getValue()
  2476.     elif reg_num < 20:
  2477.         retval = 0xff & genReg[reg_num -16].getValue()
  2478.     elif reg_num < 24:
  2479.         retval = (0xff00 & genReg[reg_num - 20].getValue()) >> 8
  2480.     elif reg_num < 32:
  2481.         retval = segReg[reg_num - 24].getValue()
  2482.     elif reg_num < 40:
  2483.         retval = debReg[reg_num - 32].getValue()
  2484.     elif reg_num < 48:
  2485.         retval = testReg[reg_num - 40].getValue()
  2486.     elif reg_num < 52:
  2487.         retval = ctrlReg[reg_num - 48].getValue()
  2488.     else:
  2489.         raise ValueError("not defined for reg_num = " + str(reg_num))
  2490.     return retval
  2491.  
  2492. def reg_signedFetch(reg_num):
  2493. # This function is never called.
  2494.     unsigned_val = regFetch(reg_num)
  2495.     if reg_num < 8:
  2496.         if unsigned_val > 0x7fffffff:
  2497.             return unsigned_val - 0x100000000
  2498.         else:
  2499.             return unsigned_val
  2500.     elif reg_num < 16:
  2501.         if unsigned_val > 32767:
  2502.             return unsigned_val - 65536
  2503.         else:
  2504.             return unsigned_val
  2505.     elif reg_num < 24:
  2506.         if unsigned_val > 127:
  2507.             return unsigned_val - 256
  2508.         else:
  2509.             return unsigned_val
  2510.     raise ValueError("Only registers numbered below 24 can have a sign.")
  2511.  
  2512.  
  2513. def regCode(reg_num,S):
  2514.     """ reg_num is a number less than 8                             S
  2515.      The return codes  follow:
  2516.           0- 7:                  EAX ECX EDX EBX ESP EBP ESI EDI    4
  2517.           8-15:                   AX  CX  DX  BX  SP  BP  SI  DI    2
  2518.          16-23:                   AL  CL  DL  BL  AH  CH  DH  BH    1
  2519.          24-31:                   ES  CS  SS  DS  FS  GS LDT TSS    5
  2520.          32-39:                  DR0 DR1 DR2 DR3 DR4 DR5 DR6 DR7    6
  2521.          40-47:                  TR0 TR1 TR2 TR3 TR4 TR5 TR6 TR7    7
  2522.          48-51:                  CR0 CR1 CR2 CR3                    8 """
  2523.     assert S > 0
  2524.     if S == 1:
  2525.         return reg_num + 16
  2526.     if S == 2:
  2527.         return reg_num + 8
  2528.     if S == 4:
  2529.         return reg_num
  2530.     return reg_num + (S - 2) * 8
  2531.  
  2532. def getFlags(n_bytes):
  2533.     retval = 0
  2534.     retval = retval + (Flags["CF"].getValue()<< 0)
  2535.     retval = retval + (1<< 1)
  2536.     retval = retval + (Flags["PF"].getValue()<< 2)
  2537.     retval = retval + (0<< 3)
  2538.     retval = retval + (Flags["AF"].getValue()<< 4)
  2539.     retval = retval + (0<< 5)
  2540.     retval = retval + (Flags["ZF"].getValue()<< 6)
  2541.     retval = retval + (Flags["SF"].getValue()<< 7)
  2542.     retval = retval + (Flags["TF"].getValue()<< 8)
  2543.     retval = retval + (Flags["IF"].getValue()<< 9)
  2544.     retval = retval + (Flags["DF"].getValue()<< 10)
  2545.     retval = retval + (Flags["OF"].getValue()<< 11)
  2546.     retval = retval + (IOPL.getValue()<< 12)   # 2 bit value
  2547.     retval = retval + (Flags["NT"].getValue()<< 14)
  2548.     retval = retval + (0<< 15)
  2549.     if n_bytes == 2:
  2550.         return retval
  2551.     retval = retval + (Flags["RF"].getValue()<< 16)
  2552.     retval = retval + (Flags["VM"].getValue()<< 17)
  2553.     retval = retval + (Flags["AC"].getValue()<< 18)
  2554.     return retval
  2555.  
  2556. def setFlags(value, n_bytes):
  2557.     Flags["CF"].setValue((value>> 0) & 1)
  2558.     Flags["PF"].setValue((value>> 2) & 1)
  2559.     Flags["AF"].setValue((value>> 4) & 1)
  2560.     Flags["ZF"].setValue((value>> 6) & 1)
  2561.     Flags["SF"].setValue((value>> 7) & 1)
  2562.     Flags["TF"].setValue((value>> 8) & 1)
  2563.     Flags["IF"].setValue((value>> 9) & 1)
  2564.     Flags["DF"].setValue((value>> 10) & 1)
  2565.     Flags["OF"].setValue((value>> 11) & 1)
  2566.     IOPL.setValue((value>> 12) & 3)  # 2 bit value
  2567.     Flags["NT"].setValue((value>> 14) & 1)
  2568.     if n_bytes == 2:
  2569.         return
  2570.     Flags["RF"].setValue((value>> 16) & 1)
  2571.     Flags["VM"].setValue((value>> 17) & 1)
  2572.     Flags["AC"].setValue((value>> 18) & 1)
  2573.  
  2574.    
  2575. def GetOffset(modrm_byte, address_size = 32, seg_reg = -1):
  2576.     assert modrm_byte < 0xc0
  2577.     default_segment_register = 3                # DS
  2578.     rm_num = modrm_byte & 7
  2579.     row_num = (modrm_byte >> 6) + 1
  2580.     if address_size == 32:
  2581.         if rm_num == 4:
  2582.             sreg, get = GetSibAdd(row_num)
  2583.             default_segment_register = sreg
  2584.         elif rm_num == 5 and row_num == 1:
  2585.             get = fetch_code(4)
  2586.         else:
  2587.             if row_num == 1:
  2588.                 get = 0
  2589.             elif row_num == 2:
  2590.                 get = fetch_code(1)
  2591.                 if get > 127:
  2592.                     get = get -256 + (1 << 32)
  2593.             elif row_num == 3:
  2594.                 get = fetch_code(4)
  2595.             if rm_num == 5:                 # EBP
  2596.                 default_segment_register = 2  #Segment register = SS
  2597.             elif rm_num == 7:                   # EDI
  2598.                 default_segment_register = 0  #Segment register = ES
  2599.             get = get + regFetch(rm_num)
  2600.             if get > 0xffffffff:
  2601.                 get = get & 0xffffffff
  2602.     elif address_size == 16:
  2603.         if rm_num == 6 and row_num == 1:
  2604.             get = fetch_code(2)
  2605.         elif row_num == 2:
  2606.             get = fetch_code(1)
  2607.             if get > 127:
  2608.                 get = get -256 + (1 << 32)  # 1<< 16?
  2609.         elif row_num == 3:
  2610.             get = fetch_code(2)
  2611.         else:
  2612.             get = 0
  2613.         if rm_num == 0:
  2614.             get = get + regFetch(11) + regFetch(14)         # BX + SI
  2615.         elif rm_num == 1:
  2616.             get = get + regFetch(11) + regFetch(15)         # BX + DI
  2617.         elif rm_num == 2:
  2618.             get = get + regFetch(13) + regFetch(14)         # BP + SI
  2619.             default_segment_register = 2  #Segment register = SS
  2620.             # segreg = SS
  2621.         elif rm_num == 3:
  2622.             get = get + regFetch(13) + regFetch(15)         # BP + DI
  2623.             default_segment_register = 2  #Segment register = SS
  2624.         elif rm_num == 4:
  2625.             get = get + regFetch(14)                                # SI
  2626.         elif rm_num == 5:
  2627.             get = get + regFetch(15)                                # DI
  2628.         elif rm_num == 6:
  2629.             get = get + regFetch(13)                                # BP
  2630.             default_segment_register = 2  #Segment register = SS
  2631.         elif rm_num == 7:
  2632.             get = get + regFetch(11)                                # BX
  2633.         get = get & 0xffff
  2634.  
  2635.     if seg_reg == -1:
  2636.         return (default_segment_register, get)
  2637.     else:
  2638.         return (seg_reg, get)
  2639.  
  2640. def GetSibAdd(row_num):
  2641.     sreg = 3                                                            # DS
  2642.     sib_byte = fetch_code(1)
  2643.     scale = 1 << (sib_byte >> 6)
  2644.     base_reg_num = sib_byte & 7
  2645.     ind_reg_num = (sib_byte>> 3) & 7
  2646.     if ind_reg_num == 4:
  2647.         if base_reg_num == 4 and scale == 1:
  2648.             scale = 0
  2649.         else:
  2650.             raise x86exception('fault', 6, -1,"Invalid SIB byte")
  2651.     if base_reg_num == 5 and row_num == 1:
  2652.         base_address = fetch_code(4)
  2653.     elif base_reg_num in [4,5]:
  2654.         sreg = 2                             #Segment register = SS
  2655.         base_address = regFetch(base_reg_num)
  2656.     else:
  2657.         base_address = regFetch(base_reg_num)
  2658.  
  2659.     if row_num == 1:
  2660.         sib_address = base_address + scale * regFetch(ind_reg_num)
  2661.     elif row_num == 2:
  2662.         imm_num = fetch_code(1)
  2663.         if imm_num > 127:
  2664.             sib_address= base_address + scale * regFetch(ind_reg_num)+ imm_num - 256
  2665.         else:
  2666.             sib_address= base_address + scale * regFetch(ind_reg_num)+ imm_num
  2667.     elif row_num == 3:
  2668.             sib_address= base_address + scale * regFetch(ind_reg_num)+ fetch_code(4)
  2669.  
  2670.     if sib_address < 0:
  2671.         sib_address = sib_address + (1<< 32)
  2672.     elif sib_address > 0xffffffff:
  2673.         sib_address = sib_address & 0xffffffff
  2674.        
  2675.     return (sreg, sib_address) 
  2676.  
  2677. def DoAacrap(byte):
  2678.     # Handles opcodes 27, 2f, 37, 3f, d4, and d5
  2679.     if byte == 0x37:     #AAA
  2680.         x = regFetch(16)   # AL
  2681.         if Flags["AF"].getValue() == 1 or (x & 15) > 9:
  2682.             x = (x + 6) & 0xf
  2683.             regStore(16, x)  # AL
  2684.             y = regFetch(20) # AH
  2685.             regStore(20, y + 1) # AH
  2686.             Flags["AF"].setValue(1)
  2687.         else:
  2688.             Flags["AF"].setValue(0)
  2689.         Flags["CF"].setValue(Flags["AF"].getValue())
  2690.     elif byte == 0x3f:   #AAS
  2691.         x = regFetch(16)   # AL
  2692.         if Flags["AF"].getValue() == 1 or (x & 15) > 9:
  2693. #           x = (x - 6) & 0xf
  2694.             x = (x & 0xf) - 6
  2695.             regStore(16, x)  # AL
  2696.             y = regFetch(20) # AH
  2697.             y = (y - 1) & 0xf
  2698.             regStore(20, y) # AH
  2699.             Flags["AF"].setValue(1)
  2700.         else:
  2701.             Flags["AF"].setValue(0)
  2702.         Flags["CF"].setValue(Flags["AF"].getValue())
  2703.     elif byte == 0x27:   #DAA
  2704.         x = regFetch(16)   # AL
  2705.         if Flags["AF"].getValue() == 1 or (x & 15) > 9:
  2706.             x = x + 6
  2707.             regStore(16, x)  # AL
  2708.             Flags["AF"].setValue(1)
  2709.         else:
  2710.             Flags["AF"].setValue(0)
  2711.  
  2712.         if Flags["CF"].getValue() == 1 or (x & 0xf0) > 0x90:
  2713.             regStore(16, x + 0x60) # AL
  2714.             Flags["CF"].setValue(1)
  2715.         else:
  2716.             Flags["CF"].setValue(0)
  2717.            
  2718.     elif byte == 0x2f:   #DAS
  2719.         x = regFetch(16)   # AL
  2720.         if Flags["AF"].getValue() == 1 or (x & 15) > 9:
  2721.             x = x - 6
  2722.             regStore(16, x)  # AL
  2723.             Flags["AF"].setValue(1)
  2724.         else:
  2725.             Flags["AF"].setValue(0)
  2726.         if Flags["CF"].getValue() == 1 or (x & 0xf0) > 0x90:
  2727.             regStore(16, x - 0x60) # AL
  2728.             Flags["CF"].setValue(1)
  2729.         else:
  2730.             Flags["CF"].setValue(0)
  2731.     elif byte == 0xd4:   #AAM
  2732.         x = regFetch(16)  #AL
  2733.         y = (fetch_code(1) or 10)
  2734.         regStore(20, x//y) #AH
  2735.         regStore(16, x % y)
  2736.     elif byte == 0xd5:  #AAD
  2737.         # regFetch(16)   = AL
  2738.         y = (fetch_code(1) or 10)
  2739.         x = (regFetch(20) * y + regFetch(16)) & 0xff
  2740.         regStore(16,x)
  2741.         regStore(20,0)
  2742.  
  2743. #Common flag settings
  2744.  
  2745.     if regFetch(16) & 0x80 == 0:  #AL
  2746.         Flags["SF"].setValue(0)
  2747.     else:
  2748.         Flags["SF"].setValue(1)
  2749.     if x == 0:
  2750.         Flags["ZF"].setValue(1)
  2751.     else:
  2752.         Flags["ZF"].setValue(0)
  2753.     Flags["PF"].setValue(evenParity(regFetch(16))) #AL
  2754.  
  2755.  
  2756. def DoAlu(oper_num,opand_num,sreg,ads,n_bits,lock_flag=0):
  2757.     n_bytes = operand_size(n_bits,opand_num & 1)
  2758.     if opand_num & 1 == 0:
  2759.         n_bits = 8
  2760.  
  2761.     if opand_num >> 1 == 2:                     # Dest = EAX, AX, or AL; Source = imm
  2762.         dest = regCode(0,n_bytes)
  2763.         op1 = regFetch(dest)
  2764.         op2 = fetch_code(n_bytes)
  2765.         if lock_flag:
  2766.             raise x86exception('fault', 6, -1, "Not lockable")
  2767.     elif opand_num >> 1 == 1:                   # Dest = r; Source = rmv or rmb
  2768.         modrm_byte = fetch_code(1)
  2769.         dest = regCode((modrm_byte>>3)&7,n_bytes)
  2770.         op1 = regFetch(dest)
  2771.         if modrm_byte >= 0xc0:
  2772.             source = regCode(modrm_byte & 7,n_bytes)
  2773.             op2 = regFetch(source)
  2774.             if lock_flag:
  2775.                 raise x86exception('fault', 6, -1, "Not lockable")
  2776.         else:                                  
  2777.             sreg,offset = GetOffset(modrm_byte,ads,sreg)
  2778.             op2 = lg_read(sreg,offset,n_bytes)
  2779.     elif opand_num >> 1 == 0:                   # Dest = rmv or rmb; Source = r
  2780.         modrm_byte = fetch_code(1)
  2781.         source = regCode((modrm_byte>>3)&7,n_bytes)
  2782.         op2 = regFetch(source)
  2783.         if modrm_byte >= 0xc0:
  2784.             dest = regCode(modrm_byte & 7,n_bytes)
  2785.             op1 = regFetch(dest)
  2786.             if lock_flag:
  2787.                 raise x86exception('fault', 6, -1, "Not lockable")
  2788.         else:                              
  2789.             sreg,offset = GetOffset(modrm_byte,ads,sreg)
  2790.             op1 = lg_read(sreg,offset,n_bytes)
  2791.     else:
  2792.         return
  2793.    
  2794.     if oper_num == 0:
  2795.         op1 = sum(op1,op2,n_bits)  
  2796.     elif oper_num in [1,4,6]:
  2797.         op1 = bblog(op1,op2,oper_num,n_bits)
  2798.     elif oper_num == 2:
  2799.         op1 = sum(op1,op2,n_bits,carry_flag=Flags["CF"].getValue())
  2800.     elif oper_num == 3:
  2801.         op1 = dif(op1,op2,n_bits,carry_flag=Flags["CF"].getValue())
  2802.     elif oper_num == 5:
  2803.         op1 = dif(op1,op2,n_bits)
  2804.     elif oper_num == 7:
  2805.         dif(op1,op2,n_bits)
  2806.  
  2807.     if opand_num >> 1 == 0 and modrm_byte < 0xc0:   # Dest = rmv or rmb; Source = r
  2808.         lg_write(sreg,offset,op1,n_bytes)
  2809.     else:
  2810.         regStore(dest,op1)
  2811.  
  2812.  
  2813. def AluMI(byte, sgrg, ads, os,lock_flag):
  2814.     n_bytes = operand_size(os, byte & 1)
  2815.     if byte == 0x83:
  2816.         n_imm_bytes = 1
  2817.     else:
  2818.         n_imm_bytes = n_bytes
  2819.  
  2820.     byte = fetch_code(1)
  2821.     reg_bits = (byte >> 3) & 7
  2822.     mem_bits = byte & 7
  2823.     if byte >= 0xc0 and lock_flag == 1:
  2824.         raise x86exception('fault', 6, -1,"Lock Invalid")
  2825.     elif byte >= 0xc0:
  2826.         dest = regCode(mem_bits, n_bytes)
  2827.         mem_num = regFetch(dest)
  2828.     else:
  2829.         sreg,offset = GetOffset(byte, seg_reg=sgrg)
  2830.         mem_num = lg_read(sgrg,offset,n_bytes)
  2831.    
  2832.     imm_num = fetch_code(n_imm_bytes)
  2833.    
  2834.     if reg_bits == 0:
  2835.         result = sum(mem_num, imm_num,n_bytes << 3, 0)
  2836.     elif reg_bits == 1 or reg_bits == 4 or reg_bits == 6:  
  2837.         result = bblog(mem_num, imm_num, reg_bits, n_bytes<< 3)
  2838.     elif reg_bits == 2:
  2839.         result = sum(mem_num, imm_num, n_bytes << 3, Flags["CF"].getValue())
  2840.     elif reg_bits == 3:
  2841.         result = dif(mem_num, imm_num, n_bytes << 3, Flags["CF"].getValue())
  2842.     elif reg_bits == 5:
  2843.         result = dif(mem_num, imm_num, n_bytes << 3, 0)
  2844.     elif reg_bits == 7:
  2845.         dif(mem_num, imm_num,n_bytes<< 3, 0)
  2846.         result = mem_num
  2847.        
  2848.  
  2849.     if byte >= 0xc0:
  2850.         regStore(dest, result)
  2851.     else:
  2852.         lg_write(sgrg,offset,result,n_bytes)
  2853.  
  2854. def DoArpl(sreg,ads,os):
  2855. #
  2856. #   if mode() == REAL or mode() == VM86 :
  2857. #       raise x86exception('fault', 6, -1,"Invalid instruction")
  2858. #  else:
  2859.         modrm_byte = fetch_code(1)
  2860.         reg_bits = (modrm_byte >> 3) &7
  2861.         source = regCode(reg_bits,  2)
  2862.         src_RPL = regFetch(source) & 3
  2863.         if modrm_byte >= 0xc0:
  2864.             rm_bits = modrm_byte & 7
  2865.             dest = regCode(rm_bits, 2)
  2866.             dst = regFetch(dest)
  2867.         else:
  2868.             (sreg, offset) = GetOffset(modrm_byte, ads, sreg)
  2869.             dst = lg_read(sreg, offset, 2)
  2870.  
  2871.         dst_RPL = dst & 3
  2872.  
  2873.         if src_RPL > dst_RPL:
  2874.             x = dst + src_RPL - dst_RPL
  2875.             if modrm_byte >= 0xc0:
  2876.                 regStore(dest, x)
  2877.             else:
  2878.                 lg_write(sreg, offset, x ,2)
  2879.             Flags["ZF"].setValue(1)
  2880.         else:
  2881.             Flags["ZF"].setValue(0)
  2882.  
  2883. def DoBits(byte,sreg,ads,os,lock_flag):
  2884. #
  2885. #  OpCodes 0F , Ay, y = 3,B and Bx where x = 3,A, or B
  2886. #
  2887.     n_bytes = os >> 3
  2888.  
  2889.     imm_flag = (byte == 0xba)
  2890.    
  2891.     oper_num = (byte - 0x83) >> 3 # For non 0xba cases.
  2892.  
  2893.     modrm_byte = fetch_code(1)
  2894.     reg_bits = (modrm_byte >> 3) & 7
  2895.     rm_bits = modrm_byte & 7
  2896.  
  2897.     if modrm_byte >= 0xc and lock_flag:
  2898.         raise x86exception('fault', 6, -1,"Invalid instruction")
  2899.     elif modrm_byte >= 0xc:
  2900.         dest = regCode(rm_bits, n_bytes)
  2901.         x = regFetch(dest)
  2902.     else:
  2903.         (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  2904.         x = lg_read(sreg, offset, n_bytes)
  2905.  
  2906.     if imm_flag:
  2907.         oper_num = reg_bits
  2908.         index = fetch_code(1)
  2909.     else:
  2910.         source = regCode(reg_bits, n_bytes)
  2911.         index = regFetch(source)
  2912.  
  2913. #   if modrm_byte >= 0xc:
  2914. #       pointer = offset + index / os
  2915. #       x = lg_read(sreg, pointer, n_bytes)
  2916.  
  2917.     index = index % os
  2918.     y = BitFlip(x,index,oper_num, n_bytes)
  2919.     if modrm_byte >= 0xc0:
  2920.         regStore(dest,y)
  2921.     else:
  2922.         lg_write(sreg,offset,y, n_bytes)
  2923.  
  2924. def BitFlip(x, index, oper_num, n_bytes):
  2925.     n_bits = (n_bytes << 3)
  2926.     check_bit = (1 << index)
  2927.     Flags["CF"].setValue(int(x & check_bit != 0))
  2928.     if oper_num == 4:       #Test
  2929.         pass
  2930.     elif oper_num == 5:     #Set
  2931.         x = x | check_bit
  2932.     elif oper_num == 6:     #Reset
  2933.         x = x & ~check_bit
  2934.     elif oper_num == 7:     #Complement
  2935.         x = x ^ check_bit
  2936.  
  2937.     return x
  2938.  
  2939. def DoBitScan(byte,sreg,ads,os,lock_flag):
  2940. #
  2941. #  OpCodes 0F , BC or BD
  2942. #
  2943.     n_bits = os
  2944.     n_bytes = os >> 3
  2945.     forward_flag = (byte == 0xbc)
  2946.  
  2947.     modrm_byte = fetch_code(1)
  2948.     reg_bits = (modrm_byte >> 3) & 7
  2949.     rm_bits = modrm_byte & 7
  2950.  
  2951.     dest = regCode(reg_bits, n_bytes)
  2952.     if modrm_byte >= 0xc and lock_flag:
  2953.         raise x86exception('fault', 6, -1,"Invalid instruction")
  2954.     elif modrm_byte >= 0xc:
  2955.         src = rm_bits
  2956.         x = regFetch(src)
  2957.     else:
  2958.         (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  2959.         x = lg_read(sreg, offset, n_bytes)
  2960.  
  2961.     if forward_flag:
  2962.         i = 0
  2963.         mask = 1
  2964.         while mask & x == 0 and i < n_bits:
  2965.             mask = (mask << 1)
  2966.             i = i + 1
  2967.         if i == n_bits:
  2968.             Flags["ZF"].setValue(1)
  2969.             r = n_bits + 1   # Need to supply an undefined value
  2970.         else:
  2971.             Flags["ZF"].setValue(0)
  2972.             r = i
  2973.     else:
  2974.         i = n_bits -1
  2975.         mask = (1 << i)
  2976.         while mask & x == 0 and i >= 0:
  2977.             mask = (mask >> 1)
  2978.             i =  i - 1
  2979.         if i == -1:
  2980.             r = n_bits + 1   # Need to supply an undefined value
  2981.             Flags["ZF"].setValue(1)
  2982.         else:
  2983.             Flags["ZF"].setValue(0)
  2984.             r = i
  2985.     y = r
  2986.     if Flags["ZF"].getValue() == 0:
  2987.         regStore(dest, y)
  2988.  
  2989. def DoBound(sreg,ads,os):
  2990.     n_bytes = os >> 3
  2991.     modrm_byte = fetch_code(1)
  2992.     if modrm_byte >= 0xc0:
  2993.         raise x86exception('fault', 6, -1,"Invalid instruction")
  2994.     reg_bits = (modrm_byte >> 3) & 7
  2995.     source = regCode(reg_bits, n_bytes)
  2996.     src1 = regFetch(source)
  2997.     (sreg, offset) = GetOffset(modrm_byte, ads, sreg)
  2998.     lower_bound = lg_read(sreg, offset, n_bytes)
  2999.     upper_bound = lg_read(sreg, offset + n_bytes, n_bytes)
  3000.     if src1 < lower_bound or src1 > upper_bound:
  3001.         raise x86exception('fault', 5, -1,"BOUND violation")
  3002.  
  3003. def DoBswap(byte):
  3004.     reg_num = byte - 0xc8
  3005.     x = genReg[reg_num].getStringValue()
  3006.     regStore(reg_num, int(byte_swap(x),16))
  3007.  
  3008. def DoCmpXchg(byte,sreg,ads,os):
  3009.     n_bytes = operand_size(os, byte & 1)
  3010.     modrm_byte = fetch_code(1)
  3011.     reg_bits = (modrm_byte >> 3) &7
  3012.     source = regCode(reg_bits,  n_bytes)
  3013.     op2 = regFetch(source)
  3014.     if modrm_byte >= 0xc0:
  3015.         rm_bits = modrm_byte & 7
  3016.         dest = regCode(rm_bits, n_bytes)
  3017.         op1 = regFetch(dest)
  3018.     else:
  3019.         (sreg, offset) = GetOffset(modrm_byte, ads, sreg)
  3020.         op1 = lg_read(sreg, offset, n_bytes)
  3021.  
  3022.     acc = regCode(0,n_bytes)
  3023.  
  3024.     result = dif(op1, regFetch(acc))# Just for the flags
  3025.  
  3026.     if op1 ==  regFetch(acc):       # Accumulator EAX, AX, or AL
  3027. #       Flags["ZF"].setValue(1)
  3028.         if modrm_byte >= 0xc0:
  3029.             regStore(dest,op2)
  3030.         else:
  3031.             lg_write(sreg,offset,op2,n_bytes)
  3032.     else:
  3033. #       Flags["ZF"].setValue(0)
  3034.         regStore(acc,op1)
  3035.  
  3036. def DoCmpXchg8b(byte,sreg,ads,os):
  3037.         (sreg, offset) = GetOffset(modrm_byte, ads, sreg)
  3038.         dest_L = lg_read(sreg, offset, 4)
  3039.         dest_H = lg_read(sreg, offset + 4, 4)
  3040.         if dest_L == regFetch(0) and dest_H == regFetch(2): #dest=EDX:EAX
  3041.             Flags["ZF"].setValue(1)
  3042.             lg_write(sreg,offset, regFetch(3))
  3043.             lg_write(sreg,offset + 4,regFetch(1))
  3044.         else:
  3045.             Flags["ZF"].setValue(0)
  3046.             regStore(0,dest_L)       #EAX
  3047.             regStore(2,dest_H)              #EDX
  3048.  
  3049.  
  3050.  
  3051. def DoCpuid():
  3052.     getEAX = regFetch(0)
  3053.     if getEAX == 0:
  3054.         regStore(0,1)
  3055.         regStore(3,0x65646957) #Wide
  3056.         regStore(2,0x2072656e) #ner
  3057.         regStore(1,0x53706d43) #CmpS
  3058.     else:
  3059.         raise x86exception('fault', 101, -1,"EAX > 0 not implemented")
  3060.  
  3061. def DoCall(byte, os):
  3062.     n_bytes = os >> 3   # opcodes e8, 9a
  3063.     prog.call_depth = prog.call_depth + 1
  3064.  
  3065.     if byte == 0xe8:
  3066.         delta_EIP = fetch_code(-n_bytes)
  3067.         branch_EIP = EIP.getvalue() + delta_EIP
  3068. #       branch_EIP = branch_EIP & ((1 << n_bytes) -1)
  3069.         branch_EIP = branch_EIP & ((1 << os) -1)
  3070.         push(EIP.getvalue(), n_bytes)
  3071.         EIP.setvalue(branch_EIP)
  3072.     elif byte == 0x9a:
  3073.         NewOffset = fetch_code(n_bytes)
  3074.         NewSel = fetch_code(2)
  3075.         push(segReg[CS].get(), n_bytes)
  3076.         push(EIP.getvalue(), n_bytes)
  3077.         DoGoFar(NewSel, NewOffset, os, jump_not_call=False)
  3078.  
  3079.  
  3080. def DoConv(byte, os):
  3081.     n_bytes = os >> 3
  3082.     if byte == 0x98:
  3083.         if archnum < 3:
  3084.             raise x86exception('fault', 6, -1,"Invalid instruction")
  3085.         dest = regCode(0,n_bytes) #EAX or AX
  3086.         source = regCode(0 ,n_bytes >>1)
  3087.         x = regFetch(source)
  3088.         if n_bytes == 4:
  3089.             if x > 32767:
  3090.                 x = x -65536 + 0x100000000
  3091.         elif n_bytes == 2:
  3092.             if x > 127:
  3093.                 x = x - 256 + 65536
  3094.     else:   # 0x99
  3095.         dest = regCode(2,n_bytes) #EDX or DX
  3096.         source = regCode(0,n_bytes)
  3097.         if n_bytes == 4:
  3098.             if regFetch(source) > 0x7ffffffff:
  3099.                 x = 0xffffffff
  3100.             else:
  3101.                 x = 0
  3102.         elif n_bytes == 2:
  3103.             if regFetch(source) > 32767:
  3104.                 x = 65535
  3105.             else:
  3106.                 x = 0
  3107.     regStore(dest, x)
  3108.        
  3109.  
  3110. def DoEnter(os):
  3111.     frame_size = fetch_code(2)
  3112.     level = fetch_code(1) & 31
  3113.  
  3114.     n_bytes = os >> 3
  3115.     stackp = regCode(4, n_bytes) # ESP or SP
  3116.     basep = regCode(5, n_bytes) #EBP or BP
  3117.  
  3118.     push(regFetch(basep), n_bytes)
  3119.  
  3120.     framePtr = regFetch(stackp, n_bytes)  # BP ok ??
  3121.  
  3122.     for i in range(1, level):
  3123.         regStore(basep, regFetch(basep) - n_bytes)
  3124.         offset = regFetch(basep)
  3125.         push(lg_read(SS, offset, n_bytes), n_bytes)
  3126.  
  3127.     push(framePtr, n_bytes)
  3128.     regStore(basep, framePtr)
  3129.  
  3130.     if descrVec[SS].DefaultAttr:
  3131.         stack_reg =  4            # ESP
  3132.     else:
  3133.         stack_reg =  12           # SP
  3134.  
  3135.     pointer = regFetch(stack_reg) - frame_size
  3136.     regStore(stack_reg,pointer)
  3137.  
  3138. def DoFEFF(byte,sreg,ads,os,lock_flag):
  3139. #
  3140. #  INC, DEC, CALL, JMP and PUSH
  3141. #
  3142.     width_bit = byte & 1
  3143.     modrm_byte = fetch_code(1)
  3144.     op_num = (modrm_byte >> 3) & 7
  3145.     n_bytes = operand_size(os, width_bit)
  3146.     rm_bits = modrm_byte & 7
  3147.    
  3148.     if width_bit == 0 and op_num > 1:
  3149.         raise x86exception('fault', 6, -1,"Invalid instruction")
  3150.     elif op_num < 2:
  3151.         save_CF = Flags["CF"].getValue()
  3152.         if modrm_byte >= 0xc0 and lock_flag:
  3153.             raise x86exception('fault', 6, -1,"Invalid instruction")
  3154.         elif modrm_byte >= 0xc0:
  3155.             dest = regCode(rm_bits,n_bytes)
  3156.             if op_num == 0:
  3157.                 regStore(dest, sum(regFetch(dest),1,n_bytes<< 3))
  3158.             elif op_num == 1:
  3159.                 regStore(dest, dif(regFetch(dest),1,n_bytes<< 3))
  3160.         else:
  3161.             (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  3162.             mem_num = lg_read(sreg, offset, n_bytes)
  3163.             if op_num == 0:
  3164.                 mem_num = sum(mem_num, 1, n_bytes << 3)
  3165.             elif op_num == 1:
  3166.                 mem_num = dif(mem_num, 1, n_bytes << 3)
  3167.             lg_write(sreg, offset, mem_num, n_bytes)
  3168.         Flags["CF"].setValue(save_CF)
  3169.     elif lock_flag:
  3170.         raise x86exception('fault', 6, -1,"Invalid instruction")
  3171.     elif op_num == 2 or op_num == 4: # Near Call or Jump r/m
  3172.         if modrm_byte >= 0xc0:
  3173.             source = regCode(rm_bits,n_bytes)
  3174.             branch_EIP = regFetch(source)
  3175.         else:
  3176.             (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  3177.             branch_EIP = lg_read(sreg, offset, n_bytes)
  3178.             if os == 16: branch_EIP &= 65535
  3179.             if op_num == 2:
  3180.                 push(EIP.getvalue(), n_bytes)
  3181.                 prog.call_depth = proc.call_depth + 1
  3182.         EIP.setvalue(branch_EIP)
  3183.     elif op_num == 3 or op_num == 5: # Far Call or Jump r/m
  3184.         if modrm_byte >= 0xc0:
  3185.             raise x86exception('fault', 6, -1,"Invalid instruction")
  3186.         else:
  3187.             (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  3188.             new_offset = lg_read(sreg, offset, n_bytes)
  3189.             new_sel = lg_read(sreg, offset + n_bytes, 2)
  3190.             if op_num  == 3:
  3191.                 prog.call_depth = prog.call_depth + 1
  3192.                 push(segReg[CS].get(), n_bytes)
  3193.                 push(EIP.getvalue(), n_bytes)
  3194.                 jmp_not_call = False
  3195.             else:
  3196.                 jmp_not_call = True
  3197.             DoGoFar(new_sel,new_offset, os, jmp_not_call)
  3198.     elif  op_num == 6: # Push rmv
  3199.         if modrm_byte >= 0xc0:
  3200.             source = regCode(rm_bits, n_bytes)
  3201.             x = regFetch(source)
  3202.         else:
  3203.             (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  3204.             x = lg_read(sreg, offset, n_bytes)
  3205.         push(x, n_bytes)
  3206.     else:
  3207.         raise x86exception('fault', 6, -1,"Invalid instruction")
  3208.  
  3209. def DoImul3(byte,sreg,ads,os):
  3210.  
  3211.     n_bytes = operand_size(os, 1)
  3212.  
  3213.     if byte == 0x69:
  3214.         imm_width_bit = 1
  3215.     elif byte == 0x6b:
  3216.         imm_width_bit = 0
  3217.     elif byte == 0xaf:
  3218.         imm_width_bit = None
  3219.  
  3220.     byte = fetch_code(1)
  3221.     reg_bits = (byte >> 3) & 7
  3222.     rm_bits = byte & 7
  3223.     dest = regCode(reg_bits, n_bytes)
  3224.  
  3225.     if imm_width_bit == None:
  3226.         op1_num = regFetch(dest)
  3227.     else:
  3228.         n_imm_bytes = operand_size(os, imm_width_bit)
  3229.         op1_num = fetch_code(-n_imm_bytes)
  3230.  
  3231. #   print(n_imm_bytes, op1_num)
  3232.  
  3233.     if byte >= 0xc0:
  3234.         source = regCode(rm_bits, n_bytes)
  3235.         op2_num = regFetch(source)
  3236.     else:
  3237.         sreg,offset = GetOffset(byte,ads,sreg)
  3238.         op2_num = lg_read(sreg,offset,n_bytes)
  3239.     y, x = signed_prod(op1_num, op2_num, n_bytes)
  3240.     regStore(dest,x)
  3241.  
  3242.  
  3243. def DoIncDec(byte,os=32):  
  3244.     """ Increment Decrement Function for opcodes (4x)"""
  3245.     n_bytes= os >> 3
  3246.  
  3247.     dest = regCode(byte&7,n_bytes)
  3248.     save_CF = Flags["CF"].getValue()
  3249.     if byte > 0x47:
  3250.         x = dif(regFetch(dest),1,os)
  3251.     else:
  3252.         x = sum(regFetch(dest),1,os)
  3253.     regStore(dest,x)
  3254.     Flags["CF"].setValue(save_CF)
  3255.  
  3256. def DoInOut(byte,ads, os):
  3257.     n_bytes = operand_size(os,byte&1)
  3258.     n_address_bytes = ads >> 3
  3259.     if byte&3 < 2:
  3260.         signal.input_register = regCode(0,n_bytes)
  3261.         if byte == 0xe4 or byte == 0xe5:
  3262.             port_num = fetch_code(1)
  3263.         elif byte == 0xec or byte == 0xed:
  3264.             port_num = regFetch(10)             #DX
  3265.         else:
  3266.             port_num = regFetch(10)             #DX
  3267.             pointer_reg = regCode(7, n_address_bytes)
  3268.             if n_bytes == 4:
  3269.                 signal.input_register = pointer_reg
  3270.             elif n_bytes == 2:
  3271.                 signal.input_register = pointer_reg & 14
  3272.             elif n_bytes == 1:
  3273.                 signal.input_register = pointer_reg & 13
  3274.         if port_num != 0:
  3275.             raise x86exception('fault', 102, -1,"Edlinas input port is 0")
  3276.         prog.set_execstate('blocked')
  3277.     else:
  3278.         source = regCode(0,n_bytes)
  3279.         num = regFetch(source)
  3280.         if byte == 0xe6 or byte == 0xe7:
  3281.             port_num = fetch_code(1)
  3282.         elif byte == 0xee or byte == 0xef:
  3283.             port_num = regFetch(10)             #DX
  3284.         else:
  3285.             port_num = regFetch(10)             #DX
  3286.             pointer_reg = regCode(6, n_address_bytes)
  3287.             num = lg_read(ES, regFetch(pointer_reg), n_bytes)
  3288.             if Flags["DF"].getValue() == 0:
  3289.                 regStore(pointer_reg, regFetch(pointer_reg) + n_bytes)
  3290.             else:
  3291.                 regStore(pointer_reg, regFetch(pointer_reg) - n_bytes)
  3292.             if signal.pending_repeat:
  3293.                 handle_repeat(n_address_bytes)
  3294.         if port_num != 1:
  3295.             raise x86exception('fault', 103, -1,"Edlinas output port is 1")
  3296.         print_feedback( "OUTPUT: " + str(num) + "    ")
  3297.         print_output(str(num))
  3298.  
  3299. def DoInt():
  3300.     interrupt_number = fetch_code(1)
  3301.     raise x86exception('fault', interrupt_number, -1,
  3302.                                         "Software interrupt number: " + str(interrupt_number))
  3303. def DoInto():
  3304.     if Flags["OF"].getValue():
  3305.         raise x86exception('fault', 4, -1, "Integer overflow")
  3306.    
  3307. def DoJcond(byte,os):
  3308. #  
  3309. # Handle 7x short jumps and 0F 8x long jumps
  3310. #
  3311.     n_bytes = operand_size(os, (byte >> 4) - 7)
  3312.     jump_num = byte & 15
  3313.     delta_EIP = fetch_code(-n_bytes)
  3314. #   print_feedback( "delta_EIP = " + str(delta_EIP))
  3315.     branch_EIP = EIP.getvalue() + delta_EIP
  3316.     assert branch_EIP >= 0
  3317.     if jump_num == 0 and Flags["OF"].getValue() == 1:
  3318.         EIP.setvalue(branch_EIP)
  3319.     elif jump_num == 1 and Flags["OF"].getValue() == 0:
  3320.         EIP.setvalue(branch_EIP)
  3321.     elif jump_num == 2 and Flags["CF"].getValue() == 1:
  3322.         EIP.setvalue(branch_EIP)
  3323.     elif jump_num == 3 and Flags["CF"].getValue() == 0:
  3324.         EIP.setvalue(branch_EIP)
  3325.     elif jump_num == 4 and Flags["ZF"].getValue() == 1:
  3326.         EIP.setvalue(branch_EIP)
  3327.     elif jump_num == 5 and Flags["ZF"].getValue() == 0:
  3328.         EIP.setvalue(branch_EIP)
  3329.     elif jump_num == 6 and Flags["CF"].getValue()| Flags["ZF"].getValue() == 1:
  3330.         EIP.setvalue(branch_EIP)
  3331.     elif jump_num == 7 and Flags["CF"].getValue()| Flags["ZF"].getValue() == 0:
  3332.         EIP.setvalue(branch_EIP)
  3333.     elif jump_num == 8 and Flags["SF"].getValue() == 1:
  3334.         EIP.setvalue(branch_EIP)
  3335.     elif jump_num == 9 and Flags["SF"].getValue() == 0:
  3336.         EIP.setvalue(branch_EIP)
  3337.     elif jump_num == 10 and Flags["PF"].getValue() == 1:
  3338.         EIP.setvalue(branch_EIP)
  3339.     elif jump_num == 11 and Flags["PF"].getValue() == 0:
  3340.         EIP.setvalue(branch_EIP)
  3341.     elif jump_num == 12 and Flags["SF"].getValue() != Flags["OF"].getValue():
  3342.         EIP.setvalue(branch_EIP)
  3343.     elif jump_num == 13 and Flags["SF"].getValue() == Flags["OF"].getValue():
  3344.         EIP.setvalue(branch_EIP)
  3345.     elif jump_num == 14:
  3346.         if Flags["SF"].getValue()!= Flags["OF"].getValue()or Flags["ZF"].getValue() == 1:
  3347.             EIP.setvalue(branch_EIP)
  3348.     elif jump_num == 15:
  3349.         if Flags["SF"].getValue()== Flags["OF"].getValue() and Flags["ZF"].getValue() == 0:
  3350.             EIP.setvalue(branch_EIP)
  3351.  
  3352. def DoJmp(byte, os):   
  3353.     n_bytes = operand_size(os, 0xeb - byte)
  3354.  
  3355.     if byte == 0xe9 or byte == 0xeb:
  3356.         delta_EIP = fetch_code(-n_bytes)
  3357.         branch_EIP = EIP.getvalue() + delta_EIP
  3358.         if branch_EIP > 0xffffffff:
  3359.             branch_EIP = branch_EIP & 0xffffffff
  3360.         EIP.setvalue(branch_EIP)
  3361.     elif byte == 0xea:
  3362.         offset = fetch_code(n_bytes)
  3363.         sel = fetch_code(2)
  3364.         DoGoFar(sel, offset, os, True)
  3365.  
  3366.  
  3367. def DoGoFar(new_sel,new_offset, os, jmp_not_call):
  3368.     raise x86exception('fault', 101, -1,"Instruction not implemented")
  3369.  
  3370. def DoLahf():
  3371.     ah = getFlags(2) #SF,ZF,AF,PF,CF
  3372.     regStore(20, ah)
  3373.    
  3374.  
  3375. def DoLea(sreg,ads,os):
  3376.     n_bytes = os >> 3
  3377.     modrm_byte = fetch_code(1)
  3378.     reg_bits = (modrm_byte >> 3)&7
  3379.     dest = regCode(reg_bits,n_bytes)
  3380.     (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  3381.     regStore(dest, offset)
  3382.  
  3383. def DoLeave(os):
  3384.     if descrVec[SS].DefaultAttr == 1:
  3385.         stack_reg = 4 #ESP
  3386.         basep_reg = 5 #EBP
  3387.     else:
  3388.         stack_reg = 12 #SP
  3389.         basep_reg = 13 #BP
  3390.     regStore(stack_reg,regFetch(basep_reg))
  3391.  
  3392.     n_bytes = os >> 3
  3393.     regStore(regCode(5, n_bytes), pop(n_bytes))
  3394.  
  3395. def DoLodSeg(byte, os):
  3396.     if byte == 0xc5:  # LDS
  3397.         segreg = DS
  3398.     elif byte == 0xc4: # LES
  3399.         segreg = ES
  3400.     elif byte == 0xb4: # LFS
  3401.         segreg = FS
  3402.     elif byte == 0xb5: # LGS
  3403.         segreg = GS
  3404.     n_bytes = os >> 3
  3405.     modrm_byte = fetch_code(1)
  3406.     reg_bits = (modrm_byte >> 3)&7
  3407.     dst = regCode(reg_bits,n_bytes)
  3408.     (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  3409.     off = lg_read(sreg,offset,n_bytes)
  3410.     sel = lg_read(sreg,offset + n_bytes, n_bytes)
  3411.  
  3412.     if mode() == REAL or mode() == VM86:
  3413.         descrVec[segreg].Base.setValue(sel << 4)
  3414.     else:
  3415.         load_data_seg(sel, descrVec[segreg], False)
  3416.     regStore(dst, off)
  3417.     regStore(segreg, sel)
  3418.    
  3419. def DoLoop(byte,ads, os):
  3420.     counter = regCode(1, ads >> 3)
  3421.     jump = fetch_code(1)
  3422.     if jump > 127:
  3423.         jump = jump - 256
  3424.     old_EIP = EIP.getvalue()
  3425.     branch_EIP = EIP.getvalue() + jump
  3426.     if branch_EIP < 0:
  3427.         branch_EIP = branch_EIP + (1 << os)
  3428.     elif branch_EIP >= 1 << os:
  3429.         branch_EIP = branch_EIP & ((1 << os)-1)
  3430.     if os == 16:
  3431.         branch_EIP = (old_EIP & 0xffff0000)| (branch_EIP & 65535)
  3432.     if byte < 0xe4:
  3433.         regStore(counter,regFetch(counter) - 1)
  3434.  
  3435.     if byte == 0xe0 and Flags["ZF"].getValue() == 0 and regFetch(counter) !=  0:
  3436.         EIP.setvalue(branch_EIP)
  3437.     elif byte == 0xe1 and Flags["ZF"].getValue() == 1 and regFetch(counter) !=  0:
  3438.         EIP.setvalue(branch_EIP)
  3439.     elif byte == 0xe2 and regFetch(counter) !=  0:
  3440.         EIP.setvalue(branch_EIP)
  3441.     elif byte == 0xe3 and regFetch(counter) == 0:
  3442.         EIP.setvalue(branch_EIP)
  3443.  
  3444. def DoMov(byte,sgreg,ads,os):                   # MOV for opcodes 8x, 7 < x < C
  3445.     n_bytes = operand_size(os,byte&1)
  3446.     r_isdest = (byte > 0x89)
  3447.     modrm_byte = fetch_code(1)
  3448.     reg_bits = (modrm_byte >> 3)&7
  3449.     rm_bits = modrm_byte & 7
  3450.     if r_isdest :
  3451.         dest = regCode(reg_bits,n_bytes)
  3452.     else:
  3453.         source = regCode(reg_bits,n_bytes)
  3454.         reg_val = regFetch(source)
  3455.  
  3456.     if modrm_byte >= 0xc0:
  3457.         m_reg = regCode(rm_bits,n_bytes)
  3458.         if r_isdest:
  3459.             x = regFetch(m_reg)
  3460.             regStore(dest,x)
  3461.         else:
  3462.             regStore(m_reg,reg_val)
  3463.     else:
  3464.         (sreg, offset) = GetOffset(modrm_byte,ads,sgreg)
  3465. #       print "sreg = ", sreg, "offset = ", offset
  3466.         if r_isdest:
  3467.             x = lg_read(sreg,offset,n_bytes)
  3468.             regStore(dest,x)
  3469.         else:
  3470.             lg_write(sreg,offset, reg_val,n_bytes)
  3471.            
  3472.    
  3473. def DoMovaI(byte,sreg, os): # MOV for opcodes Ax,  x < 4
  3474.     n_bytes = operand_size(os,byte&1)
  3475.     a_reg = regCode(0,n_bytes)
  3476.     offset = fetch_code(n_bytes)
  3477.     if byte < 0xa2:
  3478.         x = lg_read(sreg,offset,n_bytes)
  3479.         regStore(a_reg, x)
  3480.     else:
  3481.         x = regFetch(a_reg)
  3482.         lg_write(sreg,offset, x,n_bytes)
  3483.  
  3484. def DoMovmI(byte, ads, os):  #MOV for opcodes C6, C7
  3485.     n_bytes = operand_size(os,(byte>>3)&1)
  3486.     modrm_byte = fetch_code(1)
  3487.     reg_bits = (modrm_byte >> 3) & 7
  3488.     rm_bits = modrm_byte & 7
  3489.     if reg_bits > 0:
  3490.         raise x86exception('fault', 6, -1,"Invalid instruction")
  3491.     (sreg, offset) = GetOffset(modrm_byte,ads)
  3492.     imm = fetch_code(n_bytes)
  3493.     if modrm_byte >= 0xc0:
  3494.         m_reg = regCode(rm_bits,n_bytes)
  3495.         regStore(m_reg,imm)
  3496.     else:
  3497.         lg_write(sreg,offset, imm, n_bytes)
  3498.  
  3499. def DoMovrI(byte,os):   # MOV for opcodes Bx
  3500.     n_bytes = operand_size(os,(byte>>3)&1)
  3501.     dest = regCode(byte&7,n_bytes)
  3502.     imm = fetch_code(n_bytes)
  3503.     regStore(dest,imm)
  3504.  
  3505. def DoMovs(byte,sreg,ads,os):   #Mov for opcodes 8C, 8E
  3506.     modrm_byte = fetch_code(1)
  3507.     reg_bits = (modrm_byte >> 3) & 7
  3508.     rm_bits = modrm_byte & 7
  3509.     segreg = regCode(reg_bits, 5)
  3510.     if byte == 0x8e:  # Mov segreg, rm
  3511.         desc = descrVec[reg_bits]
  3512.         if modrm_byte >= 0xc0:
  3513.                 source = regCode(rm_bits, 2)
  3514.                 sel = regFetch(source)
  3515.         else:
  3516.                 sreg, offset = GetOffset(modrm_byte,ads,sreg)
  3517.                 sel = lg_read(sreg,offset,2)
  3518.         if mode() == PROTECTED:
  3519.             if segreg == SS:
  3520.                 load_SS(sel, desc, False)
  3521.             else:
  3522.                 load_data_seg(sel, desc, False)
  3523.         else:
  3524.             desc.Valid.setValue(True)
  3525.             desc.Base.setValue(sel << 4)
  3526.             desc.Limit.setValue(0xFFFF)
  3527.             desc.DefaultAttr.setValue(False)
  3528.             desc.Readable.setValue(True)
  3529.             desc.Writable.setValue(True)
  3530.             desc.ExpandDown.setValue(False)
  3531.             desc.Executable.setValue(False)
  3532.         regStore(segreg, sel)
  3533.     elif byte == 0x8c: # Mov rm, segreg
  3534.         x = regFetch(segreg)
  3535.         if modrm_byte >= 0xc0:
  3536.                 dest = regCode(rm_bits,2)
  3537.                 regStore(dest,x)
  3538.         else:
  3539.                 sreg, offset = GetOffset(modrm_byte,ads,sreg)
  3540.                 lg_write(sreg, offset, x, 2)
  3541.  
  3542. def DoMovt(byte2):
  3543.     modrm_byte = fetch_code(1)
  3544.     reg_bits = (modrm_byte >> 3) & 7
  3545.     rm_bits = modrm_byte & 7
  3546.     if byte2 == 0x20 or byte2 == 0x21 or byte2 == 0x24: # Store
  3547.         # destination = genReg[rm_bits]
  3548.         dest = rm_bits
  3549.         source = reg_bits
  3550.         if byte2 == 0x20:  # CR
  3551.             source = source + 48
  3552.         elif byte2 == 0x21: # DR
  3553.             source = source + 32
  3554.         elif byte2 == 0x24: # TR
  3555.             source = source + 40
  3556.     elif byte2 == 0x22 or byte2 == 0x23 or byte2 == 0x26: # Load
  3557.         # source = genReg[rm_bits]
  3558.         source = rm_bits
  3559.         dest = reg_bits
  3560.         if byte2 == 0x22: # CR
  3561.             dest = dest + 48
  3562.         elif byte2 == 0x23: # DR
  3563.             dest = dest + 32
  3564.         elif byte2 == 0x26: # TR
  3565.             dest = dest + 40
  3566.     else:
  3567.         raise x86exception('fault', 6, -1,"Invalid instruction")
  3568.     x = regFetch(source)
  3569.     regStore(dest,x)
  3570.  
  3571.  
  3572. def DoMovx(hb2,sreg,ads,os):
  3573.     source_width_bit = hb2 & 1
  3574.     dest_signext_bit = (hb2 >> 3) & 1
  3575.     n_dest_bytes = os >> 3
  3576.     if source_width_bit == 0:
  3577.         n_source_bytes = 1
  3578.     else:
  3579.         n_source_bytes = n_dest_bytes >> 1
  3580.    
  3581.     modrm_byte = fetch_code(1)
  3582.     reg_bits = (modrm_byte >> 3) & 7
  3583.     dest = regCode(reg_bits, n_dest_bytes)
  3584.  
  3585.     if modrm_byte >= 0xc:
  3586.         rm_bits = modrm_byte & 7
  3587.         source_reg = regCode(rm_bits,n_source_bytes)
  3588.         x = regFetch(source_reg)
  3589.     else:
  3590.         (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  3591.         x = lg_read(sreg,offset,n_source_bytes)
  3592.  
  3593.     if dest_signext_bit:
  3594.         if n_source_bytes == 1:
  3595.             if x > 127:
  3596.                 if n_dest_bytes == 2:
  3597.                     x = (x - 256) + 65536
  3598.                 elif n_dest_bytes == 4:
  3599.                     x = (x - 256) + 0x100000000
  3600.         elif n_source_bytes == 2:
  3601.             #n_dest_bytes == 4
  3602.             if x > 65535:
  3603.                 x = (x - 65536) + 0x100000000
  3604.     regStore(dest, x)
  3605.  
  3606.  
  3607. def DoPop(byte,sreg,ads,os):
  3608.     n_bytes = (os>>3)    # opcodes 5y, y > 7, 8f , 0F A1,A9
  3609.  
  3610.     val = pop(n_bytes)
  3611.  
  3612.     if byte > 0x57 and byte < 0x60:
  3613.         reg_num = regCode(byte & 7, n_bytes)
  3614.         regStore(reg_num, val)
  3615.         return
  3616.     if byte == 0x8f:
  3617.         modrm_byte = fetch_code(1)
  3618.         reg_bits = (modrm_byte >> 3)&7
  3619.         if reg_bits != 0:
  3620.             raise x86exception('fault', 6, -1,"Invalid instruction")
  3621.         if modrm_byte >= 0xc0:
  3622.             mem_bits = modrm_byte &7
  3623.             dest = regCode(mem_bits, n_bytes)
  3624.             regStore(dest,val)
  3625.         else:
  3626.             (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  3627.             lg_write(sreg,offset,val,n_bytes)
  3628.         return
  3629.     if byte < 0x20 and byte&7 == 7:
  3630.         seg_reg = byte >> 3
  3631.         segReg[seg_reg].set(val)
  3632.     elif byte in [0xa1, 0xa9]:      # 0F byte already discarded
  3633.         seg_reg = ((byte -0xa1)>> 3) + 4
  3634.         segReg[seg_reg].set(val)
  3635.     else:
  3636.         raise x86exception('fault', 101, -1,"Instruction not implemented")
  3637.  
  3638. # elif byte < 0x20 and byte & 7 == 6:
  3639. #       src = segReg[byte>>3].get()
  3640. #   else:                  
  3641. #       src = segReg[((byte - 0xa0)>>3) + 4].get()
  3642.  
  3643. def Popf(os):
  3644.     n_bytes = os >> 3
  3645.     if n_bytes == 4:
  3646.         eflg = pop(os) & 0x277fd7
  3647.         setFlags(eflg,4)
  3648.     else:
  3649.         eflg = pop(os)
  3650.         setFlags(eflg,2)
  3651.        
  3652. def DoPusha(os):
  3653.     n_bytes = os >> 3
  3654.     sp_reg = regCode( 4, n_bytes) # ESP or SP
  3655.     stack_pointer = regFetch(sp_reg)
  3656.     push(regCode(0 ,n_bytes), n_bytes)
  3657.     push(regCode(1 ,n_bytes), n_bytes)
  3658.     push(regCode(2 ,n_bytes), n_bytes)
  3659.     push(regCode(3 ,n_bytes), n_bytes)
  3660.     push(stack_pointer, n_bytes)
  3661.     push(regCode(5 ,n_bytes), n_bytes)
  3662.     push(regCode(6 ,n_bytes), n_bytes)
  3663.     push(regCode(7 ,n_bytes), n_bytes)
  3664.  
  3665. def Popa(os):
  3666.     n_bytes = os >> 3
  3667.     regStore(regCode(7 ,n_bytes), pop(n_bytes))
  3668.     regStore(regCode(6 ,n_bytes), pop(n_bytes))
  3669.     regStore(regCode(5 ,n_bytes), pop(n_bytes))
  3670.     pop(n_bytes)
  3671.     regStore(regCode(3 ,n_bytes), pop(n_bytes))
  3672.     regStore(regCode(2 ,n_bytes), pop(n_bytes))
  3673.     regStore(regCode(1 ,n_bytes), pop(n_bytes))
  3674.     regStore(regCode(0 ,n_bytes), pop(n_bytes))
  3675.  
  3676.  
  3677. def DoPush(byte,os):
  3678.     if byte > 0x20 and byte < 0x58:
  3679.         reg_num = regCode( byte & 7, os >> 3)
  3680.         src = regFetch(reg_num)
  3681.     elif byte == 0x6a:
  3682.         src = fetch_code(1)
  3683.         if src > 127:
  3684.             src = src - 256 + (1 << os)
  3685.     elif byte == 0x68:
  3686.         src = fetch_code(os>>3)
  3687.     elif byte < 0x20 and byte & 7 == 6:
  3688.         src = segReg[byte>>3].get()
  3689.     elif byte in [0xa0, 0xa8]:      # 0F byte already discarded
  3690.         src = segReg[((byte - 0xa0)>>3) + 4].get()
  3691.     else:
  3692.         raise x86exception('fault', 101, -1,"Instruction not implemented")
  3693.  
  3694.     push(src,os>>3)
  3695.  
  3696. def Pushf(os):
  3697.     eflg = getFlags(4)
  3698.     eflg = eflg & 0xfcffff  #Clear VM and RF bits
  3699.     if os == 32:
  3700.         push(eflg, 4)
  3701.     else:
  3702.         push(eflg & 0xffff, 2)
  3703.  
  3704. def DoRet(byte, os):   # opcodes c2, c3, ca, cb
  3705. #   prog.call_depth = prog.call_depth - 1
  3706.     n_bytes = os >> 3
  3707.     EIP.setvalue(pop(n_bytes))
  3708.  
  3709.     if byte == 0xca or byte == 0xcb:
  3710.         segReg[CS].set(pop(n_bytes) & 0xffff)
  3711.     if byte == 0xc2 or byte == 0xca:
  3712.         n_popbytes = fetch_code(2)
  3713.     else:
  3714.         n_popbytes = 0
  3715.  
  3716.     if descrVec[CS].DefaultAttr:
  3717.         stack_reg = 4           # ESP
  3718.     else:
  3719.         stack_reg = 12      # SP
  3720.  
  3721.     regStore(stack_reg, regFetch(stack_reg) + n_popbytes)
  3722.  
  3723.     if byte == 0xc2 or byte == 0xc3:
  3724.         return
  3725. #
  3726. #  Far return is not done!
  3727. #
  3728. #
  3729.  
  3730.  
  3731.  
  3732. def DoSahf():
  3733.     ah = regFetch(20)
  3734.     Flags["SF"].setValue(int(ah & 128!=0))
  3735.     Flags["ZF"].setValue(int(ah & 64!=0))
  3736.     Flags["AF"].setValue(int(ah & 16!=0))
  3737.     Flags["PF"].setValue(int(ah & 4!=0))
  3738.     Flags["CF"].setValue(int(ah & 2!=0))
  3739.  
  3740. def Setcond(hb2, sreg,ads):
  3741.     val = 0
  3742.     if hb2 == 0 and Flags["OF"].getValue() == 1:
  3743.         val = 1
  3744.     elif hb2 == 1 and Flags["OF"].getValue() == 0:
  3745.         val = 1
  3746.     elif hb2 == 2 and Flags["CF"].getValue() == 1:
  3747.         val = 1
  3748.     elif hb2 == 3 and Flags["CF"].getValue() == 0:
  3749.         val = 1
  3750.     elif hb2 == 4 and Flags["ZF"].getValue() == 1:
  3751.         val = 1
  3752.     elif hb2 == 5 and Flags["ZF"].getValue() == 0:
  3753.         val = 1
  3754.     elif hb2 == 6 and Flags["CF"].getValue()| Flags["ZF"].getValue() == 1:
  3755.         val = 1
  3756.     elif hb2 == 7 and Flags["CF"].getValue()| Flags["ZF"].getValue() == 0:
  3757.         val = 1
  3758.     elif hb2 == 8 and Flags["SF"].getValue() == 1:
  3759.         val = 1
  3760.     elif hb2 == 9 and Flags["SF"].getValue() == 0:
  3761.         val = 1
  3762.     elif hb2 == 10 and Flags["PF"].getValue() == 1:
  3763.         val = 1
  3764.     elif hb2 == 11 and Flags["PF"].getValue() == 0:
  3765.         val = 1
  3766.     elif hb2 == 12 and Flags["SF"].getValue()!= Flags["OF"].getValue():
  3767.         val = 1
  3768.     elif hb2 == 13 and Flags["SF"].getValue()== Flags["OF"].getValue():
  3769.         val = 1
  3770.     elif hb2 == 14:
  3771.         if Flags["SF"].getValue()!= Flags["OF"].getValue() or Flags["ZF"].getValue() == 1:
  3772.             val = 1
  3773.     elif hb2 == 15:
  3774.         if Flags["SF"].getValue()== Flags["OF"].getValue() and Flags["ZF"].getValue() == 0:
  3775.             val = 1
  3776.     modrm_byte = fetch_code(1)
  3777.     rm_bits = modrm_byte & 7
  3778.     reg_num = regCode(rm_bits, 1) # 1 byte register
  3779.     if modrm_byte  >= 0xc0:
  3780.         regStore(reg_num, val)
  3781.     else:
  3782.         (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  3783.         lg_write(sreg, offset, val, 1)
  3784.    
  3785. def DoShift(byte,sreg,ads,os):
  3786.  
  3787. #
  3788. #  Funnel shift Opcodes  0F Ax, x = 4,5,C & D
  3789. #
  3790. #  First byte opcodes C0, C1, Dx x < 4
  3791. #
  3792.     double_flag = (byte < 0xb0)
  3793.     if double_flag:
  3794.         imm_flag = (byte & 1 == 0)
  3795.         width_bit = 1
  3796.         left_flag = (byte & 8 == 0)
  3797.     else:
  3798.         imm_flag = (byte < 0xd0)
  3799.         width_bit = (byte & 1)
  3800.  
  3801.     n_bytes = operand_size(os, width_bit)
  3802.     bit_len =  (n_bytes << 3)
  3803.     if not imm_flag:
  3804.         if double_flag or (byte & 2 == 2):
  3805.             num_shifts = regFetch(17)   #CL
  3806.         else:
  3807.             num_shifts = 1
  3808.  
  3809.     byte = fetch_code(1)
  3810.     reg_bits = (byte >> 3) & 7
  3811.     rm_bits = byte & 7
  3812.    
  3813.     if double_flag:
  3814.         source =    reg_bits
  3815.         pad = regFetch(source)
  3816.         y = ('{0:0' + str(bit_len)+ 'b}').format(pad)[0:bit_len]
  3817.         if left_flag:
  3818.             op_num = -1
  3819.         else:
  3820.             op_num = -2
  3821.     else:
  3822.         op_num = reg_bits
  3823.  
  3824.     if byte >= 0xc0:
  3825.         dest = rm_bits
  3826.         dest = regCode(dest,n_bytes)
  3827.         x =  ('{0:0' + str(bit_len)+ 'b}').format(regFetch(dest))[0:bit_len]
  3828.     else:
  3829.         sreg,offset = GetOffset(byte,ads,seg_reg = sreg)
  3830.         imm_num = lg_read(sreg,offset,n_bytes)
  3831.         x =  ('{0:0' + str(bit_len)+ 'b}').format(imm_num)[0:bit_len]
  3832.  
  3833.     if imm_flag:
  3834.         num_shifts = fetch_code(1)
  3835.     if num_shifts == 0:
  3836.         return
  3837.  
  3838.     if op_num == 0:                             # ROL
  3839.         x =  x[num_shifts:] + x[:num_shifts]
  3840.         Flags["CF"].setValue(int(x[-1]))
  3841.         if num_shifts == 1:                      #Set if CF does not match most sig bit
  3842.             Flags["OF"].setValue(int(not(Flags["CF"].getValue() == int(x[0])))) #Agarwal p 548
  3843.         else:
  3844.             Flags["OF"].setValue(random.randint(0,1))
  3845.     elif op_num == 1:                           # ROR
  3846.         x = x[bit_len - num_shifts:] + x[:bit_len - num_shifts]
  3847.         Flags["CF"].setValue(int(x[0]))
  3848.         if num_shifts == 1:                      # Set if two most sig bits differ
  3849.             Flags["OF"].setValue(int(not(x[0] == x[1]))) #Agarwal p 548
  3850.         else:
  3851.             Flags["OF"].setValue(random.randint(0,1))
  3852.     elif op_num == 2:                           # RCL
  3853.         x = str(Flags["CF"].getValue()) + x
  3854.         x =  x[num_shifts:] + x[:num_shifts]
  3855.         Flags["CF"].setValue(int(x[0]))
  3856.         x = x[1:]  
  3857.         if num_shifts == 1:                      #Set if CF does not match most sig bit
  3858.             Flags["OF"].setValue(int(not(Flags["CF"].getValue() == int(x[0])))) #Agarwal p 548
  3859.         else:
  3860.             Flags["OF"].setValue(random.randint(0,1))
  3861.     elif op_num == 3:                           # RCR
  3862.         x = str(Flags["CF"].getValue()) + x
  3863.         x = x[bit_len + 1- num_shifts:] + x[:bit_len + 1- num_shifts]
  3864.         Flags["CF"].setValue(int(x[0]))
  3865.         x = x[1:]  
  3866.         if num_shifts == 1:                      # Set if two most sig bits differ
  3867.             Flags["OF"].setValue(int(not(x[0] == x[1]))) #Agarwal p 548
  3868.         else:
  3869.             Flags["OF"].setValue(random.randint(0,1))
  3870.     elif op_num == 4:                           # SHL
  3871.         Flags["CF"].setValue(int(x[num_shifts -1]))
  3872.         x = x[num_shifts:] + ''.zfill(num_shifts)
  3873.         if num_shifts == 1:                      #Set if CF does not match most sig bit
  3874.             Flags["OF"].setValue(int(not(Flags["CF"].getValue() == int(x[0])))) #Agarwal p 548
  3875.         else:
  3876.             Flags["OF"].setValue(random.randint(0,1))
  3877.         Flags["ZF"].setValue(int('1' not in x))
  3878.         Flags["SF"].setValue(int(x[0]))
  3879.     elif op_num == 5:                           # SHR
  3880.         Flags["CF"].setValue(int(x[-num_shifts]))
  3881.         if num_shifts == 1:             #Agarwal p 563
  3882.             Flags["OF"].setValue(int(x[0]))
  3883.         else:
  3884.             Flags["OF"].setValue(random.randint(0,1))
  3885.         x = ''.zfill(num_shifts) + x[:-num_shifts]
  3886.         Flags["ZF"].setValue(int('1' not in x))
  3887.         Flags["SF"].setValue(int(x[0]))
  3888.     elif op_num == 6:
  3889.         raise x86exception('fault', 6, -1,"Invalid instruction")
  3890.     elif op_num == 7:                           # SAR
  3891.         Flags["CF"].setValue(int(x[-num_shifts]))
  3892.         if num_shifts == 1:
  3893.             Flags["OF"].setValue(0)
  3894.         x = ''.join([x[0] for t in range(num_shifts)]) + x[:-num_shifts]
  3895.         Flags["ZF"].setValue(int('1' not in x))
  3896.         Flags["SF"].setValue(int(x[0]))
  3897.     elif op_num == -1:                           # SHLD p 563
  3898.         num_shifts = num_shifts % os
  3899.         Flags["CF"].setValue(int(x[num_shifts]))
  3900.         y = y[:num_shifts]
  3901.         x = x[num_shifts:] + y
  3902.         Flags["OF"].setValue(int(not(Flags["CF"].getValue() == int(x[0])))) #Agarwal p 548
  3903.         Flags["ZF"].setValue(int('1' not in x))
  3904.         Flags["SF"].setValue(int(x[0]))
  3905.         Flags["PF"].setValue(evenParity(int(x,2))) 
  3906.     elif op_num == -2:                           # SHRD p 565
  3907.         num_shifts = num_shifts % os
  3908.         Flags["CF"].setValue(int(x[-num_shifts]))
  3909.         y = y[-num_shifts:]
  3910.         x = y + x[:-num_shifts]
  3911.         Flags["OF"].setValue(int(not(x[0] == x[1])))
  3912.         Flags["ZF"].setValue(int('1' not in x))
  3913.         Flags["SF"].setValue(int(x[0]))
  3914.         Flags["PF"].setValue(evenParity(int(x,2))) 
  3915.  
  3916.     if byte >= 0xc0:
  3917.         regStore(dest,int(x,2))
  3918.     else:
  3919.         lg_write(sreg,offset,int(x,2),n_bytes)
  3920.  
  3921. def DoString(byte, ads, os):
  3922.     n_bytes = operand_size(os, byte &1)
  3923.     n_adbytes = ads >> 3
  3924.     if byte < 0x70:
  3925.         DoInOut(byte, ads, os)
  3926. #       if byte < 0x6e:  #INS
  3927. #           pass
  3928. #       else:            #OUTS
  3929. #           pass
  3930.     else:
  3931.         hb2by2 = (byte & 15) >> 1
  3932.         if hb2by2 == 2:  #MOVS
  3933.             source = regCode(6, n_adbytes) # ESI
  3934.             dest = regCode(7, n_adbytes)   #EDI
  3935.             x = lg_read(DS, regFetch(source), n_bytes)
  3936.             lg_write(ES, regFetch(dest), x, n_bytes)
  3937.             if Flags["DF"].getValue() == 1:
  3938.                 regStore(source,regFetch(source) - n_bytes)
  3939.                 regStore(dest,regFetch(dest) - n_bytes)
  3940.             else:
  3941.                 regStore(source,regFetch(source) + n_bytes)
  3942.                 regStore(dest,regFetch(dest) + n_bytes)
  3943.         elif hb2by2 == 3:#CMPS
  3944.             source = regCode(6, n_adbytes) # ESI
  3945.             dest = regCode(7, n_adbytes)   #EDI
  3946.             x = lg_read(DS, regFetch(source), n_bytes)
  3947.             y = lg_read(ES, regFetch(dest), n_bytes)
  3948.             z = dif(x,y,n_bytes<<3)
  3949.             if Flags["DF"].getValue() == 1:
  3950.                 regStore(source,regFetch(source) - n_bytes)
  3951.                 regStore(dest,regFetch(dest) - n_bytes)
  3952.             else:
  3953.                 regStore(source,regFetch(source) + n_bytes)
  3954.                 regStore(dest,regFetch(dest) + n_bytes)
  3955.         elif hb2by2 == 5:#STOS
  3956.             source = regCode(0, n_bytes) # EAX
  3957.             dest = regCode(7, n_adbytes)   #EDI
  3958.             lg_write(ES, regFetch(dest), regFetch(source), n_bytes)
  3959.             if Flags["DF"].getValue() == 1:
  3960.                 regStore(dest,regFetch(dest) - n_bytes)
  3961.             else:
  3962.                 regStore(dest,regFetch(dest) + n_bytes)
  3963.         elif hb2by2 == 6: # LODS
  3964.             source = regCode(7, n_adbytes) # EDI
  3965.             dest = regCode(0, n_bytes)   #EAX
  3966.             x = lg_read(DS,regFetch(source), n_bytes)
  3967.             regStore(dest, x)
  3968.             if Flags["DF"].getValue() == 1:
  3969.                 regStore(dest,regFetch(source) - n_bytes)
  3970.             else:
  3971.                 regStore(dest,regFetch(source) + n_bytes)
  3972.         elif hb2by2 == 7:#SCAS
  3973.             source = regCode(0, n_bytes) # EAX
  3974.             dest = regCode(7, n_adbytes)   #EDI
  3975.             x = regFetch(source)
  3976.             y = lg_read(ES, regFetch(dest), n_bytes)
  3977.             z = dif(x,y,n_bytes<<3)
  3978.             if Flags["DF"].getValue() == 1:
  3979.                 regStore(dest,regFetch(dest) - n_bytes)
  3980.             else:
  3981.                 regStore(dest,regFetch(dest) + n_bytes)
  3982.     if signal.pending_repeat:
  3983.         handle_repeat(n_adbytes)
  3984.  
  3985. def DoTest(byte,sreg,ads,os):
  3986.     n_bytes = operand_size(os, byte&1)
  3987.  
  3988.     if byte < 0xa0:
  3989.         byte = fetch_code(1)
  3990.  
  3991.         reg_bits = (byte >> 3) & 7
  3992.         rm_bits = byte & 7
  3993.         dest = regCode(reg_bits, n_bytes)
  3994.         if byte >= 0xc0:
  3995.             source = rm_bits
  3996.             bblog(regFetch(dest),regFetch(source), 4, n_bytes)
  3997.         else:
  3998.             sgreg, offset = GetOffset(byte,ads,seg_reg=sreg)
  3999.             imm_num = lg_read(sgreg,offset,n_bytes)
  4000.             bblog(regFetch(dest), imm_num, 4, n_bytes)
  4001.     else:
  4002.         dest = regCode(0, n_bytes)    #EAX = 0
  4003.         imm_num = fetch_code(n_bytes)
  4004.         bblog(regFetch(dest), imm_num, 4, n_bytes)
  4005.  
  4006. def DoUnM(byte,sreg,ads,os,lock_flag = 0):
  4007. #
  4008. #        Unary Operations, opcodes F6 and F7
  4009. #
  4010. #  /r, 0:TEST imm, 2:NOT,  3:NEG, 4:MUL, 5:IMUL, 6:DIV, 7:IDIV
  4011. #
  4012.     n_bytes = operand_size(os, byte & 1)
  4013.    
  4014.     byte = fetch_code(1)
  4015.     reg_bits = (byte >> 3) & 7
  4016.     rm_bits = byte & 7
  4017.  
  4018.     if reg_bits == 1:
  4019.         raise x86exception('fault', 6, -1,"Invalid instruction")
  4020.  
  4021.     if byte >= 0xc0 and lock_flag:
  4022.         raise x86exception('fault', 6, -1,"Lock Invalid")
  4023.     elif byte >= 0xc0:
  4024.         dest = regCode(rm_bits ,n_bytes)
  4025.         mem_num = regFetch(dest)
  4026.     else:
  4027.         sreg, offset = GetOffset(byte, ads, sreg)
  4028.         mem_num = lg_read(sreg, offset, n_bytes)
  4029.  
  4030.     if reg_bits == 0:  
  4031.         imm_num = fetch_code(n_bytes)
  4032.         bblog(mem_num, imm_num, 4, n_bytes)
  4033.     elif reg_bits  == 2:
  4034.         mem_num = (1 << (n_bytes << 3))- 1 - mem_num
  4035.     elif reg_bits  == 3:
  4036.         mem_num = dif(0, mem_num, n_bytes<< 3)
  4037.     else:
  4038. #       accum = regCode(0,n_bytes)
  4039. #       x = regFetch(accum)
  4040.         if n_bytes == 1:
  4041.             if reg_bits > 5:
  4042.                 y = regFetch(20)         # AH
  4043.                 x = regFetch(8)          # AX
  4044.             else:
  4045.                 x = regFetch(16)        # AL
  4046.         elif n_bytes == 2:
  4047.             if reg_bits > 5:
  4048.                 y = regFetch(10)         # DX
  4049.                 x = (y << 16) + regFetch(8)# DX:AX
  4050.             else:
  4051.                 x = regFetch(8)         # AX
  4052.         elif n_bytes == 4:
  4053.             if reg_bits > 5:
  4054.                 y = regFetch(2)          # EDX
  4055.                 x = (y << 32) + regFetch(0)# EDX:EAX
  4056.             else:
  4057.                 x = regFetch(0)
  4058.  
  4059. #       print("1:x = ", x)
  4060. #       print("reg_bits =", reg_bits)
  4061.         if reg_bits == 4:
  4062. #           print("mem_num = ", mem_num)
  4063. #           print("n_bytes = ", n_bytes)
  4064.             y,x = prod(x, mem_num, n_bytes)    
  4065.         elif reg_bits == 5:
  4066.             y,x  = signed_prod(x, mem_num, n_bytes)    
  4067.         elif reg_bits == 6:
  4068.             y,x = divide(x,mem_num, n_bytes)       
  4069.         elif reg_bits == 7:
  4070.             y,x = signed_divide(x,mem_num, n_bytes)    
  4071.  
  4072. #       print("2:x = ", x)
  4073.         if n_bytes == 1:
  4074.             regStore(16, x)         # AL
  4075.             regStore(20, y)         # AH
  4076.         elif n_bytes == 2:
  4077.             regStore( 8, x)         # AX
  4078.             regStore(10, y)         # DX
  4079.         elif n_bytes == 4:
  4080.             regStore(0, x)          # EAX
  4081.             regStore(2, y)          # EDX
  4082.        
  4083.     if reg_bits == 2 or reg_bits == 3:
  4084.         if byte >= 0xc0:
  4085.             regStore(dest, mem_num)
  4086.         else:
  4087.             lg_write(sreg, offset, mem_num, n_bytes)
  4088.  
  4089. def DoXadd(byte,sreg,ads,os):
  4090.     n_bytes = operand_size(os, byte & 1)
  4091.     modrm_byte = fetch_code(1)
  4092.     reg_bits = (modrm_byte >> 3)&7
  4093.     rm_bits = modrm_byte & 7
  4094.     source = regCode(reg_bits, n_bytes)
  4095.     op2 = regFetch(source)
  4096.     temp = op2
  4097.     if modrm_byte >= 0xc0:
  4098.         dest = regCode(rm_bits, n_bytes)
  4099.         op1 = regFetch(dest)
  4100.     else:
  4101.         (sreg, offset) = GetOffset(modrm_byte,ads,sreg)
  4102.         op1 = lg_read(sreg, offset, n_bytes)
  4103. #   op2 = op1
  4104.     regStore(source, op1)
  4105.     result = sum(op1, temp, n_bytes << 3)
  4106.     if modrm_byte >= 0xc0:
  4107.         regStore(dest, result)
  4108.     else:
  4109.         lg_write(sreg, offset, result, n_bytes)
  4110.  
  4111. def DoXch(byte,sreg,ads,os,lock_flag = 0):
  4112.     if byte >= 0x90:
  4113.         n_bytes = operand_size(os, 1)
  4114.         dest = regCode(0, n_bytes)   # EAX = 0
  4115.         source = regCode(byte & 7, n_bytes)
  4116.         x = regFetch(source)
  4117.         regStore(source, regFetch(dest))
  4118.         regStore(dest, x)  
  4119.     else:
  4120.         n_bytes = operand_size(os, byte - 0x86)
  4121.         byte = fetch_code(1)
  4122.         dest = regCode((byte >> 3)&7, n_bytes)
  4123.         if byte >= 0xc0 and lock_flag:
  4124.             raise x86exception('fault', 6, -1,"Invalid instruction")
  4125.         elif byte >= 0xc0:
  4126.             source = byte & 7
  4127.             source = regCode(source, n_bytes)
  4128.             x = regFetch(source)
  4129.             regStore(source, regFetch(dest))
  4130.             regStore(dest, x)
  4131.         else:
  4132.             sreg, offset = GetOffset(byte, ads, sreg)
  4133.             imm_num = lg_read(sreg,offset,n_bytes)
  4134.             x = imm_num
  4135.             imm_num = regFetch(dest)
  4136.             regStore(dest, x)
  4137.             lg_write(sreg, offset, imm_num, n_bytes)
  4138.  
  4139. def Xlat(byte, ads):
  4140.     n_bytes = ads >> 3
  4141.     base = regFetch(regCode(3, n_bytes)) # EBX or BX
  4142.     pointer = base + regFetch(16) # AL
  4143.     regStore(16, lg_read(DS, pointer, 1)) # AL(16) # AL
  4144.  
  4145.  
  4146. def handle_repeat(n_addressbytes):
  4147.     counter_reg = regCode(1,n_addressbytes)  
  4148.     regStore(counter_reg, regFetch(counter_reg) -1)
  4149.     if signal.pending_repeat == "REP":
  4150.         if regFetch(counter_reg) == 0:
  4151.             signal.pending_repeat = ''
  4152.         else:
  4153.             EIP.setvalue(EIP.getvalue() - 1)
  4154.     elif signal.pending_repeat == "REPE":
  4155.         if regFetch(counter_reg) == 0 or Flags["ZF"].getValue() == 1:
  4156.             signal.pending_repeat = ''
  4157.         else:
  4158.             EIP.setvalue(EIP.getvalue() - 1)
  4159.     elif signal.pending_repeat == "REPNE":
  4160.         if regFetch(counter_reg) == 0 or Flags["ZF"].getValue() == 0:
  4161.             signal.pending_repeat = ''
  4162.         else:
  4163.             EIP.setvalue(EIP.getvalue() - 1)
  4164.  
  4165.  
  4166. def dif(a,b,n_bits,carry_flag=0):
  4167.     assert n_bits in [8,16,32], str(n_bits)
  4168.     d = a - b - carry_flag
  4169.  
  4170.     if (a & 15) - (b & 15) - carry_flag < 0:
  4171.         Flags["AF"].setValue(1)             #  AF = 1
  4172.     else:
  4173.         Flags["AF"].setValue(0)             #  AF = 0
  4174.  
  4175.     if a >= 1 << (n_bits -1):
  4176.         az = a - (1 << n_bits)
  4177.     else:
  4178.         az = a
  4179.  
  4180.     if b >= 1 << (n_bits -1):
  4181.         bz = b - (1 <<  n_bits )
  4182.     else:
  4183.         bz = b
  4184.  
  4185.     dz = az - bz - carry_flag
  4186.  
  4187.     if dz < - (1 << (n_bits - 1)) or dz >= (1 << (n_bits - 1)):
  4188.         Flags["OF"].setValue(1)             #  OF = 1
  4189.     else:
  4190.         Flags["OF"].setValue(0)             #  OF = 0
  4191.  
  4192.     if d < 0:
  4193.         Flags["CF"].setValue(1)             #  CF = 1
  4194.         d = d + (1 << n_bits)
  4195.     else:
  4196.         Flags["CF"].setValue(0)             #  CF = 0
  4197.  
  4198.     if d == 0:
  4199.         Flags["ZF"].setValue(1)             #  ZF = 1
  4200.     else:
  4201.         Flags["ZF"].setValue(0)             #  ZF = 0
  4202.  
  4203.     if d >= (1 <<(n_bits -1)):
  4204.         Flags["SF"].setValue(1)             #  SF = 1
  4205.     else:
  4206.         Flags["SF"].setValue(0)             #  SF = 0
  4207.  
  4208.     Flags["PF"].setValue(evenParity(d))
  4209.  
  4210.     return d
  4211.  
  4212.  
  4213. def sum(a,b,n_bits,carry_flag=0):
  4214.     d = a + b + carry_flag
  4215.  
  4216.     if (a & 15) + (b & 15) + carry_flag >= 16:
  4217.         Flags["AF"].setValue(1)             #  AF = 1
  4218.     else:
  4219.         Flags["AF"].setValue(0)             #  AF = 0
  4220.  
  4221.     if a >= 1 << (n_bits -1):
  4222.         az = a - (1 << n_bits)
  4223.     else:
  4224.         az = a
  4225.  
  4226.     if b >= 1 << (n_bits -1):
  4227.         bz = b - (1 << n_bits)
  4228.     else:
  4229.         bz = b
  4230.  
  4231.     dz = az + bz + carry_flag
  4232.     if dz < - (1 << (n_bits - 1)) or dz >= (1 << (n_bits - 1)):
  4233.         Flags["OF"].setValue(1)             #  OF = 1
  4234.     else:
  4235.         Flags["OF"].setValue(0)             #  OF = 0
  4236.  
  4237.     if d >= 1<< n_bits:
  4238.         Flags["CF"].setValue(1)             #  CF = 1
  4239.         d = d - (1 << n_bits)
  4240.     else:
  4241.         Flags["CF"].setValue(0)             #  CF = 0
  4242.  
  4243.     if d == 0:
  4244.         Flags["ZF"].setValue(1)             #  ZF = 1
  4245.     else:
  4246.         Flags["ZF"].setValue(0)             #  ZF = 0
  4247.  
  4248.     if d >= 1 << (n_bits -1):
  4249.         Flags["SF"].setValue(1)             #  SF = 1
  4250.     else:
  4251.         Flags["SF"].setValue(0)             #  SF = 0
  4252.  
  4253.     Flags["PF"].setValue(evenParity(d))
  4254.  
  4255.     return d
  4256.  
  4257. def bblog(a,b,oper_num,n_bits):
  4258.     """Binary bitwise logic operations"""
  4259.     if oper_num == 1:
  4260.         c = a|b
  4261.     elif oper_num == 4:
  4262.         c = a&b
  4263.     elif oper_num == 6:
  4264.         c = a^b
  4265.  
  4266.     if c >= 1<< (n_bits -1):
  4267.         Flags["SF"].setValue(1)             #  SF = 1
  4268.     else:
  4269.         Flags["SF"].setValue(0)             #  SF = 0
  4270.  
  4271.     if c == 0:
  4272.         Flags["ZF"].setValue(1)             #  ZF = 1
  4273.     else:
  4274.         Flags["ZF"].setValue(0)             #  ZF = 0
  4275.  
  4276.     Flags["OF"].setValue(0)             #  OF = 0
  4277.     Flags["CF"].setValue(0)             #  CF = 0
  4278.     Flags["AF"].setValue(random.randint(0,1))
  4279.     Flags["PF"].setValue(evenParity(c))
  4280.     return c
  4281.    
  4282. def evenParity(x,numbits=8):
  4283.     retval = 1
  4284.     y = x
  4285.     for k in range(numbits):
  4286.         retval = retval ^ (y & 1)
  4287.         y = y >> 1
  4288.     return retval
  4289.  
  4290. def push(value,n_bytes):
  4291. #
  4292. #       p 116
  4293. #
  4294. #if descrVec[SS].DefaultAttr:
  4295.     stack_reg = 4                   #ESP
  4296. #else:
  4297. #   stack_reg = 12                  #SP
  4298.    
  4299.     pointer = regFetch(stack_reg) - n_bytes
  4300.     lg_write(2, pointer, value, n_bytes)  # 2 = SS
  4301.     regStore(stack_reg,pointer)
  4302.  
  4303. def pop(n_bytes):
  4304. #
  4305. #       p 118
  4306. #
  4307. #if descrVec[SS].DefaultAttr:
  4308.     stack_reg = 4                   #ESP
  4309. #else:
  4310. #   stack_reg = 12                  #SP
  4311.    
  4312.     pointer = regFetch(stack_reg)
  4313.     retval = lg_read(2, pointer, n_bytes)  # 2 = SS
  4314.     pointer = pointer + n_bytes
  4315.     regStore(stack_reg,pointer)
  4316.     return retval
  4317.  
  4318. def prod(a,b,n_bytes):
  4319.  
  4320.     c = a * b
  4321.     if n_bytes == 1:
  4322.         x = c & 255
  4323.         y = c >> 8
  4324.         flags = (c >= 256)
  4325.         regStore(16, x)             # AL
  4326.         regStore(20, y)             # AH
  4327.     elif n_bytes == 2:
  4328.         x = c & 65535
  4329.         y = c >> 16
  4330.         flags = (c >= 65536)
  4331.         regStore(8, x)             # AX
  4332.         regStore(10, y)             # DX
  4333.     elif n_bytes == 4:
  4334.         x = c & 0xffffffff
  4335.         y = c >> 32
  4336.         flags = (c >= 0x100000000)
  4337.         regStore(0, x)            # EAX
  4338.         regStore(2, y)            # EDX
  4339.  
  4340.     Flags["CF"].setValue(int(flags))
  4341.     Flags["OF"].setValue(int(flags))
  4342.     Flags["SF"].setValue(random.randint(0,1))
  4343.     Flags["ZF"].setValue(random.randint(0,1))
  4344.     Flags["AF"].setValue(random.randint(0,1))
  4345.     Flags["PF"].setValue(random.randint(0,1))
  4346.  
  4347.     return (y,x)
  4348.  
  4349. def signed_prod(a,b,n_bytes,third_arg=None):
  4350.  
  4351.     if n_bytes == 1:
  4352.         if a > 127:
  4353.             a = a - 256
  4354.         if b > 127:
  4355.             b = b - 256
  4356.         c = a * b
  4357.         flags = (c > 127 or c < -128)
  4358.         if c < 0:
  4359.             c = c + 256
  4360.         x = c & 255
  4361.         y = c >> 8
  4362. #       flags = (c >= 256)
  4363. #       regStore(AL, x)
  4364. #       regStore(AH, y)
  4365.     elif n_bytes == 2:
  4366.         if a > 32767:
  4367.             a = a - 65536
  4368.         if b > 32767:
  4369.             b = b - 65536
  4370.         c = a * b
  4371.         flags = (c > 32767 or c < -32768)
  4372.         if c < 0:
  4373.             c = c + 65536
  4374.         x = c & 65535
  4375.         y = c >> 16
  4376. #       flags = (c >= 65536)
  4377. #       regStore(AX, x)
  4378. #       regStore(DX, y)
  4379.     elif n_bytes == 4:
  4380.         if a > 0x7fffffff:
  4381.             a = a - 0x100000000
  4382.         if b > 0x7fffffff:
  4383.             b = b - 0x100000000
  4384.         c = a * b
  4385.         flags = (c > 0x7fffffff or c < -0x80000000)
  4386.         if c < 0:
  4387.             c = c + 0x10000000000000000
  4388.         x = c & 0xffffffff
  4389.         y = c >> 32
  4390. #       flags = (c >= 0x100000000)
  4391. #       regStore(EAX, x)
  4392. #       regStore(EDX, y)
  4393.  
  4394.     Flags["CF"].setValue(int(flags))
  4395.     Flags["OF"].setValue(int(flags))
  4396.     Flags["SF"].setValue(random.randint(0,1))
  4397.     Flags["ZF"].setValue(random.randint(0,1))
  4398.     Flags["AF"].setValue(random.randint(0,1))
  4399.     Flags["PF"].setValue(random.randint(0,1))
  4400.  
  4401.     return (y,x)
  4402.  
  4403. def divide(a,b,n_bytes):
  4404.  
  4405.     if b == 0:
  4406.         raise x86exception('fault', 0, -1,"Division overflow")
  4407.        
  4408.     q = a // b
  4409.     r = a % b
  4410.  
  4411.     if q >= (1 << (n_bytes << 3)):
  4412.         raise x86exception('fault', 0, -1,"Division overflow")
  4413.  
  4414.     Flags["SF"].setValue(random.randint(0,1))
  4415.     Flags["ZF"].setValue(random.randint(0,1))
  4416.     Flags["AF"].setValue(random.randint(0,1))
  4417.     Flags["PF"].setValue(random.randint(0,1))
  4418.     Flags["CF"].setValue(random.randint(0,1))
  4419.     Flags["OF"].setValue(random.randint(0,1))
  4420.  
  4421.     return (r,q)
  4422.  
  4423. def signed_divide(a,b,n_bytes):
  4424.  
  4425.     if b == 0:
  4426.         raise x86exception('fault', 0, 0, "Division Overflow")
  4427.     if n_bytes == 1:
  4428.         a_neg = (a > 32767)
  4429.         b_neg = (b > 127)
  4430.         if a_neg:
  4431.             a = 65536 - a
  4432.         if b_neg:
  4433.             b = 256 - b
  4434.         q = a // b
  4435.         if q > 128 or a_neg == b_neg and q == 128:
  4436.             raise x86exception('fault', 0, 0, "Division Overflow")
  4437.         r = a % b
  4438.         if r == 0:
  4439.             if a_neg != b_neg:
  4440.                     q = 256 - q
  4441.         else:
  4442.             if a_neg != b_neg:
  4443.                 q = 255 - q
  4444.                 r = b - r
  4445.             if b_neg:
  4446.                 r = 256 - r
  4447. #       regStore(AL, q)
  4448. #       regStore(AH, r)
  4449.     elif n_bytes == 2:
  4450.         a_neg = (a > 0x7fffffff)
  4451.         if a_neg:
  4452.             a = 0x100000000 - a
  4453.         b_neg = (b > 32767)
  4454.         if b_neg:
  4455.             b = 65536 - b
  4456.         q = a // b
  4457.         if q > 65536 or a_neg == b_neg and q == 65536:
  4458.             raise x86exception('fault', 0, 0, "Division Overflow")
  4459.         r = a % b
  4460.         if r == 0:
  4461.             if a_neg != b_neg:
  4462.                 q = 65536 - q
  4463.         else:
  4464.             if a_neg != b_neg:
  4465.                 q = 65535 - q
  4466.                 r = b - r
  4467.             if b_neg:
  4468.                 r = 65536 - r
  4469. #       regStore(AX, q)
  4470. #       regStore(DX, r)
  4471.     elif n_bytes == 4:
  4472.         a_neg = (a > 0x7fffffffffffffff)
  4473.         if a_neg:
  4474.             a = 0x10000000000000000 - a
  4475.         b_neg = (b > 0x7fffffff)
  4476.         if b_neg:
  4477.             b = 0x100000000 - b
  4478.         q = a//b
  4479.         if q > 0x100000000 or a_neg == b_neg and q == 0x100000000:
  4480.             raise x86exception('fault', 0, 0, "Division Overflow")
  4481.         r = a % b
  4482.         if r == 0:
  4483.             if a_neg != b_neg:
  4484.                 q = 0x100000000 - q
  4485.         else:
  4486.             if a_neg != b_neg:
  4487.                 q = 0xffffffff - q
  4488.                 r = b - r
  4489.             if b_neg:
  4490.                 r = 0x100000000 - r
  4491. #       regStore(EAX, q)
  4492. #       regStore(EDX, r)
  4493.     Flags["CF"].setValue(random.randint(0,1))
  4494.     Flags["OF"].setValue(random.randint(0,1))
  4495.     Flags["SF"].setValue(random.randint(0,1))
  4496.     Flags["ZF"].setValue(random.randint(0,1))
  4497.     Flags["AF"].setValue(random.randint(0,1))
  4498.     Flags["PF"].setValue(random.randint(0,1))
  4499.  
  4500.     return (r,q)
  4501.  
  4502.  
  4503. def input_data(datum):
  4504.     try:
  4505.         num = int(datum)
  4506.     except:
  4507.         print_feedback("Bad input    ")
  4508.         return
  4509.     if signal.input_register == 0:                  # EAX
  4510.         n_bits = 32
  4511.     elif signal.input_register == 8:                # AX
  4512.         n_bits = 16
  4513.     elif signal.input_register == 16:               # AL
  4514.         n_bits = 8
  4515.     else:
  4516.         n_bits = 1 << ((signal.input_register & 3) + 2)
  4517.         n_bytes = n_bits >> 3
  4518.         pointer_reg = signal.input_register | 3   # EDI or DI
  4519.         n_address_bytes = 32 // (pointer_reg + 1)
  4520.  
  4521.     if num < 1<< n_bits and num >= -(1<<(n_bits -1)):
  4522.         if num < 0:
  4523.             num = num  + (1 << n_bits)
  4524.         if signal.input_register & 7 == 0:
  4525.             regStore(signal.input_register,num)
  4526.         else:
  4527.             lg_write(ES, regFetch(pointer_reg), num, n_bytes)
  4528.             if Flags["DF"].getValue() == 0:
  4529.                 regStore(pointer_reg, regFetch(pointer_reg) + n_bytes)
  4530.             else:
  4531.                 regStore(pointer_reg, regFetch(pointer_reg) - n_bytes)
  4532.             if signal.pending_repeat:
  4533.                 handle_repeat(n_address_bytes)
  4534.         assert prog.execstate == 'blocked'
  4535.         prog.set_current_inst(instoffset = (EIP.getvalue() - prog.load_origin))
  4536.         prog.set_execstate(prog.previous_state)
  4537.     else:
  4538.         print_feedback("input not in " + str(n_bits) + " bit range    ")
  4539. #
  4540. #  End of the Fetch Execute Section
  4541. #
  4542.        
  4543.  
  4544. ##############################################################
  4545. #
  4546. #  x86 Program section.
  4547. #
  4548. ##############################################################
  4549.  
  4550.  
  4551. class Line:
  4552.     count = 0
  4553.     def __init__(self, source, processed_line):
  4554.         self.instoffset = 0
  4555.         self.label = ''
  4556.         self.mnemonic = ''
  4557.         self.displabel = ''
  4558.         self.dispcode = 0
  4559.         # dispwidth = 1 << ((dispcode & 7) >> 1)
  4560.         self.source = source
  4561.         self.hexcode = processed_line
  4562.         self.instlen = len(processed_line)>>1
  4563.  
  4564. class Program:
  4565.  
  4566.     def __init__(self, load_origin = 0):
  4567.         dummy_line = Line("Place holder", '')
  4568.         dummy_line.instoffset = -1
  4569.         terminal_line = Line("Terminal Line", '')
  4570.         self.codelist = [dummy_line, terminal_line]
  4571.         self.viewlist = []
  4572.         self.current_inst = 1
  4573.         self.call_depth = 0
  4574.         self.filename = ''
  4575.         self.execstate = 'inserting'
  4576.         self.previous_state = ''
  4577.         self.pace = 1000             # milliseconds
  4578.         self.unresolved_labels = []
  4579.         self.duplicate_labels = []
  4580.         self.label_resolve = {}
  4581.         self.stored_command = ''
  4582.         self.execstack = []
  4583.         self.execstackpointer = 0
  4584.         self.store_origin = -32
  4585.         self.tabwidth = 8
  4586.         self.editstack = []
  4587.         self.load_origin = load_origin
  4588.  
  4589.     def set_execstate(self, new_state):
  4590.         assert new_state in ['inserting', 'changing', 'stepping', 'blocked', 'interpreting','running']
  4591.         old_state = self.previous_state
  4592.         self.previous_state = self.execstate
  4593.         self.execstate = new_state
  4594.         if old_state == 'interpreting':
  4595.             self.viewlist[self.current_inst - 1].configure(background = "yellow")
  4596.         if new_state == 'inserting':
  4597.             entrybox.configure(state = NORMAL)
  4598.             userbox_label.configure(background = "orange")
  4599.             userbox_label.configure(text = "Enter Command:")
  4600.             entrybox.focus_force()
  4601.         elif new_state == 'changing':
  4602.             entrybox.configure(state = NORMAL)
  4603.             userbox_label.configure(background = "orange")
  4604.             userbox_label.configure(text = "Edit Command:")
  4605.             entrybox.focus_force()
  4606.         elif new_state == 'stepping':
  4607.             entrybox.configure(state = DISABLED)
  4608.             self.refresh()
  4609.             self.execstate = new_state
  4610.             userbox_label.configure(background = "green")
  4611.             userbox_label.configure(text = "Enter Command:")
  4612.             RunBtn.configure(state = NORMAL)
  4613.         elif new_state == 'blocked':
  4614.             userbox_label.configure(background = "red")
  4615.             userbox_label.configure(text = "Enter data:")
  4616.             root.after(self.pace, accept_input)
  4617.             if self.previous_state == 'running':
  4618.                 root.after(self.pace, accept_input)
  4619.             else:
  4620.                 accept_input()
  4621.         elif new_state == 'running':
  4622.             entrybox.configure(state = DISABLED)
  4623.             userbox_label.configure(background = "green")
  4624.             userbox_label.configure(text = "Enter Command:")
  4625.             root.after(self.pace, walk)
  4626.         elif new_state == 'interpreting':
  4627.             entrybox.configure(state = NORMAL)
  4628.             userbox_label.configure(background = "yellow")
  4629.             userbox_label.configure(text = "Enter Command:")
  4630. #           print("self.current_inst = ", self.current_inst)
  4631.             if self.current_inst + 1 < len(self.viewlist):
  4632.                 self.viewlist[self.current_inst - 1].configure(background = "green")
  4633.             entrybox.focus_force()
  4634.  
  4635.     def set_current_inst(self, instoffset= None, instnum = None):
  4636.         if self.execstate == 'interpreting':
  4637.             background_color = "green"
  4638.         else:
  4639.             background_color = "yellow"
  4640.         if instnum == None:
  4641.             for k in range(1,len(self.codelist)):
  4642.                 if self.codelist[k].instoffset == instoffset:
  4643.                     self.current_inst = k
  4644.                     self.viewlist[k-1].configure(background = background_color)
  4645.                 elif self.viewlist[k-1]["background"] != 'white':
  4646.                     self.viewlist[k-1].configure(background = 'white')
  4647.         else:
  4648.             address = self.load_origin
  4649.             for k in range(len(self.codelist)-1):
  4650.                 if k == instnum:
  4651.                     self.current_inst = k + 1
  4652.                     self.viewlist[k].configure(background = background_color)
  4653.                     EIP.setvalue(address)
  4654.                 elif self.viewlist[k]["background"] != 'white':
  4655.                     self.viewlist[k].configure(background = 'white')
  4656.                 address = address + self.codelist[k+1].instlen
  4657.  
  4658.     def instdelete(self):
  4659.         current_instruction = self.current_inst
  4660.         line = self.codelist[current_instruction]
  4661.         current_offset = line.instoffset
  4662.         n_bytes_removed = line.instlen
  4663.         if line.label:
  4664.             if line.label in self.label_resolve:
  4665.                 labelled_lines = self.label_resolve[line.label]
  4666.                 if len(labelled_lines) == 1:
  4667.                     del self.label_resolve[line.label]
  4668.                 else:
  4669.                     labelled_lines.remove(current_instruction)
  4670. #                   self.label_resolve[line.label] = labelled_lines
  4671.                
  4672.         self.editstack.append(self.codelist[current_instruction])
  4673.         del self.codelist[current_instruction]
  4674.         self.textslide(current_instruction , n_bytes_removed, '-')
  4675.         self.fixjumps()
  4676.  
  4677.     def instinsert(self,line):
  4678.         current_instruction = self.current_inst
  4679.         current_offset = self.codelist[current_instruction].instoffset
  4680.         line.instoffset = current_offset
  4681.         n_bytes_added = line.instlen
  4682.         self.textslide(current_instruction, n_bytes_added, '+')
  4683.         self.codelist[current_instruction:current_instruction]= [line] 
  4684.         if line.label:
  4685. #           self.label_resolve[line.label] = current_instruction
  4686.             if line.label in self.label_resolve:
  4687.                 self.label_resolve[line.label].append(current_instruction)
  4688.             else:
  4689.                 self.label_resolve[line.label] = [current_instruction]
  4690.  
  4691.        
  4692.         #resolve labels in line just added
  4693.         while 1:
  4694.             for index, lin in enumerate(self.codelist):
  4695.                 if not lin.displabel:
  4696.                     continue
  4697.                 target_num = self.label_resolve.get(lin.displabel,1)
  4698.                 if target_num != 1:
  4699.                     target = target_num[0]
  4700.                 else:
  4701.                     target = 1
  4702. #               target = self.codelist[self.label_resolve.get(lin.displabel,1)].instoffset
  4703.                 target = self.codelist[target].instoffset
  4704.                 jump = target - lin.instoffset - lin.instlen
  4705.                 if lin.dispwidth == 1:
  4706.                     if -128 <= jump < 128:
  4707.                         continue
  4708.                     elif Use_size.get() == 16 and lin.hexcode[0] == '7': #Conditional jump
  4709.                         self.textslide(index + 1, 2, '+')
  4710.                         lin.instlen = lin.instlen + 2
  4711.                         lin.dispwidth = 2
  4712.                         if jump < 0:
  4713.                             lin.hexcode= '0F8' + hexcode[1] + byte_swap("%04X" % (jump+ 65536))
  4714.                         else:
  4715.                             lin.hexcode= '0F8' + hexcode[1] + byte_swap("%04X" % jump)
  4716.                     elif Use_size.get() == 16 : #Unconditional jump
  4717.                         self.textslide(index + 1, 1, '+')
  4718.                         lin.instlen = lin.instlen + 1
  4719.                         lin.dispwidth = 4
  4720.                         if jump < 0:
  4721.                             lin.hexcode= 'E9' + byte_swap("%04X" % (jump+ 65536))
  4722.                         else:
  4723.                             lin.hexcode= 'E9' + byte_swap("%04X" % jump)
  4724.                     elif lin.hexcode[0] == '7': #Conditional jump
  4725.                         self.textslide(index + 1, 4, '+')
  4726.                         lin.instlen = lin.instlen + 4
  4727.                         lin.dispwidth = 4
  4728.                         if jump < 0:
  4729.                             lin.hexcode= '0F8' + hexcode[1] + byte_swap("%08X" % (jump+(1<<32)))
  4730.                         else:
  4731.                             lin.hexcode= '0F8' + hexcode[1] + byte_swap("%08X" % jump)
  4732.                     elif lin.hexcode[:2] == 'EB': #Unconditional jump
  4733.                         self.textslide(index + 1, 3, '+')
  4734.                         lin.instlen = lin.instlen + 3
  4735.                         lin.dispwidth = 4
  4736.                         if jump < 0:
  4737.                             lin.hexcode= 'E9' + byte_swap("%08X" % (jump+(1<<32)))
  4738.                         else:
  4739.                             lin.hexcode= 'E9' + byte_swap("%08X" % jump)
  4740.                     break
  4741.                 elif lin.dispwidth == 2:
  4742.                     if -32768 <= jump < 32768:
  4743.                         continue
  4744.                     else:
  4745.                         print("Very long jump.")
  4746.                         raise SystemExit
  4747.                 elif lin.dispwidth == 4:
  4748.                     continue
  4749.             else:
  4750.                 break
  4751.         self.fixjumps()
  4752.  
  4753.     def textslide(self,index,n_bytes, sign):
  4754.         for i,lin in enumerate(self.codelist):
  4755.             if i >= index:
  4756.                 if sign == '+':
  4757.                     lin.instoffset += n_bytes
  4758.                 else:
  4759.                     lin.instoffset -= n_bytes
  4760.         for label in self.label_resolve:
  4761. #           if self.label_resolve[label] >= index:
  4762. #               if sign == '+' :
  4763. #                   self.label_resolve[label] += 1
  4764. #               else:
  4765. #                   self.label_resolve[label] -= 1
  4766.             newlist = []
  4767.             for target in self.label_resolve[label]:
  4768.                 if target >= index:
  4769.                     if sign == '+':
  4770.                         newlist.append(target + 1)
  4771.                     else:
  4772.                         newlist.append(target - 1)
  4773.                 else:
  4774.                     newlist.append(target)
  4775.             self.label_resolve[label] = newlist
  4776.  
  4777.     def fixjumps(self):
  4778.         bad_list = []
  4779.         repeat_list = []
  4780.         for lin in self.codelist:
  4781.             if not lin.displabel:
  4782.                 continue
  4783.             target_list = self.label_resolve.get(lin.displabel,1)
  4784.             if target_list == 1:
  4785.                     if lin.displabel not in bad_list:
  4786.                         bad_list.append(lin.displabel)
  4787.                     target_num = 1
  4788.             elif len(target_list) > 1:
  4789.                     target_num = target_list[0]
  4790.                     if lin.displabel not in repeat_list:
  4791.                         repeat_list.append(lin.displabel)
  4792.             else:
  4793.                     target_num = target_list[0]
  4794. #           target = self.codelist[self.label_resolve.get(lin.displabel,1)].instoffset
  4795.  
  4796.             target = self.codelist[target_num].instoffset
  4797.             jump = target - lin.instoffset - lin.instlen
  4798.             if lin.dispwidth == 1 and jump < 0:
  4799.                 lin.hexcode = lin.hexcode[:-2] + "%02X"%(jump + 256)
  4800.             elif lin.dispwidth == 1:
  4801.                 lin.hexcode = lin.hexcode[:-2] + "%02X"% jump
  4802.             elif lin.dispwidth == 2 and jump < 0:
  4803.                 lin.hexcode = lin.hexcode[:-4] + byte_swap("%04X"%(jump + 65536))
  4804.             elif lin.dispwidth == 2:
  4805.                 lin.hexcode = lin.hexcode[:-4] + byte_swap("%04X"% jump )
  4806.             elif lin.dispwidth == 4 and jump < 0:
  4807.                 lin.hexcode = lin.hexcode[:-8] + byte_swap("%08X"%(jump + (1<<32)) )
  4808.             elif lin.dispwidth == 4 :
  4809.                 lin.hexcode = lin.hexcode[:-8] + byte_swap("%08X"% jump)
  4810.         self.unresolved_labels = bad_list
  4811.         self.duplicate_labels = repeat_list
  4812.  
  4813.  
  4814.        
  4815.     def store(self):
  4816.         pointer = self.load_origin
  4817.         for lin in self.codelist:
  4818.             for k in range(lin.instlen):
  4819.                 byte_val = int(lin.hexcode[2*k:2*k + 2],16)
  4820.                 LA_write(pointer, byte_val,1)
  4821.                 pointer = pointer + 1
  4822.  
  4823.     def codelin(self):
  4824.         cl = StringVar()
  4825.         m = Label(codePanel.interior,borderwidth=0,
  4826.                   anchor = "w",
  4827.                   relief=SUNKEN,
  4828.                   textvariable=cl,
  4829.                   width = 32,
  4830.                   background = "white",
  4831.                   font = "Courier 12 bold")
  4832.         cl.set('  ')
  4833.         m.value = cl
  4834.         m.bind('<Button-1>', self.select_line)
  4835.         m.bind('<Button-3>', self.show_hex)
  4836.         return m
  4837.  
  4838.     def select_line(self, event):
  4839.         if self.execstate != 'inserting' and self.execstate != 'stepping':
  4840.             self.set_execstate('stepping')
  4841.         for i,x in enumerate(self.viewlist):
  4842.             if event.widget == x:
  4843.                 EIP.setvalue(self.codelist[i+1].instoffset)
  4844.                 self.set_current_inst(instnum = i)
  4845.  
  4846.     def show_hex(self, event):
  4847.         for i,x in enumerate(self.viewlist):
  4848.             if event.widget == x:
  4849.                 print_feedback(self.codelist[i+1].hexcode + ' ')
  4850.  
  4851.     def refresh(self):
  4852.         for m in self.viewlist:
  4853.             m.pack_forget()
  4854.         self.viewlist = []
  4855.         if self.execstate == 'interpreting':
  4856.             background_color = "green"
  4857.         else:
  4858.             background_color = "yellow"
  4859.         for i,x in enumerate(self.codelist):
  4860.             if i == 0:continue
  4861.             m = self.codelin()
  4862.             m.value.set(x.source.rstrip())
  4863.             self.viewlist.append(m)
  4864.             if i + 1 == len(self.codelist): continue
  4865.             m.pack(side = TOP, fill = X, expand = YES)
  4866.             if self.current_inst == i:
  4867.                 m.configure(background = background_color)
  4868.  
  4869. #################################################################
  4870. #
  4871. #  Memory Section
  4872. #
  4873. #################################################################
  4874.  
  4875. class Memlin(Label):
  4876.    
  4877.     def __init__(self, parent, n_bytes = 8):
  4878.         viewing_line = StringVar()
  4879.         Label.__init__(self,parent,borderwidth=0,relief=SUNKEN,width=32,
  4880.                         textvariable=viewing_line,
  4881.                         background="white",font="Courier 12 bold")
  4882.         viewing_line.set('           ')
  4883.         self.textvariable = viewing_line
  4884.         self.width = n_bytes
  4885.  
  4886.     def setvalue(self, value):
  4887.         assert type(value) is tuple and len(value) in [5,9]
  4888.         if self.width == 8:
  4889.             row = "%02X  %02X%02X%02X%02X  %02X%02X%02X%02X"
  4890.         elif self.width ==4:
  4891.             row = "%02X  %02X%02X%02X%02X"
  4892.         self.textvariable.set(row % value)
  4893.  
  4894. class Memory:
  4895.  
  4896.     def __init__(self, addr_bits, panel):
  4897.         self.length = (1 << addr_bits)
  4898.         self.addr_bits = addr_bits
  4899.         self.vec = array.array('B', [0 for x in range(self.length)])
  4900.         self.viewbase = 0
  4901.         self.panel = panel
  4902.         self.memlist = self.build_memlist()
  4903.  
  4904.     def read(self,phys_addr,n_bytes):
  4905.         if phys_addr + n_bytes <= self.length:
  4906.             retval = 0
  4907.             for k in range(n_bytes):
  4908.                 retval = retval + (self.vec[phys_addr + k] << (k << 3))
  4909.             return retval
  4910.         # See Agarwal page 91 for a description of the following wrap-around behavior.
  4911.         mask = self.length - 1
  4912.         retval = 0
  4913.         for k in range(n_bytes):
  4914.             retval = retval + (self.vec[(phys_addr + k) & mask] << (k << 3))
  4915.         return retval
  4916.  
  4917.     def read_n_bytes(self, physaddr,n_bytes = 8):
  4918.         if n_bytes == 8:
  4919.                 mask = 248
  4920.         elif n_bytes == 4:
  4921.                 mask = 252
  4922.         retlist = [physaddr & -n_bytes] + list(self.vec[physaddr:physaddr + n_bytes])
  4923.         return tuple(retlist)
  4924.        
  4925.  
  4926.     def write(self,phys_addr, value, n_bytes):
  4927.         assert phys_addr + n_bytes <= self.length
  4928.         assert n_bytes > 0
  4929.         if phys_addr + n_bytes <= self.length:
  4930.             for k in range(n_bytes):
  4931.                 self.vec[phys_addr + k] = (value & 255)
  4932.                 value = (value >> 8)
  4933.         else:
  4934.             mask = self.length - 1
  4935.             for k in range(n_bytes):
  4936.                 self.vec[(phys_addr + k) & mask] = (value & 255)
  4937.                 value = (value >> 8)
  4938.  
  4939.     def build_memlist(self):
  4940.         ml = []
  4941.         for x in range(self.viewbase, self.viewbase + 192,8):
  4942.             newline = Memlin(self.panel)
  4943.             newline.pack(side = TOP)
  4944.             ml.append(newline)
  4945.         return ml
  4946.  
  4947.     def refresh(self):
  4948.         x = self.viewbase
  4949.         for ml in self.memlist:
  4950.             ml.setvalue(self.read_n_bytes(x))
  4951.             x = x + 8
  4952.  
  4953.  
  4954. class MemView:
  4955.     def __init__(self,panel,width = 8):
  4956.         self.panel = panel
  4957.         self.memlist = []
  4958.         self.viewbase = 0
  4959.         self.width = width
  4960.         for x in range(self.viewbase, self.viewbase + 192,8):
  4961.             newline = Memlin(self.panel)
  4962.             newline.pack(side = TOP)
  4963.             self.memlist.append(newline)
  4964.  
  4965.     def refresh(self):
  4966.         x = self.viewbase
  4967.         for ml in self.memlist:
  4968.             ml.setvalue(mem.read_n_bytes(x, self.width))
  4969.             x = x + self.width
  4970.  
  4971. ##############################################################
  4972. #
  4973. #  x86 Architecture
  4974. #
  4975. ##############################################################
  4976.  
  4977. class Viewable_Register:
  4978.  
  4979.     def __init__(self, num_bits, name):
  4980.         self.strvalue = StringVar()
  4981.         self.bitlength = num_bits
  4982.         self.formatString = " %0" + str(self.bitlength >> 2) + "X"
  4983.         self.strvalue.set(self.formatString % 0)
  4984.         self.name = name
  4985.  
  4986.     def setValue(self,new_value):  
  4987.         assert 0 <= new_value < 1 << self.bitlength
  4988.         self.strvalue.set(self.formatString % new_value)
  4989.  
  4990.     def getValue(self):
  4991.         return int(self.strvalue.get(),16)
  4992.  
  4993. class Viewable_Boolean:
  4994.    
  4995.     def __init__(self, name):
  4996.         self.strvalue = StringVar()
  4997. #       self.formatString = " %0" + str(self.bitlength >> 2) + "X"
  4998.         self.formatString = " %01X"
  4999.         self.strvalue.set(self.formatString % 1)
  5000.         self.name = name
  5001.  
  5002.     def setValue(self,new_value):  
  5003.         if type(new_value) is bool:
  5004.             if new_value:
  5005.                 self.strvalue.set(self.formatString % 1)
  5006.             else:
  5007.                 self.strvalue.set(self.formatString % 0)
  5008.         elif type(new_value) is int:
  5009.             if new_value == 0:
  5010.                 self.strvalue.set(self.formatString % 0)
  5011.             else:
  5012.                 self.strvalue.set(self.formatString % 1)
  5013.  
  5014.     def getValue(self):
  5015.         return bool(int(self.strvalue.get()))
  5016.  
  5017. class Modifiable_Register(Frame):
  5018.     def __init__(self,regname,numbits):
  5019.         Frame.__init__(self)
  5020.         self.grid()
  5021.         lbl = Label(self, background = "red",
  5022.                         foreground = "yellow",
  5023.                         text = regname,
  5024.                         width = 5,
  5025.                         font = "Arial 20")
  5026.         lbl.pack(side = "left")
  5027.         self.value_box = Entry(self,width = 12, background = "white",
  5028.                                   font ="Courier 20 bold")
  5029.         self.value_box.pack()
  5030.         self.value_box.bind("<Return>",self.enterValue)
  5031.         self.bitlength = numbits
  5032.         self.value= "".join(random.sample("0123456789ABCDEF",8))
  5033.         self.value_box.insert(0,  "  " + self.value )
  5034.    
  5035.     def enterValue(self,event):
  5036.         text = event.widget.get()
  5037.         save_old = int(self.getStringValue(),16)
  5038.         save_old = self.getValue()
  5039.         try:
  5040.             new_value = int(text,16)
  5041.         except:
  5042.             new_value = save_old
  5043.         if 0 > new_value or new_value >= 1<< self.bitlength:
  5044.             new_value = save_old
  5045.         self.setValue(new_value)
  5046.  
  5047.     def getStringValue(self):
  5048.         return self.value
  5049.    
  5050.     def setValue(self,new_value):  
  5051.         assert 0 <= new_value < 1 << self.bitlength
  5052.         self.value =   "%08X"% new_value
  5053.         self.value_box.delete(0,END)
  5054.         self.value_box.insert(END,  "  " + self.value )
  5055.  
  5056.     def getValue(self):
  5057.         return int(self.value,16)
  5058.  
  5059. class InstructionPointer:
  5060.  
  5061.     def __init__(self, size):
  5062.         self.value = 0
  5063.  
  5064.     def setvalue(self, new_value):
  5065.         assert new_value < (1<<32)
  5066.         self.value = new_value
  5067.  
  5068.     def getvalue(self):
  5069.         return self.value
  5070.  
  5071. class Flag(Frame)
  5072.     def __init__(self,flagname):
  5073.         Frame.__init__(self)
  5074.         lbl = Label(self, background = "gray",
  5075.                         foreground = "white",
  5076.                                 text = flagname,
  5077.                                 width = 3,
  5078.                                 relief = SUNKEN,
  5079.                                 font = "Arial 20")
  5080.         lbl.pack(side = "left",padx=3)
  5081.         lbl.bind("<Button-1>", self.toggleValue)
  5082.         self.value = 0
  5083.         self.label = lbl
  5084.  
  5085.     def setValue(self,new_value):
  5086.         assert new_value == 0 or new_value == 1
  5087.         self.value = new_value
  5088.         if new_value == 0:
  5089.             self.label.configure(background = "gray",foreground="white")
  5090.         else:
  5091.             self.label.configure(background = "black",foreground = "orange")
  5092.  
  5093.     def getValue(self):
  5094.         return self.value
  5095.    
  5096.     def toggleValue(event,d):
  5097.         flag = event
  5098.         flag.setValue(1 - flag.getValue())
  5099.    
  5100. class Descr:
  5101.     def __init__(self):
  5102. #               See Agarwal pp 32, 33.
  5103.         self.Base = Viewable_Register(32,"Base")
  5104.         self.Base.setValue(0)
  5105.         self.Limit = Viewable_Register(32,"Limit")
  5106.         self.Limit.setValue(0xffffffff)
  5107.         self.DPL = Viewable_Register(2,"DPL")
  5108.         self.DPL.setValue(0)
  5109.         self.Valid = Viewable_Boolean("Valid")
  5110.         self.Valid.setValue(True)
  5111.         self.CDSeg = Viewable_Boolean("CDSeg")
  5112.         self.CDSeg.setValue(True)
  5113.         self.Readable = Viewable_Boolean("Readable")
  5114.         self.Readable.setValue(True)
  5115.         self.Writable = Viewable_Boolean("Writable")
  5116.         self.Writable.setValue(True)
  5117.         self.Executable = Viewable_Boolean("Executable")
  5118.         self.Executable.setValue(True)
  5119.         self.Conforming = Viewable_Boolean("Conforming")
  5120.         self.Conforming.setValue(True)
  5121.         self.ExpandDown = Viewable_Boolean("ExpandDown")
  5122.         self.ExpandDown.setValue(False)
  5123.         self.Type = Viewable_Register(4,"Type")
  5124.         self.Type.setValue(0)
  5125.         self.DefaultAttr = Viewable_Boolean("DefaultAttr")
  5126.         self.DefaultAttr.setValue(True)
  5127.         self.GDField = Viewable_Register(4,"GDField")
  5128.         self.GDField.setValue(0)
  5129.         self.Accessed = Viewable_Boolean("Accessed")
  5130.         self.Accessed.setValue(False)
  5131.         self.Selector = Viewable_Register(16,"Selector")
  5132.         self.Selector.setValue(0)
  5133.         self.Offset = Viewable_Register(32,"Offset")
  5134.         self.Offset.setValue(0)
  5135.         self.ParamCount = Viewable_Register(4,"ParamCount")
  5136.         self.ParamCount.setValue(0)
  5137.  
  5138.     def read_descr(self, sel, TSS_load):
  5139.     # Read descriptor and write into desc
  5140.         # pp 63-66
  5141.         erc = sel & 0xFFFC
  5142.    
  5143.         if (sel & 4) == 0:
  5144.             tableDesc = descrVec[GDT]
  5145.         else:
  5146.             tableDesc = descrVec[LDT]
  5147.    
  5148.         sel_Index = sel & 0xfff8
  5149.         d1 = DTAB_read(erc, tableDesc, sel_Index, TSS_load, 4)
  5150.         d2 = DTAB_read(erc, tableDesc, sel_Index + 4, TSS_load, 4)
  5151.  
  5152.         self.Valid.setValue(bool(d2 & (1 << 15)))
  5153.         self.DPL.setValue((d2 >> 13) & 3)            # Bits 13,14
  5154.         self.CDSeg.setValue(bool(d2 & (1 << 12)))    # Bit 12
  5155.         if self.CDSeg.getValue():
  5156.             self.Base.setValue((((d2 >> 24) & 255) << 24) | ((d2 & 255) << 16)| (d1 >>16))
  5157.             self_Limit = (((d2 >> 16) & 15) << 16) + (d1 & 65535)
  5158.             if d2 & (1 << 23):                        # Page granularity
  5159.                 self.Limit.setValue((self_Limit << 12) + 0xfff)
  5160.             else:
  5161.                 self.Limit.setValue(self_Limit)
  5162.             self.DefaultAttr.setValue(d2 & (1 << 22))
  5163.             self.Executable.setValue(d2 & (1 << 11))
  5164.             if self.Executable.getValue():
  5165.                 self.Conforming.setValue(d2 & (1<< 10))
  5166.                 self.Readable.setValue(d2 & (1<< 9))
  5167.                 self.Writable.setValue(False)
  5168.                 self.ExpandDown.setValue(False)
  5169.             else:
  5170.                 self.ExpandDown.setValue(d2 & (1 << 10))
  5171.                 self.Writable.setValue(d2 & (1 << 9))
  5172.                 self.Readable.setValue(True)
  5173.                 self.Conforming.setValue(False)
  5174.             self.Type.setValue(0)
  5175.         else:
  5176.             self.Type.setValue((d2 >> 8) & 15)
  5177.             self.Selector.setValue(d1 >> 16)
  5178.             self.Offset.setValue((d2 >> 16)<< 16) | (d1 & 65535)
  5179.             self.Executable = False
  5180.             if self.Type.getValue() in [1,2,3,9,11]:
  5181.             # LDT_SEG,NOTBUSY_TSS16,BUSY_TSS16,NOTBUSY_TSS32,BUSY_TSS32
  5182.                 self.Readable.setValue(True)
  5183.                 self.Writable.setValue(True)
  5184.             else:
  5185.                 self.Readable.setValue(False)
  5186.                 self.Writable.setValue(False)
  5187.                 self.ParamCount.setValue(d2 & 31)
  5188.         self.Accessed.setValue(d2 & 256)
  5189.         self.GDField.setValue((d2 >> 20) & 15)
  5190.  
  5191.     def write_descr(self, phys_addr):
  5192.     #  The x86 cannot do this.  This is for the edlinas user only.
  5193.         d2 = 0
  5194.         if self.Valid.getValue():
  5195.             d2 = d2 | (1 << 15)
  5196.         d2 = d2 | (self.DPL.getValue() << 13)
  5197.         d2 = d2 | (int(self.CDSeg.getValue()) << 12)
  5198.         if self.CDSeg.getValue() or self.Type.getValue() in [1,2,3,9,11]:
  5199.                   # LDT_SEG,NOTBUSY_TSS16,BUSY_TSS16,NOTBUSY_TSS32,BUSY_TSS32
  5200.             d1 = (self.Base.getValue() & 0xffff)<< 16
  5201.             if self.GDField.getValue() & 8:
  5202.                 d1 = d1 | ((self.Limit.getValue() >> 12) & 0xffff)
  5203.                 d2 = d2 | ((self.Limit.getValue() >> 12) & 0xf0000)
  5204.             else:
  5205.                 d1 = d1 | (self.Limit.getValue() & 0xffff)
  5206.                 d2 = d2 | (self.Limit.getValue() & 0xf0000)
  5207.             d2 = d2 |(self.Base.getValue() & 0xff000000)|((self.Base.getValue() & 0xff0000) > 16)
  5208.             d2 = d2 |(self.GDField.getValue() << 20)
  5209.             if self.CDSeg.getValue():
  5210.                 d2 = d2 | (1 << 12)
  5211.                 if self.Executable.getValue():
  5212.                     d2 = d2 | (1 << 11)
  5213.                     if self.Conforming.getValue():
  5214.                         d2 = d2 | (1 << 10)
  5215.                     if self.Readable.getValue():
  5216.                         d2 = d2 | (1 << 9)
  5217.                 else:
  5218.                     if self.ExpandDown.getValue():
  5219.                         d2 = d2 | (1 << 10)
  5220.                     if self.Writable.getValue():
  5221.                         d2 = d2 | (1 << 9)
  5222.             else:
  5223.                 d2 = d2 | (self.Type.getValue() << 8)
  5224.         else:
  5225.             d2 = d2 | (self.Type.getValue() << 8)
  5226.             d2 = d2 | (self.Offset.getValue() & 0xffff0000)
  5227.             d1 = d1 | (self.Offset.getValue() & 0xffff)
  5228.             d1 = d1 | (self.Selector.getValue() << 16)
  5229.             d2 = d2 | self.ParamCount.getValue()
  5230.         mem.write(phys_addr, d1, 4)
  5231.         mem.write(phys_addr + 4, d2, 4)
  5232.  
  5233. class showDescr(Frame):
  5234.     def __init__(self, parent,segnum):
  5235.         Frame.__init__(self, parent)
  5236.         self.grid()
  5237.         lbl = Label(self, background = "red",
  5238.                         foreground = "yellow",
  5239.                         text = segReg[segnum].name,
  5240.                         width = 5,
  5241.                         font = "Arial 20")
  5242.         lbl.pack(side = "top")
  5243.         m = showReg(self, "Base", 32, descrVec[segnum].Base.strvalue)
  5244.         m.pack(side = 'top')
  5245.         m = showReg(self, "Limit", 32, descrVec[segnum].Limit.strvalue)
  5246.         m.pack(side = 'top')
  5247.         m = showReg(self, "Valid", 1, descrVec[segnum].Valid.strvalue)
  5248.         m.pack(side = 'left')
  5249.         m = showReg(self, "DPL", 1, descrVec[segnum].DPL.strvalue)
  5250.         m.pack(side = 'left')
  5251.  
  5252. #
  5253. # This function was modified to change the display behavior for descriptor table
  5254. # entries GDT and IDT. These two will be displayed like normal registers except
  5255. # the entry box for the register value will be grayed out since they are not
  5256. # actual registers. This was done by adding the if/else block to determine if the
  5257. # current register is a actual register or just a descriptor table entry.
  5258. ###
  5259. ### Changed to use reg.value_box.configure(state = DISABLED) after showReg is called
  5260. ###
  5261. class showReg(Frame):
  5262.     def __init__(self,parent,regname,numbits,content,source=None):
  5263.         Frame.__init__(self,parent)
  5264. #       self.grid()
  5265.         lbl = Label(self, background = "red",
  5266.                         foreground = "yellow",
  5267.                         text = regname,
  5268.                         width = 5,
  5269.                         font = "Arial 20")
  5270.         lbl.pack(side = "left")
  5271. #       if regname=="GDT" or regname=="IDT":
  5272. #           self.value_box = Entry(self,width = 2 + (numbits//4), background = "white", font ="Courier 20 bold", textvariable=content, state=DISABLED)
  5273. #       else:
  5274.         self.value_box = Entry(self,width = 2 + ((numbits + 3)//4), background = "white",
  5275.                 font ="Courier 20 bold", textvariable=content)
  5276.         self.value_box.pack()
  5277.         self.value_box.bind("<Return>",self.enterValue)
  5278.         self.bitlength = numbits
  5279.         self.value = content
  5280.         self.source = source
  5281.  
  5282.     def enterValue(self,event):
  5283.         text = event.widget.get()
  5284.         save_old = self.getValue()
  5285.         try:
  5286.             new_value = int(text,16)
  5287.         except:
  5288.             new_value = save_old
  5289.         if 0 > new_value or new_value >= 1<< self.bitlength:
  5290.             new_value = save_old
  5291.         self.setValue(new_value)
  5292.         if new_value != save_old and self.source:
  5293.             source.setValue(new_value)
  5294.    
  5295.     def setValue(self,new_value):  
  5296.         assert 0 <= new_value < 1 << self.bitlength
  5297.         formatString = " %0" + str(self.bitlength >> 2) + "X"
  5298.         self.value.set(formatString % new_value)
  5299.  
  5300.     def getValue(self):
  5301.         return int(self.value.get(),16)
  5302.  
  5303.     def refresh(self):
  5304.         self.setValue(source.getValue())
  5305.  
  5306. class StackView(Frame):
  5307.     def __init__(self,parent):
  5308.     # stackPanel = Frame(m,width = 200, height = 540, background = "white")
  5309.         viewing_line = StringVar()
  5310.         Frame.__init__(self,parent,width = 200, height = 540, background = "white")
  5311.         self.memlist = []
  5312.         self.bottom = genReg[4].getValue() # ESP
  5313.         self.bind("<Button-1>", lambda e: e.widget.reset_bottom())
  5314.         self.bind('<KeyPress-Down>', lambda e: e.widget.pop_stack())
  5315.         self.bind('<KeyPress-Up>', lambda e: e.widget.push_stack())
  5316.  
  5317.     def refresh(self):
  5318.        
  5319.         for m in self.memlist:
  5320.                 m.pack_forget()
  5321.    
  5322.         stack_pointer = genReg[4].getValue()
  5323.         for lin_address in range(self.bottom, stack_pointer, -4):
  5324.                 memlin = Memlin(self, 4)
  5325. #               print(mem.read_n_bytes(lin_address - 4, 4))
  5326.                 memlin.setvalue(mem.read_n_bytes(lin_address - 4, 4))
  5327.                 memlin.pack(side = BOTTOM)
  5328.                 self.memlist.append(memlin)
  5329.  
  5330.     def reset_bottom(self):
  5331.         self.bottom = genReg[4].getValue() # ESP
  5332.         self.refresh()
  5333.  
  5334.     def push_stack(self):
  5335.         self.bottom = self.bottom + 4
  5336.         self.refresh()
  5337.  
  5338.     def pop_stack(self):
  5339.         self.bottom = self.bottom - 4
  5340.         self.refresh()
  5341.  
  5342. # Functions called when memory is setup
  5343.  
  5344. def set_viewbase(event):
  5345.     text = event.widget.get()
  5346.     save_old = mem.viewbase
  5347.     try:
  5348.         new_value = int(text,16) &-8
  5349.     except:
  5350.         new_value = save_old
  5351.     if 0 > new_value or new_value >= 1<< mem.addr_bits:
  5352.         new_value = save_old
  5353.     mem.viewbase = new_value
  5354.     event.widget.delete(0,END)
  5355.     event.widget.insert(END, "%08X"% new_value)
  5356.     mem.refresh()
  5357.  
  5358. def build_membox(root):
  5359.     value_box = Entry(root,width = 8, background = "white", font ="Courier 16 bold")
  5360.     value_box.place(x = 1006,y=43)
  5361.     value_box.insert(END, "%08X"% 0)
  5362.     return value_box
  5363.  
  5364. ################################################################
  5365. #
  5366. #  Set up GUI
  5367. #
  5368. ###############################################################
  5369.  
  5370. root = Tk()
  5371.  
  5372. root.title("Edlinas")
  5373.  
  5374. root.geometry("1200x740")
  5375.  
  5376. app = Frame(root)
  5377.  
  5378. app.grid()
  5379.  
  5380. app.master["background"]="blue"
  5381.  
  5382. H_16 = "Helvetica -16 bold"
  5383.  
  5384. #################################################################
  5385. #
  5386. #  Menu Section
  5387. #
  5388. #################################################################
  5389.  
  5390.  
  5391. mBar = Frame(root, relief = RAISED, borderwidth = 2)
  5392. mBar.place(x = 0, y = 0, width = 1250)
  5393.  
  5394.  
  5395. #
  5396. #  File Menu
  5397. #
  5398.  
  5399. def interpret(e = None):
  5400.     prog.set_execstate('interpreting')
  5401.     return
  5402.  
  5403. def clearscreen():
  5404.     global prog
  5405.     for m in prog.viewlist:
  5406.         m.pack_forget()
  5407.     prog = Program()
  5408.     prog.refresh()
  5409.  
  5410. def merge_file():
  5411.     filename = askopenfilename(defaultextension='.asm',
  5412.                                     initialdir = os.getcwd(),
  5413.                                     title = 'Merge assembler file',
  5414.                                     filetypes = [('assembler','*.asm'),('assembler','*.ASM')])
  5415.     if not filename :
  5416.         return
  5417.     else:
  5418.         fetch_file(filename,replace_old = False)
  5419.  
  5420. def save_as_file():
  5421.     filename = asksaveasfilename(defaultextension='.asm',
  5422.                                     initialdir = os.getcwd(),
  5423.                                     title = 'Save As',
  5424.                                     filetypes = [('assembler','*.asm'),('assembler','*.ASM')])
  5425.     if not filename :
  5426.         return
  5427.     else:
  5428.         save_file(filename)
  5429.  
  5430. def get_file():
  5431.     filename = askopenfilename(defaultextension='.asm',
  5432.                                     initialdir = os.getcwd(),
  5433.                                     title = 'Open assembler file',
  5434.                                     filetypes = [('assembler','*.asm'),('assembler','*.ASM')])
  5435.     if not filename :
  5436.         return
  5437.     else:
  5438.         fetch_file(filename)
  5439.    
  5440. def fetch_file(filename, replace_old = True):
  5441.     if replace_old:
  5442.         global prog
  5443.         for m in prog.viewlist:
  5444.             m.pack_forget()
  5445.         prog = Program()
  5446.         prog.filename = filename
  5447.     open_file(filename)
  5448.  
  5449.  
  5450.  
  5451. def open_file(filename):
  5452.     f = open(filename,"r")
  5453.     line_num = 1
  5454.     for source_line in f:
  5455.         line = build_line(source_line.rstrip(), line_num)
  5456.         if type(line) is str:
  5457.             print_feedback(line)
  5458.             return
  5459.         prog.instinsert(line)
  5460.         prog.current_inst = prog.current_inst + 1
  5461.         line_num = line_num + 1
  5462.     f.close()
  5463.     prog.store()
  5464.     mem.refresh()
  5465.     prog.filename = filename
  5466.     prog.set_execstate('stepping')
  5467.     return
  5468.  
  5469. def open_same_file():
  5470.     global prog
  5471.     if prog.filename :
  5472.         for m in prog.viewlist:
  5473.             m.pack_forget()
  5474.         old_program_name = prog.filename
  5475.         prog = Program()
  5476.         prog.filename = old_program_name
  5477.         open_file(old_program_name)
  5478.         prog.refresh()
  5479.     else:
  5480.         print_feedback("No previous load attempted")
  5481.         return
  5482.  
  5483. def save_file(fname=None):
  5484.     if fname == None:
  5485.         f = open(prog.filename, "w")
  5486.     else:
  5487.         f= open(fname, "w")
  5488.     for k,l in enumerate(prog.codelist):
  5489.         if k == 0: continue
  5490.         f.write(l.source)
  5491.     f.close()
  5492.  
  5493.  
  5494. def makeFileMenu():
  5495.     FileBtn = Menubutton(mBar, text = 'File', width = 8, font = H_16, underline= 0)
  5496.     FileBtn.pack(side = LEFT, padx = "2m")
  5497.     FileBtn.menu = Menu(FileBtn)
  5498.     FileBtn.menu.choices = Menu(FileBtn)
  5499.     FileBtn.menu.add_command(label = "New",font = H_16, command= clearscreen)
  5500.     FileBtn.menu.add_command(label = "Open",font = H_16, command=get_file)
  5501.     FileBtn.menu.add_command(label = "Re-open",font = H_16, command=open_same_file)
  5502.     FileBtn.menu.add_command(label = "Merge",font = H_16, command=merge_file)
  5503.     FileBtn.menu.add_command(label = "Save",font = H_16, command=save_file)
  5504.     FileBtn.menu.add_command(label = "Save As",font = H_16, command=save_as_file)
  5505.     FileBtn.menu.add_command(label = "Quit",font = H_16, command=FileBtn.quit)
  5506.     FileBtn['menu'] = FileBtn.menu
  5507.     return FileBtn
  5508.  
  5509. #
  5510. # Make Edit Menu
  5511. #
  5512.  
  5513.  
  5514. def insert_mode():
  5515.     prog.set_execstate('inserting')
  5516.     return
  5517.  
  5518. def changeline():
  5519.     try:
  5520.         line = prog.codelist[prog.current_inst]
  5521.     except:
  5522.         return
  5523.     if prog.current_inst + 1 == len(prog.codelist):
  5524.         print_feedback("Not a program line.")
  5525.         return
  5526.     prog.set_execstate('changing')
  5527.     entrybox.insert(0,line.source.rstrip())
  5528.  
  5529. def delete_current():
  5530.     if prog.current_inst + 1 == len(prog.codelist):
  5531.         print_feedback("Not a program line.")
  5532.         return
  5533.     prog.instdelete()
  5534.     prog.store()
  5535.     prog.refresh()
  5536.     mem.refresh()
  5537.     return
  5538.  
  5539. def insert_saved_line():
  5540.     if prog.editstack == []:
  5541.         return
  5542.     old_source = prog.editstack.pop().source
  5543.     line = build_line(old_source)
  5544.     if type(line) is str:
  5545.         return
  5546.     prog.instinsert(line)
  5547.     prog.store()
  5548.     prog.refresh()
  5549.     mem.refresh()
  5550.  
  5551. def makeEditMenu():
  5552.     EditBtn = Menubutton(mBar, text = 'Edit', width = 8, font = H_16, underline= 0)
  5553.     EditBtn.pack(side = LEFT, padx = "2m")
  5554.     EditBtn.menu = Menu(EditBtn)
  5555.     EditBtn.menu.add_command(label = "Change ",font = H_16, command=changeline)
  5556.     EditBtn.menu.add_command(label = "Delete ",font = H_16, command=delete_current)
  5557.     EditBtn.menu.add_command(label = "Insert ",font = H_16, command=insert_mode)
  5558.     EditBtn.menu.add_command(label = "Paste ",font = H_16, command=insert_saved_line)
  5559.     EditBtn['menu'] = EditBtn.menu
  5560.     return EditBtn
  5561.  
  5562. #
  5563. # Make Run Menu
  5564. #
  5565.  
  5566. def run_program(e=None):
  5567.     reset_execstate()
  5568.     if prog.execstate == 'inserting':
  5569.         return
  5570.     continue_execution()
  5571.  
  5572. def continue_execution(e = None):
  5573.     prog.set_execstate('running')
  5574.  
  5575. def walk():
  5576.     if prog.execstate == 'running':
  5577.         try:
  5578.             fetchexec()
  5579.         except x86exception as e:
  5580.             print_feedback("Exception "+str(e.interrupt_number)+': '+ e.error_message + '  ')
  5581.             prog.set_execstate('stepping')
  5582.         if prog.execstate == 'running':
  5583.             root.after(prog.pace, walk)
  5584.  
  5585. def single_step():
  5586.     prog.set_execstate('stepping')
  5587.  
  5588. def block():
  5589.     prog.set_execstate('blocked')
  5590.  
  5591. def accept_input():
  5592.     entrybox.configure(state = NORMAL)
  5593.     entrybox.focus_force()
  5594.     userbox_label.configure(text = "Enter data:")
  5595.  
  5596. def reset_execstate():
  5597.     if len(prog.duplicate_labels) == 1:
  5598.         message = "Duplicate label: " + prog.duplicate_labels[0]
  5599.     elif len(prog.duplicate_labels) > 1:
  5600.         message = "Duplicate labels: "
  5601.         for lbl in prog.duplicate_labels:
  5602.             message = message + lbl + " "
  5603.     elif len(prog.unresolved_labels) == 1:
  5604.         message = "Unresolved label: " + prog.unresolved_labels[0]
  5605.     elif len(prog.unresolved_labels) > 1:
  5606.         message = "Unresolved labels: "
  5607.         for lbl in prog.unresolved_labels:
  5608.             message = message + lbl + " "
  5609.     else:
  5610.             message = ''
  5611.     if message:
  5612.             print_feedback(message)
  5613.             prog.set_execstate('inserting')
  5614.             return
  5615.    
  5616.     EIP.setvalue(0)
  5617.     prog.current_inst = 1
  5618.     prog.call_depth = 0
  5619.     prog.set_execstate('stepping')
  5620.  
  5621. def makeRunMenu():
  5622.     RunBtn = Menubutton(mBar, text = 'Run',width = 8, font = H_16,  underline= 0)
  5623.     RunBtn.pack(side = LEFT, padx = "2m")
  5624.     RunBtn.menu = Menu(RunBtn)
  5625.     RunBtn.menu.add_command(label = "Run ",font = H_16, command= run_program)
  5626.     RunBtn.menu.add_command(label = "Continue",font = H_16, command=continue_execution)
  5627.     RunBtn.menu.add_command(label = "Interpret",font = H_16, command= interpret)
  5628.     RunBtn.menu.add_command(label = "Single Step",font = H_16, command= single_step)
  5629.     RunBtn.menu.add_command(label = "Reset",font = H_16, command= reset_execstate)
  5630.     RunBtn['menu'] = RunBtn.menu
  5631.     return RunBtn
  5632.  
  5633.  
  5634. #
  5635. # Make Internals Menu : Call Toplevel Windows for Placed over the Right Panel
  5636. #
  5637.  
  5638. Display_Geometry = "340x595+850+75"
  5639.  
  5640.  
  5641.  
  5642. def displayInternals(RegList, name):
  5643.     m = Toplevel(root,width = 100, height = 590)
  5644.     m.wm_geometry(Display_Geometry)
  5645. #   m.title("Segment Registers")
  5646.     m.title(name + " Registers")
  5647.     m.wm_attributes("-topmost", 1)
  5648.     for ireg in RegList:
  5649.         reg = showReg(m, ireg.name, 32, ireg.strvalue)
  5650.         reg.pack(side = TOP, pady = 14)
  5651.  
  5652. def displayDebugRegs():
  5653.     displayInternals(debReg, "Debug")
  5654.  
  5655. def displayTestRegs():
  5656.     displayInternals(testReg, "Test")
  5657.  
  5658. def displayControlRegs():
  5659.     displayInternals(ctrlReg, "Control")
  5660.    
  5661. # This function is called from displaySegments when the "More Info" button is pressed next
  5662. # to a register or Descriptor Table entry. If the button is next to a Segment register,
  5663. # this will load the contents of the Segment Register and the matching Descriptor from the
  5664. # Descriptor Table. If the button is pressed next to a Descriptor entry (GDT or IDT), this
  5665. # will just load the Descriptor entry for the selected Table.
  5666. def viewMore(regname,k):
  5667.     m = Toplevel(root, width=100, height=300, bg="blue")
  5668.     m.title("Descriptor Info")
  5669.     m.wm_attributes("-topmost", 1)
  5670.     if regname=="GDT" or regname=="IDT":
  5671.         reg = showReg(m, regname, 16, "")
  5672.     else:
  5673.         reg = showReg(m, regname, 16, segReg[k].strvalue)
  5674.     reg.grid(row=0)
  5675.     spacer0= Label(m, background="blue", text='\n')
  5676.     spacer0.grid(row=1)
  5677.     seg_info = showDescr(m,k)
  5678.     seg_info.config(background="blue")
  5679.     seg_info.grid(row=2)
  5680.  
  5681. # This function was modified to correctly display all the Segment Registers and two Descriptor
  5682. # Table entries. The Segment Registers now display correctly in order and two Descriptor Table
  5683. # entiries were added (GDT and IDT). A "More Info" button was provided next to each entry to
  5684. # display additional information from the appropriate descriptor table.
  5685. def displaySegments():
  5686.     m = Toplevel(root,width = 100, height = 300, bg="blue")
  5687. #   m.wm_geometry(Display_Geometry)
  5688.     m.title("Segment Registers")
  5689.     m.wm_attributes("-topmost", 1)
  5690.     for k, r_name in enumerate(register_names):
  5691.         reg = showReg(m, r_name, 16, segReg[k].strvalue)
  5692.         reg.grid(row=k, column=0)
  5693.         spacer=Label(m, background="blue", text="\t")
  5694.         spacer.grid(row=k, column=2)
  5695.         view_more_info_btn = Button(m, text="More\nInfo", font = "Courier 10", bd=5, command=lambda k=k,r_name=r_name:viewMore(r_name,k))
  5696.         view_more_info_btn.grid(row=k,column=3)
  5697. #   reg.value_box.configure(state = DISABLED)
  5698.     k=k+1
  5699.     r_name="GDT"
  5700.     reg=showReg(m, r_name, 16, "")
  5701.     reg.grid(row=k, column=0)
  5702.     reg.value_box.configure(state = DISABLED)
  5703.     spacer=Label(m, background="blue", text="\t")
  5704.     spacer.grid(row=k, column=2)
  5705.     view_more_info_btn = Button(m, text="More\nInfo", font = "Courier 10", bd=5, command=lambda k=k,r_name=r_name: viewMore(r_name,k))
  5706.     view_more_info_btn.grid(row=k,column=3)
  5707.     k=k+1
  5708.     r_name="IDT"
  5709.     reg=showReg(m, r_name, 16, "")
  5710.     reg.grid(row=k, column=0)
  5711.     reg.value_box.configure(state = DISABLED)
  5712.     spacer=Label(m, background="blue", text="\t")
  5713.     spacer.grid(row=k, column=2)
  5714.     view_more_info_btn = Button(m, text="More\nInfo", font = "Courier 10", bd=5, command=lambda k=k,r_name=r_name: viewMore(r_name,k))
  5715.     view_more_info_btn.grid(row=k,column=3)
  5716.  
  5717. #MARK# <--- temporary location marker
  5718.  
  5719. def displayStack():
  5720.     global stackWindow, stackView
  5721.     if genReg[4].getValue() >= ( 1 << mem.addr_bits):
  5722.             print_feedback("Stack pointer is too large.")
  5723.             return
  5724.     stackWindow = Toplevel(root,width = 200, height = 590)
  5725.     stackWindow.wm_geometry(Display_Geometry)
  5726.     stackWindow.wm_attributes("-topmost", 1)
  5727.     stackWindow.title("Stack")
  5728.     l = Label(stackWindow, font = "Arial 20", text = "Stack", background = 'red')
  5729.     l.pack(side = TOP,fill = X, expand = NO, pady = 0)
  5730.     stackView = StackView(stackWindow)
  5731.     stackView.pack(side = TOP, fill= BOTH, expand = YES)
  5732.  
  5733. def bottomInit(panel):
  5734.     panel.set_bottom()
  5735.  
  5736. #def displayStatusRegs():
  5737. #   m = Toplevel(root,width = 200, height = 600)
  5738. #   m.wm_geometry(Display_Geometry)
  5739. #   m.title("Control Registers")
  5740. #   m.wm_attributes("-topmost", 1)
  5741. #   l = Label(m, font = "Arial 20", text = "Control Registers", background = 'red')
  5742. #   l.pack(side = TOP,fill = X, expand = NO, pady = 0)
  5743. #   stackPanel = Frame(m,width = 200, height = 540, background = "white")
  5744. #   stackPanel.pack(side = TOP, fill= BOTH, expand = YES)
  5745. #   for k in range(8):
  5746. #       reg = showReg(m, "CR" + str(k), 16, segReg[k].strvalue)
  5747. #       reg.pack(side = TOP, pady = 14)
  5748.  
  5749. def makePopupMenu():
  5750.     PopupBtn = Menubutton(mBar, text = 'Internals', width = 8, font = H_16, underline= 0)
  5751.     PopupBtn.pack(side = LEFT, padx = "2m")
  5752.     PopupBtn.menu = Menu(PopupBtn)
  5753.     PopupBtn.menu.add_command(label = "Segment Registers",font = H_16,command=displaySegments)
  5754. #   PopupBtn.menu.add_command(label = "Segment Descriptors",font = H_16,command=displayDescriptors)
  5755.     PopupBtn.menu.add_command(label = "Debug Registers",font=H_16,command=displayDebugRegs)
  5756.     PopupBtn.menu.add_command(label = "Test  Registers",font=H_16,command=displayTestRegs)
  5757.     PopupBtn.menu.add_command(label = "Control Registers",font=H_16,command=displayControlRegs)
  5758.     PopupBtn['menu'] = PopupBtn.menu
  5759.     return PopupBtn
  5760.  
  5761. #
  5762. # Make View Menu
  5763. #
  5764.  
  5765. def displayEIP():
  5766.     m = Toplevel(root,width = 200, height = 600)
  5767.     m.wm_geometry(Display_Geometry)
  5768.     m.title("Stack")
  5769.     r = Reg(32)
  5770.  
  5771. def makeViewMenu():
  5772.     ViewBtn = Menubutton(mBar, text = 'View', width = 8, font = H_16, underline= 0)
  5773.     ViewBtn.pack(side = LEFT, padx = "2m")
  5774.     ViewBtn.menu = Menu(ViewBtn)
  5775.     ViewBtn.menu.add_command(label = "Stack",font = H_16, command=displayStack)
  5776.     ViewBtn.menu.add_command(label = "Show Flags Register",font = H_16, command=displayStack, state = DISABLED)
  5777.     ViewBtn.menu.add_command(label = "Current Privilege Level",font = H_16, command=displayStack, state = DISABLED)
  5778.     ViewBtn.menu.add_command(label = "Instruction Pointer",font = H_16,command=displaySegments, state = DISABLED)
  5779.     ViewBtn['menu'] = ViewBtn.menu
  5780.     return ViewBtn
  5781.  
  5782. #
  5783. # Make Settings Menu
  5784. #
  5785.  
  5786. def settabwidth():
  5787.     f = Frame(root, width = 200, height = 600)
  5788.     f.place(x = 515, y = 40)
  5789.     Maximum_choice = 15
  5790.     l = Label(f, font = H_16, text = "Spaces per Tab", background = 'white')
  5791.     l.pack(side= TOP, fill = X)
  5792.     list = Listbox(f,font = H_16, height = Maximum_choice, width = 15, selectmode=SINGLE)
  5793.     list.pack(side = TOP)
  5794.     for x in range(1, Maximum_choice + 1):
  5795.         list.insert(END,str(x))
  5796.     list.bind('<Button-1>', lambda e: gettabwidth(e))
  5797.     f.bind('<Leave>', lambda e: e.widget.destroy())
  5798.  
  5799. Use_size = IntVar()
  5800. Use_size.set(32)
  5801.  
  5802.  
  5803. def askforpace():
  5804.     Choices_list = ['30','60','120','300','600','1200','3000','6000']
  5805.     f = Frame(root, width = 200, height = 600)
  5806.     f.place(x = 515, y = 40)
  5807.     l = Label(f, font = H_16, text = "Instructions per Minute", background = 'white')
  5808.     l.pack(side= TOP, fill = X)
  5809.     list = Listbox(f,font = H_16,height = len(Choices_list), width = 10,selectmode=SINGLE)
  5810.     list.pack(side = TOP)
  5811.     for x in Choices_list:
  5812.         list.insert(END,str(x))
  5813.     list.bind('<Button-1>', lambda e: getpace(e))
  5814.     f.bind('<Leave>', lambda e: e.widget.destroy())
  5815.  
  5816. def getpace(e):
  5817.     selections = e.widget.curselection()
  5818.     if not selections :
  5819.         return
  5820.     num = int(e.widget.get(selections[0]))
  5821.     e.widget.destroy()
  5822.     prog.pace= 60000//num
  5823.  
  5824.  
  5825. def gettabwidth(e):
  5826.     selections = e.widget.curselection()
  5827.     if not selections :
  5828.         return
  5829.     num = int(e.widget.get(selections[0]))
  5830.     e.widget.destroy()
  5831.     prog.tabwidth = num
  5832.  
  5833. def trypopup():
  5834.     m = Toplevel(root)
  5835.     m.title("Trythis")
  5836.    
  5837. def makeOptionsMenu():
  5838.     OptionBtn = Menubutton(mBar, text = 'Settings', width = 8, font = H_16, underline = 0)
  5839.     OptionBtn.pack(side = LEFT, padx = "2m")
  5840.     OptionBtn.menu = Menu(OptionBtn)
  5841.     RadBtn = Menubutton(OptionBtn)
  5842.     RadBtn.menu = Menu(RadBtn)
  5843.     RadBtn.menu.add_radiobutton(label = '32 bit coding', font = H_16,
  5844.                                value=32, variable= Use_size)
  5845.     RadBtn.menu.add_radiobutton(label = '16 bit coding', font = H_16,
  5846.                                value=16, variable= Use_size)
  5847.     OptionBtn.menu.add_command(label = "Run Speed", font = H_16, command = askforpace)
  5848. #   OptionBtn.menu.add_command(label = "Load Origin",font = H_16,  command = trypopup)
  5849.     OptionBtn.menu.add_command(label = "Tab Width",font = H_16,  command = settabwidth)
  5850.     OptionBtn.menu.add_cascade(label = 'Coding Default', font = H_16, menu = RadBtn.menu)
  5851.     OptionBtn['menu'] = OptionBtn.menu
  5852.     return OptionBtn
  5853.  
  5854. #
  5855. # Make About Menu
  5856. #
  5857.  
  5858. def showAbout(event):
  5859.     s_ver = sys.version_info
  5860.     message = Message(root,background = "white",width = 400, font = H_16,
  5861.    text="""This program was written by Bob Neveln, with additions by John Stoddart.  It supports the textbook `Linux Assembly Language Programming' available from Prentice-Hall.  The program implements in Python the C language pseudo-code in Rakesh Agarwal's 80x86 Architecture & Programming, Volume II.  Bugs may be reported to neveln@cs.widener.edu""" )
  5862.   #text= "Python version " + "%d.%d.%d\n"%(s_ver.major,s_ver.minor,s_ver.micro))
  5863. #   message.pack(side = TOP)
  5864.     message.place(x=600,y=40)
  5865.     message.bind('<Button-1>',lambda e: e.widget.destroy(),'+')
  5866.     message.bind('<Leave>',lambda e: e.widget.destroy(),'+')
  5867.  
  5868.  
  5869. def makeAboutMenu():
  5870.     AboutBtn = Menubutton(mBar, text = 'About', width = 8, font = H_16, underline= 0)
  5871.     AboutBtn.pack(side = LEFT, padx = "2m")
  5872.     AboutBtn.bind('<Button-1>', showAbout)
  5873.     return AboutBtn
  5874.  
  5875. #
  5876. # Make Help Menu
  5877. #
  5878. def helpKeys():
  5879.         key_help = Toplevel()
  5880.         key_help.title("Key Commands")
  5881.         message = Message(key_help,background = "white", font = H_16, text="""
  5882.  C - change a line
  5883.  D - delete a line
  5884.  I - insert lines
  5885.  J - go down a line
  5886.  K - go up a line
  5887.  P - paste a line
  5888.  Q - quit the program
  5889.  R - re-open a file""" )
  5890. #        message.pack(side = TOP)
  5891.         message.grid()
  5892. #        message.bind('<Button-1>',lambda e: e.widget.destroy(),'+')
  5893. #        message.bind('<Leave>',lambda e: e.widget.destroy(),'+')
  5894.  
  5895.  
  5896. def helpEdit():
  5897.     message = Message(root,background = "white",width = 400, font = H_16,
  5898.   text="""This program has line-editing capabilities.  To edit a line in the center panel, first select it by clicking on it.  You may then delete it, change it, or insert another line at that location.  Select these functions using the Edit menu and make your edits in the orange lit Enter command box.  You may also use an external editor and Re-Open the source file.""" )
  5899.     message.place(x=700,y=40)
  5900.     message.bind('<Button-1>',lambda e: e.widget.destroy(),'+')
  5901.     message.bind('<Leave>',lambda e: e.widget.destroy(),'+')
  5902.  
  5903.  
  5904. def helpRun():
  5905.     message = Message(root,background = "white",width = 400, font = H_16,
  5906.   text="""Once a program is loaded you may execute single steps that are first selected using the mouse.  To do a single step hit the Space Bar.  If you need to leave edit mode you may use Single-stepping on the Run menu.  To run the program you may either hit Run on the Run menu or select the first instruction and hit Continue. """ )
  5907.     message.place(x=700,y=40)
  5908.     message.bind('<Button-1>',lambda e: e.widget.destroy(),'+')
  5909.     message.bind('<Leave>',lambda e: e.widget.destroy(),'+')
  5910.  
  5911.  
  5912.  
  5913.  
  5914. def makeHelpMenu():
  5915.     HelpBtn = Menubutton(mBar, text = 'Help', width = 8, font = H_16, underline= 0)
  5916.     HelpBtn.pack(side = LEFT, padx = "2m")
  5917.     HelpBtn.menu = Menu(HelpBtn)
  5918.     HelpBtn.menu.add_command(label = "Help Edit",font = H_16,command=helpEdit)
  5919.     HelpBtn.menu.add_command(label = "Help Run",font = H_16,command=helpRun)
  5920.     HelpBtn.menu.add_command(label = "Help Keys",font = H_16,command=helpKeys)
  5921.     HelpBtn['menu'] = HelpBtn.menu
  5922.     return HelpBtn
  5923.  
  5924. FileBtn = makeFileMenu()
  5925. EditBtn = makeEditMenu()
  5926. RunBtn = makeRunMenu()
  5927. RunBtn.configure(state = DISABLED)
  5928. InternalsBtn = makePopupMenu()
  5929. ViewBtn = makeViewMenu()
  5930. OptionBtn = makeOptionsMenu()
  5931. AboutBtn = makeAboutMenu()
  5932. HelpBtn = makeHelpMenu()
  5933.  
  5934. #mBar.tk_menuBar(FileBtn,EditBtn,RunBtn,InternalsBtn,ViewBtn,OptionBtn,AboutBtn,HelpBtn)
  5935.  
  5936.  
  5937. #############################################################################
  5938. #
  5939. # End Menu Section
  5940. #
  5941. #############################################################################
  5942. #
  5943. #  The following code used for the codePanel was taken from
  5944. #
  5945. #      tkinter.unpy.net/wiki
  5946. #
  5947.  
  5948. class VerticalScrolledFrame(Frame):
  5949.     def __init__(self, parent, *args, **kw):
  5950.         Frame.__init__(self,parent,*args,**kw)
  5951.  
  5952.         vscrollbar = Scrollbar(self, orient=VERTICAL)
  5953.         vscrollbar.pack(fill=Y,side=RIGHT,expand=FALSE)
  5954.         canvas = Canvas(self, height=510,bd=0,highlightthickness=0,yscrollcommand=vscrollbar.set)
  5955.         canvas.pack(side=LEFT,fill=BOTH,expand=TRUE)
  5956.         vscrollbar.config(command=canvas.yview)
  5957.  
  5958.         canvas.xview_moveto(0)
  5959.         canvas.yview_moveto(0)
  5960.  
  5961.         self.interior = interior = Frame(canvas)
  5962.         interior_id = canvas.create_window(0,0,window=interior,anchor=NW)
  5963.  
  5964.         def _configure_interior(event):
  5965.  
  5966.             size = (interior.winfo_reqwidth(),interior.winfo_reqheight())
  5967.             canvas.config(scrollregion="0 0 %s %s" % size)
  5968.             if interior.winfo_reqwidth() != canvas.winfo_width():
  5969.                 canvas.config(width = interior.winfo_reqwidth())
  5970.  
  5971.         interior.bind('<Configure>', _configure_interior)
  5972.  
  5973.         def _configure_canvas(event):
  5974.  
  5975.             if interior.winfo_reqwidth() != canvas.winfo_width():
  5976.                 canvas.itemconfigure(interior_id,width=canvas.winfo_width())
  5977.  
  5978.         canvas.bind('<Configure>', _configure_canvas)
  5979.  
  5980.         return
  5981.  
  5982. #############################################################################
  5983. #
  5984. # This is the center panel containing the source code:
  5985. #
  5986. #############################################################################
  5987.  
  5988. codePanel = VerticalScrolledFrame(root,width = 440, height = 510, background = "white")
  5989. codePanel.place(x = 400,y = 85)
  5990.  
  5991. m = Frame(codePanel.interior,borderwidth=0,
  5992.                   width = 340,
  5993.                   background = "white")
  5994. m.pack(side = TOP, fill = X, expand = YES)
  5995.  
  5996. #############################################################################
  5997. #
  5998. # This is the memory viewing window:
  5999. #
  6000. #############################################################################
  6001.  
  6002. memoryPanel = Frame(root,width = 200, height = 540, background = "white")
  6003. memoryPanel.place(x = 820,y = 85)
  6004.  
  6005. # Initialize memory with zeros
  6006.  
  6007. addr_bits = 20
  6008. mem = Memory(addr_bits, memoryPanel)
  6009. mem.viewbase = 0
  6010. mem.refresh()
  6011.  
  6012. # Initialize the base setting Window
  6013.  
  6014. lbl = Label(root, background = "red",
  6015.                   foreground = "yellow",
  6016.                   text = "Memory Base:" ,
  6017.                   width = 13,
  6018.                   font = "Arial 16")
  6019.  
  6020. lbl.place(x = 830, y = 44)
  6021.  
  6022.  
  6023. MemBaseBox = build_membox(root)
  6024. MemBaseBox.bind("<Return>", set_viewbase)
  6025.  
  6026. #  Title the screen with the CPU type
  6027.  
  6028. proc_name = Label(root, text = "486 CPU",
  6029.                         background = "blue",
  6030.                         foreground = "yellow",
  6031.                         width = 15,
  6032.                         font = "Arial 24")
  6033.  
  6034. proc_name.place(x = 436,y = 40)
  6035.  
  6036. #
  6037. # Create the registers and the flags
  6038. #
  6039.  
  6040. archnum = 4                                 # only 486 for now
  6041. register_names = ["EAX","EBX","ECX","EDX","ESP","EBP","ESI","EDI"]
  6042. genReg = []
  6043.  
  6044. y_coord = 70
  6045. for r_name in register_names:
  6046.  
  6047.     reg = Modifiable_Register(r_name,32)
  6048.     genReg.append(reg)
  6049.     reg.place(x = 5, y = y_coord)
  6050.     reg.bind("<Return>", reg.quit)
  6051.     y_coord = y_coord + 60
  6052.  
  6053. reg_ebx = genReg[1]
  6054. del genReg[1]
  6055. genReg[3:3] = [reg_ebx]
  6056.  
  6057. flag_names = ["CF","OF","ZF","SF"]
  6058. Flags = {}
  6059.  
  6060. x_coord = 7
  6061. y_coord = 560
  6062. for f_name in flag_names:
  6063.  
  6064.     flag = Flag(f_name)
  6065.     Flags[f_name] = flag
  6066.     flag.place(x = x_coord,y=y_coord)
  6067.     x_coord = x_coord + 75
  6068.     if x_coord > 240:
  6069.         x_coord = 7
  6070.         y_coord = y_coord + 40
  6071.  
  6072. flag_names = ["AF","PF","DF","IF","TF","NT","RF","VM","AC"]
  6073.  
  6074. for f_name in flag_names:
  6075.  
  6076.     flag = Flag(f_name)
  6077.     Flags[f_name] = flag
  6078.  
  6079. EIP = InstructionPointer(32)
  6080.  
  6081.  
  6082. #
  6083. # Segment Register and Descriptor Table Numbers
  6084. #
  6085.  
  6086. register_names = ["ES","CS","SS","DS","FS","GS","LDTS","TSS"]
  6087. segReg = []
  6088.  
  6089. for r_name in register_names:
  6090.     sreg = Viewable_Register(16, r_name)
  6091.     sreg.strvalue.set(" " + "".join(random.sample("0123456789ABCDEF",4)))
  6092.     segReg.append(sreg)
  6093.  
  6094. ES  = 0
  6095. CS  = 1
  6096. SS  = 2
  6097. DS  = 3
  6098. FS  = 4
  6099. GS  = 5
  6100. LDT = 6
  6101. TSS = 7
  6102. GDT = 8
  6103. IDT = 9
  6104.  
  6105. descrVec = [Descr() for i in range(10)]
  6106.  
  6107.  
  6108. debReg = []
  6109. for n in range(8):
  6110.     ireg = Viewable_Register(32, "DR" + str(n))
  6111.     debReg.append(ireg)
  6112.  
  6113. testReg = []
  6114. for n in range(8):
  6115.     ireg = Viewable_Register(32, "TR" + str(n))
  6116.     testReg.append(ireg)
  6117.  
  6118. ctrlReg = []
  6119. for n in range(4):
  6120.     ireg = Viewable_Register(32, "CR" + str(n))
  6121.     ctrlReg.append(ireg)
  6122.  
  6123. #
  6124. #  Create the flags register
  6125. #
  6126. #
  6127. CPL = 0
  6128.  
  6129. IOPL = Viewable_Register(2, "IOPL")
  6130.  
  6131. class Signal:
  6132.     def __init__(self):
  6133.         self.input_register = 0 # Used by IN handler to distinguish AL, AX, EAX
  6134.         self.pending_repeat = ''
  6135.  
  6136. signal = Signal()
  6137.  
  6138. #
  6139. #  Create the User Entry Box Below the Registers and the Code Panel
  6140. #
  6141.  
  6142.  
  6143. User_Entry = Frame(root, height=8,width=80)
  6144. User_Entry.place(x = 5, y = 620)
  6145.    
  6146. userbox_label = Label(User_Entry, background = "green",
  6147.                                      foreground = "black",
  6148.                                      text = "Enter Command:",
  6149.                                      width = 15,
  6150.                                      font = "Arial 20")
  6151.  
  6152. userbox_label.pack(side = LEFT)
  6153. userbox_label.bind('<Button-1>', interpret)
  6154.  
  6155.  
  6156. entrybox_contents = StringVar()
  6157. entrybox=Entry(User_Entry, relief=SUNKEN,
  6158.                        textvariable=entrybox_contents,
  6159.                        width = 32,
  6160.                        background = "white",
  6161.                        font = "Arial 20")
  6162.  
  6163. def getEntry(event,d=entrybox_contents):
  6164.     user_entry = d.get()
  6165.     d.set('')
  6166.     if prog.execstate == 'stepping':
  6167.         return
  6168.     elif prog.execstate == 'running':
  6169.         return
  6170.     elif prog.execstate == 'blocked':
  6171.         input_data(user_entry)
  6172.     elif prog.execstate in ['interpreting', 'inserting','changing']:
  6173.         if user_entry.strip() == '':
  6174.             prog.set_execstate('stepping')
  6175.             return
  6176.         line = build_line(user_entry)
  6177.         if type(line) is str:
  6178.             print_feedback(line)
  6179.             return
  6180.         if prog.execstate == 'inserting':
  6181.             prog.instinsert(line)
  6182.             prog.store()
  6183.             prog.refresh()
  6184. #           prog.set_current_inst(instnum = prog.current_inst)  # New code
  6185.             if prog.current_inst == len(prog.codelist)-1:
  6186.                 pass
  6187.             else:
  6188.                 prog.set_current_inst(instnum = prog.current_inst )
  6189.             mem.refresh()
  6190.         elif prog.execstate == 'changing':
  6191.             prog.instdelete()
  6192.             prog.instinsert(line)
  6193.             mem.refresh()
  6194.             prog.set_execstate('stepping')
  6195.             prog.refresh()
  6196.         else:
  6197.             if line.hexcode == '':
  6198.                 print_feedback("Unknown command: ")
  6199.                 return
  6200.             prog.stored_command = line.hexcode
  6201.             prog.execstack.append(user_entry)
  6202.             prog.execstackpointer = 0
  6203.             save_EIP = EIP.getvalue()
  6204.             EIP.setvalue(prog.store_origin)
  6205.             try:
  6206.                 fetchexec()
  6207.             except x86exception as e:
  6208.                 print_feedback("Exception "+str(e.interrupt_number)+': '+ e.error_message+ '  ')
  6209.             EIP.setvalue(save_EIP)
  6210.             prog.set_current_inst(instoffset = save_EIP)
  6211.  
  6212. def space_off(event):
  6213.     root.unbind('<KeyPress-space>')
  6214.  
  6215. def space_on(event):
  6216.     root.bind('<KeyPress-space>', spacebar_handle)
  6217.  
  6218. entrybox.pack(side=LEFT,expand=YES,fill=BOTH)
  6219. entrybox.bind("<Return>", getEntry)
  6220. entrybox.bind("<Enter>", space_off, '+')
  6221. entrybox.bind("<Leave>", space_on, '+')
  6222.  
  6223. #
  6224. #  Create the Feedback Window at the Bottom of the Screen
  6225. #
  6226.  
  6227. Feedback_Box = Entry(root, width=80,
  6228.                            font = "Arial 20",
  6229.                                      disabledforeground="black",
  6230.                                      disabledbackground ="white",
  6231.                                      state="disabled")
  6232. Feedback_Box.place(x = 5, y = 670)
  6233.  
  6234. def print_feedback(text, delete = False):
  6235.     Feedback_Box["state"]="normal"
  6236.     if delete:
  6237.         Feedback_Box.delete(0,END)
  6238.     Feedback_Box.insert(0, text)
  6239.     Feedback_Box["state"]="disabled"
  6240.  
  6241. def print_output(text):
  6242.     global Data_Box
  6243.     try:
  6244.         Data_Box.insert(END, text + '\n')
  6245.     except:
  6246.         m = Toplevel(root,width = 100, height = 590)
  6247.         m.wm_geometry(Display_Geometry)
  6248.         m.title("Program Output")
  6249.         m.wm_attributes("-topmost", 1)
  6250.         Data_Box = Text(m,width = 20,height = 100,font = "Arial 20", state = "normal")
  6251.         Data_Box.pack(side = TOP)
  6252.         Data_Box.insert(END, text + '\n')
  6253.  
  6254.    
  6255. #
  6256. #  Add Key Bindings
  6257. #
  6258.  
  6259.  
  6260. def key_Down_handle(event):
  6261.     if prog.execstate == 'stepping' or prog.execstate == 'inserting':
  6262.         if prog.current_inst == len(prog.codelist)-1:
  6263.             pass
  6264.         else:
  6265.             prog.set_current_inst(instnum = prog.current_inst )
  6266.     elif prog.execstate == 'interpreting':
  6267.         if   prog.execstackpointer < 0:
  6268.             prog.execstackpointer = prog.execstackpointer + 1
  6269.         if   prog.execstackpointer < 0:
  6270.             entrybox_contents.set(prog.execstack[prog.execstackpointer])
  6271.         elif   prog.execstackpointer == 0:
  6272.             entrybox_contents.set('               ')
  6273.  
  6274.  
  6275. def key_Up_handle(event):
  6276.     if prog.execstate == 'stepping' or prog.execstate == 'inserting':
  6277.         if prog.current_inst == 1:
  6278.             pass
  6279.         else:
  6280.             prog.set_current_inst(instnum = prog.current_inst -2)
  6281.     elif prog.execstate == 'interpreting':
  6282.         if  - prog.execstackpointer < len(prog.execstack):
  6283.             prog.execstackpointer = prog.execstackpointer - 1
  6284.             entrybox_contents.set(prog.execstack[prog.execstackpointer])
  6285.            
  6286.  
  6287. def key_c_handle(event):
  6288.     if prog.execstate == 'stepping':
  6289.         changeline()
  6290.  
  6291. def key_d_handle(event):
  6292.     if prog.execstate == 'stepping':
  6293.         delete_current()
  6294.  
  6295. def key_i_handle(event):
  6296.     if prog.execstate == 'stepping':
  6297.         insert_mode()
  6298.  
  6299. def key_j_handle(event):
  6300.     if prog.execstate == 'stepping' or prog.execstate == 'inserting':
  6301.         if prog.current_inst == len(prog.codelist)-1:
  6302.             pass
  6303.         else:
  6304.             prog.set_current_inst(instnum = prog.current_inst )
  6305.  
  6306. def key_k_handle(event):
  6307.     if prog.execstate == 'stepping' or prog.execstate == 'inserting':
  6308.         if prog.current_inst == 1:
  6309.             pass
  6310.         else:
  6311.             prog.set_current_inst(instnum = prog.current_inst -2)
  6312.  
  6313. def key_p_handle(event):
  6314.     if prog.execstate == 'stepping':
  6315.         insert_saved_line()
  6316.  
  6317. def key_q_handle(event):
  6318.     if prog.execstate == 'stepping':
  6319.         FileBtn.quit()
  6320.  
  6321. def key_r_handle(event):
  6322.     if prog.execstate == 'stepping':
  6323.         open_same_file()
  6324.  
  6325. def do_nothing(e=None):
  6326.     pass
  6327.  
  6328. def spacebar_handle(event):
  6329.     if prog.execstate == 'stepping':
  6330.         try:
  6331.             fetchexec()
  6332.         except x86exception as e:
  6333.             print_feedback("Exception "+str(e.interrupt_number)+': '+ e.error_message + '  ')
  6334.  
  6335. def key_y_handle(event):
  6336.         print_feedback("current_inst = " + str(prog.current_inst))
  6337.         print_feedback("EIP = " + str(EIP.getvalue()))
  6338.  
  6339.  
  6340. root.bind('<KeyRelease-F5>', continue_execution)
  6341. root.bind('<KeyPress-c>',    key_c_handle)
  6342. root.bind('<KeyPress-d>',    key_d_handle)
  6343. root.bind('<KeyPress-i>',    key_i_handle)
  6344. root.bind('<KeyPress-j>',    key_j_handle)
  6345. root.bind('<KeyPress-k>',    key_k_handle)
  6346. root.bind('<KeyPress-p>',    key_p_handle)
  6347. root.bind('<KeyPress-q>',    key_q_handle)
  6348. root.bind('<KeyPress-r>',    key_r_handle)
  6349. root.bind('<KeyPress-y>',    key_y_handle)
  6350. root.bind('<KeyPress-Down>', key_Down_handle)
  6351. root.bind('<KeyPress-Up>',   key_Up_handle)
  6352. root.bind('<KeyPress-space>',spacebar_handle)
  6353. root.bind('<KeyPress-Tab>',  do_nothing)
  6354.  
  6355. #
  6356. #  Start with a command line program if there is one
  6357. #
  6358. prog = Program()
  6359. prog.refresh()
  6360.  
  6361. if len(sys.argv) > 1:
  6362.     if os.path.isfile(sys.argv[1]):
  6363.         open_file(sys.argv[1]) 
  6364.         prog.filename = sys.argv[1]
  6365.     else:
  6366.         print_feedback("Couldn't find file: " + sys.argv[1])
  6367.         prog.set_execstate('interpreting')
  6368. else:
  6369.     prog.set_execstate('interpreting')
  6370.  
  6371. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement