?login_element?

Subversion Repositories NedoOS

Rev

Rev 1132 | Rev 1205 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. beginmovs
  2.  
  3.         ALIGNrm
  4. MOVrm8i8
  5.         get
  6.         next
  7. ;a=MD000R/M: mov r/m,i8
  8. ;MD=00: mov [...],i8
  9. ;MD=01: mov [...+disp8],i8
  10. ;MD=10: mov [...+disp16],i8
  11. ;MD=11: mov r/m,i8 ;проще всего, но не имеет смысла (есть короткий код)
  12.         cp 0b11000000
  13.         ;jr c,MOVrmmemi8
  14.         jr nc,MOVr8i8
  15. ;MOVrmmemi8
  16.        ADDRm16_for_PUTm8a_nokeepaf
  17.         get
  18.         next
  19.        _PUTm8aLoopC_oldpglx
  20. MOVr8i8
  21.        sub 64
  22.         ld l,a
  23.         ld h,_AX/256
  24.         ld l,(hl) ;rm addr
  25.         get
  26.         next
  27.         ld (hl),a
  28.        _Loop_
  29.  
  30.         ALIGNrm
  31. MOVrm16i16
  32.         get
  33.         next
  34. ;a=MD000R/M: mov r/m,i16
  35. ;MD=00: mov [...],i16
  36. ;MD=01: mov [...+disp8],i16
  37. ;MD=10: mov [...+disp16],i16
  38. ;MD=11: mov r/m,i16 ;проще всего, но не имеет смысла (есть короткий код)
  39.         cp 0b11000000
  40.         ;jr c,MOVrmmemi16
  41.         jr nc,MOVr16i16
  42. ;MOVrmmemi16
  43.        ADDRm16_for_PUTm16_nokeepaf
  44.         getBC
  45.        _PUTm16LoopC
  46. MOVr16i16
  47.         ADDRr16_nokeepa ;rm addr
  48.         getBC
  49.        _PUTr16Loop_
  50.  
  51.         ALIGNrm
  52. MOVrmr8
  53.         get
  54.         next
  55. ;a=MDregR/M
  56. ;MD=00: mov [...],reg8
  57. ;MD=01: mov [...+disp8],reg8
  58. ;MD=10: mov [...+disp16],reg8
  59. ;MD=11: mov r/m,reg8 ;проще всего
  60.         cp 0b11000000
  61.         jr c,MOVrmmemr8
  62.         ld l,a
  63.         ld h,_AX/256
  64.         ld l,(hl) ;reg8 addr
  65.         ld c,(hl)
  66.        sub 64
  67.         ld l,a
  68.         ld l,(hl) ;rm addr
  69.         ld (hl),c
  70.        _Loop_
  71. MOVrmmemr8
  72.        push af
  73.        ADDRm16_for_PUTm8a_nokeepaf
  74.        pop af
  75.         or 0b11000000
  76.         ld c,a
  77.         ld b,_AX/256
  78.         ld a,(bc) ;reg8 addr
  79.         ld c,a
  80.         ld a,(bc)
  81.        _PUTm8aLoopC_oldpglx
  82.  
  83.         ALIGNrm
  84. MOVrmr16
  85.         get
  86.         next
  87. ;a=MDregR/M
  88. ;MD=00: mov [...],reg16
  89. ;MD=01: mov [...+disp8],reg16
  90. ;MD=10: mov [...+disp16],reg16
  91. ;MD=11: mov r/m,reg16 ;проще всего
  92.         cp 0b11000000
  93.         jr c,MOVrmmemr16
  94.        ld h,a
  95.         rra
  96.         rra
  97.         and 7*2
  98.         ld l,a
  99.        ld a,h
  100.         ld h,_AX/256
  101.         ld c,(hl)
  102.         inc l
  103.         ld b,(hl) ;reg16
  104.        and 7
  105.        add a,a
  106.         ld l,a ;rm addr
  107.        _PUTr16Loop_
  108. MOVrmmemr16
  109.        ADDRm16_for_PUTm16
  110.        push hl
  111.         rra
  112.         rra
  113.         and 7*2
  114.         ld l,a
  115.         ld h,_AX/256
  116.         ld c,(hl)
  117.         inc l
  118.         ld b,(hl) ;reg16
  119. pophl_PUTm16LoopC
  120.        pop hl
  121.        _PUTm16LoopC
  122.  
  123.         ALIGNrm
  124. POPrm16
  125.         get
  126.         next
  127.         cp 0b11000000
  128.         jr nc,$ ;not mem
  129.         ADDRm16_for_PUTm16_nokeepaf
  130.         push hl
  131.         getmemspBC
  132.        ; pop hl
  133.        ;_PUTm16LoopC
  134.        jr pophl_PUTm16LoopC
  135.  
  136.         ALIGNrm
  137. MOVr8rm
  138.         get
  139.         next
  140. ;a=MDregR/M
  141. ;MD=00: mov reg8,[...]
  142. ;MD=01: mov reg8,[...+disp8]
  143. ;MD=10: mov reg8,[...+disp16]
  144. ;MD=11: mov reg8,r/m ;проще всего
  145.         cp 0b11000000
  146.         jp c,MOVr8rmmem
  147.         ADDRr8 ;rm addr
  148.         ld c,(hl)
  149.        ld l,a
  150.         ld l,(hl) ;reg8 addr
  151.         ld (hl),c
  152.        _Loop_
  153. MOVr8rmmem
  154.        ADDRm16_GETm8b_keepaf
  155.        or 0b11000000
  156.         ld l,a
  157.         ld h,_AX/256
  158.         ld l,(hl) ;reg8 addr
  159.         ld (hl),b
  160.        _LoopC
  161.  
  162.         ALIGNrm
  163. MOVr16rm
  164.         get
  165.         next
  166. ;a=MDregR/M
  167. ;MD=00: mov reg16,[...]
  168. ;MD=01: mov reg16,[...+disp8]
  169. ;MD=10: mov reg16,[...+disp16]
  170. ;MD=11: mov reg16,r/m ;проще всего
  171.         cp 0b11000000
  172.         jr c,MOVr16rmmem
  173.         ADDRr16_keepa
  174.         ld c,(hl)
  175.         inc l
  176.         ld b,(hl) ;rm
  177.         rra
  178.         rra
  179.         and 7*2
  180.         ld l,a ;reg16 addr
  181.        _PUTr16Loop_
  182. MOVr16rmmem
  183.        ADDRm16_GETm16 ;bc=rmmem
  184.         rra
  185.         rra
  186.         and 7*2
  187.         ld l,a ;reg16 addr
  188.         ld h,_AX/256
  189.        _PUTr16LoopC_AisL
  190.  
  191.         ALIGNrm
  192. MOVsregrm16
  193.         get
  194.         next
  195. ;a=MDregR/M
  196. ;MD=00: mov sreg,[...]
  197. ;MD=01: mov sreg,[...+disp8]
  198. ;MD=10: mov sreg,[...+disp16]
  199. ;MD=11: mov sreg,r/m ;проще всего
  200.         cp 0b11000000
  201.         jr c,MOVsregrmmem
  202.         ADDRr16_keepa
  203.         ld c,(hl)
  204.         inc l
  205.         ld b,(hl) ;rm
  206.         jr MOVsregrmq
  207. MOVsregrmmem
  208.        ADDRm16_GETm16 ;bc=rmmem
  209.         ld h,_AX/256
  210. MOVsregrmq
  211.         rra
  212.         rra
  213.         and 7*2
  214.         add a,_ES&0xff
  215.         ld l,a
  216.         ld (hl),c
  217.         inc l
  218.         ld (hl),b
  219. ;count?S
  220.         xor a
  221.         sla c
  222.         rl b
  223.         rla
  224.         sla c
  225.         rl b
  226.         rla
  227.         sla c
  228.         rl b
  229.         rla
  230.         sla c
  231.         rl b
  232.         rla
  233.         set 5,l ;0x11 -> 0x31
  234.         ld (hl),b
  235.         dec l
  236.         ld (hl),c
  237.         res 4,l
  238.         ld (hl),a
  239.        _LoopC
  240.  
  241.         ALIGNrm
  242. MOVrm16sreg
  243.         get
  244.         next
  245. ;a=MDregR/M
  246. ;MD=00: mov [...],sreg16
  247. ;MD=01: mov [...+disp8],sreg16
  248. ;MD=10: mov [...+disp16],sreg16
  249. ;MD=11: mov r/m,sreg16 ;проще всего
  250.         cp 0b11000000
  251.         jr c,MOVrmmemsreg
  252.        ld h,a
  253.         rra
  254.         rra
  255.         and 7*2
  256.         add a,_ES&0xff
  257.         ld l,a ;sreg16 addr
  258.        ld a,h
  259.         ld h,_ES/256
  260.         ld c,(hl)
  261.         inc l
  262.         ld b,(hl)
  263.        and 7
  264.        add a,a
  265.         ld l,a ;rm addr
  266.        _PUTr16Loop_
  267. MOVrmmemsreg
  268.        ADDRm16_for_PUTm16
  269.        push hl
  270.         rra
  271.         rra
  272.         and 7*2
  273.         add a,_ES&0xff ;единственное отличие от MOVrmmemr16
  274.         ld l,a ;sreg16 addr
  275.         ld h,_ES/256
  276.         ld c,(hl)
  277.         inc l
  278.         ld b,(hl)
  279.        pop hl
  280.        _PUTm16LoopC
  281.  
  282.        display "movs size=",$-beginmovs
  283. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  284. beginalus
  285.  
  286.         ALIGNrm
  287. GRP1rmi8
  288.         get
  289.         next
  290. ;a=MD000R/M: add r/m,i8
  291. ;a=MD001R/M: or r/m,i8
  292. ;a=MD010R/M: adc r/m,i8
  293. ;a=MD011R/M: sbb r/m,i8
  294. ;a=MD100R/M: and r/m,i8
  295. ;a=MD101R/M: sub r/m,i8
  296. ;a=MD110R/M: xor r/m,i8
  297. ;a=MD111R/M: cmp r/m,i8
  298.         cp 0b11000000
  299.         jr c,GRP1rmmemi8
  300.        ADDRr8
  301.        rla
  302.        rla
  303.        rla
  304.        jr c,GRP1rmi8_1xx
  305.        add a,a
  306.        jp p,GRP1rmi8_ADD_ADC
  307.        jr c,SBBrmi8
  308.         get
  309.         or (hl)
  310.         jr GRP1rmi8logicstoreq
  311. SBBrmi8
  312.         ex af,af' ;' ;old CF for sbb
  313.         get
  314. SUBrmi8
  315.         ld c,a
  316.         ld a,(hl)
  317.         sbc a,c
  318.         jr GRP1rmi8storeq
  319. GRP1rmi8_ADD_ADC
  320.        jr nc,ADDrmi8 ;CF=0 for add
  321.         ex af,af' ;' ;old CF for adc
  322. ADDrmi8
  323.         get
  324.         adc a,(hl)
  325. GRP1rmi8storeq
  326.         ld (hl),a
  327. GRP1rmi8q
  328.         KEEPHFCFPARITYOVERFLOW_FROMA
  329.         next ;doesn't keep SF
  330.        _LoopC      
  331. GRP1rmi8_1xx
  332.        add a,a
  333.         get
  334.        jp p,GRP1rmi8_AND_XOR      
  335.        jr nc,SUBrmi8 ;CF=0 for sub
  336. ;CMPrmi8
  337.         ld c,a
  338.         ld a,(hl)
  339.         sub c
  340.         jr GRP1rmi8q        
  341. GRP1rmi8_AND_XOR
  342.         jr c,XORrmi8
  343.         and (hl)
  344. GRP1rmi8logicstoreq
  345.         ld (hl),a
  346.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  347.         next ;doesn't keep SF
  348.        _LoopC
  349. XORrmi8
  350.         xor (hl)
  351.         jr GRP1rmi8logicstoreq
  352. GRP1rmmemi8
  353.        ADDRm16_GETm8c_for_PUTm8
  354.        rla
  355.        rla
  356.        rla
  357.        jr c,GRP1rmmemi8_1xx
  358.        add a,a
  359.        jp p,GRP1rmmemi8_ADD_ADC
  360.        jr c,SBBrmmemi8
  361.         get
  362.         or c
  363.         jr GRP1rmmemi8logicstoreq
  364. SBBrmmemi8
  365.         ex af,af' ;' ;old CF for sbb
  366.         get
  367. SUBrmmemi8
  368.         ld b,a
  369.         ld a,c ;rmmem
  370.         sbc a,b
  371.         jr GRP1rmmemi8storeq
  372. GRP1rmmemi8_ADD_ADC
  373.        jr nc,ADDrmmemi8 ;CF=0 for add
  374.         ex af,af' ;' ;old CF for adc
  375. ADDrmmemi8
  376.         get
  377.         adc a,c
  378. GRP1rmmemi8storeq
  379.         ld c,a
  380.         KEEPHFCFPARITYOVERFLOW_FROMA
  381.         next ;doesn't keep SF
  382.        _PUTm8cLoopC_oldpglx
  383. GRP1rmmemi8_1xx
  384.        add a,a
  385.         get
  386.        jp p,GRP1rmmemi8_AND_XOR      
  387.        jr nc,SUBrmmemi8 ;CF=0 for sub
  388. ;CMPrmmemi8
  389.         ld b,a
  390.         ld a,c
  391.         sub b
  392.         KEEPHFCFPARITYOVERFLOW_FROMA
  393.         next ;doesn't keep SF
  394.        _LoopC
  395. GRP1rmmemi8_AND_XOR
  396.         jr c,XORrmmemi8
  397.         and c
  398. GRP1rmmemi8logicstoreq
  399.         ld c,a
  400.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  401.         next ;doesn't keep SF
  402.        _PUTm8cLoopC_oldpglx
  403. XORrmmemi8
  404.         xor c
  405.         jr GRP1rmmemi8logicstoreq
  406.  
  407. GRP1rmi16_ADD_ADC
  408.        jr nc,ADDr16i16 ;CF=0 for add
  409.         ex af,af' ;' ;old CF for adc
  410. ADDr16i16
  411.         get
  412.         next
  413.         ld c,a
  414.         get
  415.         ld b,a
  416. ADCr16bc
  417.         ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  418. GRP1rmi16q
  419.         next
  420. GRP2r16i8q
  421.        _PUTr16hlLoop_
  422.         ALIGNrm
  423. GRP1rmi16
  424.         get
  425.         next
  426. ;a=MD000R/M: add r/m,i16
  427. ;a=MD001R/M: or r/m,i16
  428. ;a=MD010R/M: adc r/m,i16
  429. ;a=MD011R/M: sbb r/m,i16
  430. ;a=MD100R/M: and r/m,i16
  431. ;a=MD101R/M: sub r/m,i16
  432. ;a=MD110R/M: xor r/m,i16
  433. ;a=MD111R/M: cmp r/m,i16
  434.         cp 0b11000000
  435.         jp c,GRP1rmmemi16
  436.        ADDRr16_keepa
  437.        push hl
  438.         GETr16_hl
  439.        rla
  440.        rla
  441.        rla
  442.        jr c,GRP1rmi16_1xx
  443.        add a,a
  444.        jp p,GRP1rmi16_ADD_ADC
  445.        jr c,SBBr16i16
  446. ;ORr16i16
  447.         get
  448.         next
  449.         or l
  450.         ld l,a
  451.         get
  452.         or h
  453.         jp GRP1rmi16logicq        
  454. SBBr16i16
  455.         ex af,af' ;' ;old CF for sbb
  456.         get
  457. SUBr16i16
  458.         next
  459.         ld c,a
  460.         get
  461.         ld b,a
  462. SBCr16bc
  463.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  464.         jp GRP1rmi16q
  465. GRP1rmi16_1xx
  466.        add a,a
  467.         get
  468.        jp p,GRP1rmi16_AND_XOR
  469.        jr nc,SUBr16i16 ;CF=0 for sub
  470. CMPr16i16
  471.         next
  472.         ld c,a
  473.         get
  474. CMPr16hlac
  475.         ld b,a
  476.         or a
  477.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  478.        pop hl ;skip
  479.         next
  480.        _LoopC
  481. GRP1rmi16_AND_XOR
  482.         next
  483.         jr c,XORr16i16
  484. ;ANDr16i16
  485.         and l
  486.         ld l,a
  487.         get
  488.         and h
  489. GRP1rmi16logicq
  490.         ld h,a
  491.         KEEPLOGICCFPARITYOVERFLOW_FROMHL_AisH
  492.         next
  493.        _PUTr16hlLoop_
  494. XORr16i16
  495.         xor l
  496.         ld l,a
  497.         get
  498.         xor h
  499.         jr GRP1rmi16logicq
  500. GRP1rmmemi16_ADD_ADC
  501.        jr nc,ADDrmmemi16 ;CF=0 for add
  502.         ex af,af' ;' ;old CF for adc
  503. ADDrmmemi16
  504.         get
  505.         next
  506.         ld c,a
  507.         get
  508.         ld b,a
  509. ADCrmmem16bc
  510.         ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  511. GRP1rmmemi16q
  512.         next
  513.        _PUTm16hlLoopC
  514. GRP1rmmemi16
  515.         ADDRm16_GETm16_for_PUTm16
  516.        push hl
  517.         ld h,b
  518.         ld l,c
  519.        rla
  520.        rla
  521.        rla
  522.        jr c,GRP1rmmemi16_1xx
  523.        add a,a
  524.        jp p,GRP1rmmemi16_ADD_ADC
  525.        jr c,SBBrmmemi16
  526. ;ORrmmemi16
  527.         get
  528.         next
  529.         or l
  530.         ld l,a
  531.         get
  532.         or h
  533.         jr GRP1rmmemi16logicq
  534. SBBrmmemi16
  535.         ex af,af' ;' ;old CF for sbb
  536.         get
  537. SUBrmmemi16
  538.         next
  539.         ld c,a
  540.         get
  541.         ld b,a
  542. SBBrmmem16bc
  543.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  544.         jp GRP1rmmemi16q        
  545. GRP1rmmemi16_1xx
  546.        add a,a
  547.         get
  548.        jp p,GRP1rmmemi16_AND_XOR
  549.        jr nc,SUBrmmemi16
  550.         jp CMPr16i16
  551. GRP1rmmemi16_AND_XOR
  552.         next
  553.        jr c,XORrmmemi16
  554. ;ANDrmmemi16
  555.         and l
  556.         ld l,a
  557.         get
  558.         and h
  559. GRP1rmmemi16logicq
  560.         ld h,a
  561.         KEEPLOGICCFPARITYOVERFLOW_FROMHL_AisH
  562.         next
  563.        _PUTm16hlLoopC
  564. XORrmmemi16
  565.         xor l
  566.         ld l,a
  567.         get
  568.         xor h
  569.         jr GRP1rmmemi16logicq
  570.  
  571.         ALIGNrm
  572. GRP1rm16i8 ;операнд расширяется со знаком (проверено)
  573.         get
  574.         next
  575. ;a=MD000R/M: add r/m,i8
  576. ;a=MD010R/M: adc r/m,i8
  577. ;a=MD011R/M: sbb r/m,i8
  578. ;a=MD101R/M: sub r/m,i8
  579. ;a=MD111R/M: cmp r/m,i8
  580.         cp 0b11000000
  581.         jr c,GRP1rmmem16i8
  582.        ADDRr16_keepa
  583.        push hl
  584.         GETr16_hl
  585.        rla
  586.        rla
  587.        rla
  588.        jr c,GRP1rm16i8_1xx
  589.        add a,a
  590.        jp p,GRP1rm16i8_ADD_ADC
  591.        jr nc,$ ;no OR
  592.        ;jr c,SBBr16i8
  593.         ex af,af' ;'
  594. SUBr16i8
  595.         ex af,af' ;'
  596. SBBr16i8
  597.         get
  598.         ld c,a
  599.         rla
  600.         sbc a,a
  601.         ld b,a
  602.         ex af,af' ;'
  603.         jp SBCr16bc ;там next
  604. GRP1rm16i8_ADD_ADC
  605.        jr c,ADCr16i8
  606. ;ADDr16i8
  607.         ex af,af' ;'
  608. ADCr16i8
  609.         get
  610.         ld c,a
  611.         rla
  612.         sbc a,a
  613.         ld b,a
  614.         ex af,af' ;'
  615.         jp ADCr16bc ;там next
  616. GRP1rm16i8_1xx
  617.        add a,a
  618.        ;jp p,$ ;no AND,XOR??? used in para512!
  619.        jp p,GRP1rm16i8_AND_XOR
  620.        jr nc,SUBr16i8
  621. CMPr16i8
  622.         get
  623.         ld c,a
  624.         rla
  625.         sbc a,a
  626.         jp CMPr16hlac ;там next
  627. GRP1rm16i8_AND_XOR
  628.        jr c,XORr16i8
  629.         get
  630.         ld c,a
  631.         and l
  632.         ld l,a
  633.         ld a,c
  634.         rla
  635.         sbc a,a
  636.         and h
  637.         jp GRP1rmi16logicq ;al=result ;там next
  638. XORr16i8
  639.         get
  640.         ld c,a
  641.         xor l
  642.         ld l,a
  643.         ld a,c
  644.         rla
  645.         sbc a,a
  646.         xor h
  647.         jp GRP1rmi16logicq ;al=result ;там next
  648.  
  649. GRP1rmmem16i8
  650.         ADDRm16_GETm16_for_PUTm16
  651.        push hl
  652.         ld h,b
  653.         ld l,c
  654.        rla
  655.        rla
  656.        rla
  657.        jr c,GRP1rmmem16i8_1xx
  658.        add a,a
  659.        jp p,GRP1rmmem16i8_ADD_ADC
  660.        ;jr c,SBBrmmem16i8
  661.        jr nc,$ ;no OR
  662.         ex af,af' ;'
  663. SUBrmmem16i8
  664.         ex af,af' ;'
  665. SBBrmmem16i8
  666.         get
  667.         ld c,a
  668.         rla
  669.         sbc a,a
  670.         ld b,a
  671.         ex af,af' ;'
  672.         jp SBBrmmem16bc ;там next
  673. GRP1rmmem16i8_ADD_ADC
  674.        jr c,ADCrmmem16i8
  675. ;ADDrmmem16i8
  676.         ex af,af' ;'
  677. ADCrmmem16i8
  678.         get
  679.         ld c,a
  680.         rla
  681.         sbc a,a
  682.         ld b,a
  683.         ex af,af' ;'
  684.         jp ADCrmmem16bc ;там next
  685. GRP1rmmem16i8_1xx
  686.        add a,a
  687.        jp p,$ ;no AND,XOR
  688.        jr nc,SUBrmmem16i8
  689.         jr CMPr16i8
  690.  
  691. ;--------------- alu single calls
  692.        macro OPrmr8_PRE
  693.         get
  694.         next
  695. ;a=MDregR/M
  696. ;MD=00: cmd [...],reg8
  697. ;MD=01: cmd [...+disp8],reg8
  698. ;MD=10: cmd [...+disp16],reg8
  699. ;MD=11: cmd r/m,reg8 ;проще всего
  700.         cp 0b11000000
  701.         jp c,6f;OPrmmemr8
  702.         ld l,a
  703.         ld h,_AX/256
  704.         ld l,(hl) ;reg8 addr
  705.         ld c,(hl)
  706.        sub 64
  707.         ld l,a
  708.         ld l,(hl) ;rm addr
  709.         ;op (hl),c
  710.        endm
  711.        macro OPrmr8_POST
  712. 6;OPrmmemr8
  713.        ADDRm16_GETm8c_for_PUTm8
  714.         or 0b11000000
  715.         ;ld l,a
  716.         ;ld h,_AX/256
  717.         ;ld l,(hl) ;reg8 addr
  718.         ;op c,(hl)
  719.        endm
  720.  
  721.         ALIGNrm
  722. ADDrmr8
  723.         or a
  724.         ex af,af' ;'
  725.         ALIGNrm
  726. ADCrmr8
  727.         OPrmr8_PRE
  728.         ex af,af' ;'
  729.         ld a,(hl)
  730.         adc a,c ;op
  731.         ld (hl),a
  732.         KEEPHFCFPARITYOVERFLOW_FROMA
  733.        _Loop_
  734.         OPrmr8_POST
  735.        push hl
  736.         ld l,a
  737.         ld h,_AX/256
  738.         ld l,(hl) ;reg8 addr
  739.         ex af,af' ;'
  740.         ld a,c
  741.         adc a,(hl) ;op
  742.         ld c,a
  743.         KEEPHFCFPARITYOVERFLOW_FROMA
  744.        pop hl
  745.        _PUTm8cLoopC_oldpglx
  746.  
  747.         ALIGNrm
  748. SUBrmr8
  749.         or a
  750.         ex af,af' ;'
  751.         ALIGNrm
  752. SBBrmr8
  753.         OPrmr8_PRE
  754.         ex af,af' ;'
  755.         ld a,(hl)
  756.         sbc a,c ;op
  757.         ld (hl),a
  758.         KEEPHFCFPARITYOVERFLOW_FROMA
  759.        _Loop_
  760.         OPrmr8_POST
  761.        push hl
  762.         ld l,a
  763.         ld h,_AX/256
  764.         ld l,(hl) ;reg8 addr
  765.         ex af,af' ;'
  766.         ld a,c
  767.         sbc a,(hl) ;op
  768.         ld c,a
  769.         KEEPHFCFPARITYOVERFLOW_FROMA
  770.        pop hl
  771.        _PUTm8cLoopC_oldpglx
  772.  
  773.         ALIGNrm
  774. CMPrmr8
  775.         OPrmr8_PRE
  776.         ld a,(hl)
  777.         sub c ;op
  778.         KEEPHFCFPARITYOVERFLOW_FROMA
  779.        _Loop_
  780. 6;CMPrmmemr8
  781.        ADDRm16_GETm8b_keepaf
  782.        or 0b11000000
  783.         ld l,a
  784.         ld h,_AX/256
  785.         ld l,(hl) ;reg8 addr
  786.        ld a,b
  787.         sub (hl) ;op
  788.         KEEPHFCFPARITYOVERFLOW_FROMA
  789.        _LoopC
  790.  
  791.         ALIGNrm
  792. XORrmr8
  793.         OPrmr8_PRE
  794.         ld a,c
  795.         xor (hl) ;op
  796.         ld (hl),a
  797.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  798.        _Loop_
  799.         OPrmr8_POST
  800.        push hl
  801.         ld l,a
  802.         ld h,_AX/256
  803.         ld l,(hl) ;reg8 addr
  804.         ld a,c
  805.         xor (hl) ;op
  806.         ld c,a
  807.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  808.        pop hl
  809.        _PUTm8cLoopC_oldpglx
  810.  
  811.         ALIGNrm
  812. ORrmr8
  813.         OPrmr8_PRE
  814.         ld a,c
  815.         or (hl) ;op
  816.         ld (hl),a
  817.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  818.        _Loop_
  819.         OPrmr8_POST
  820.        push hl
  821.         ld l,a
  822.         ld h,_AX/256
  823.         ld l,(hl) ;reg8 addr
  824.         ld a,c
  825.         or (hl) ;op
  826.         ld c,a
  827.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  828.        pop hl
  829.        _PUTm8cLoopC_oldpglx
  830.  
  831.         ALIGNrm
  832. ANDrmr8
  833.         OPrmr8_PRE
  834.         ld a,c
  835.         and (hl) ;op
  836.         ld (hl),a
  837.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  838.        _Loop_
  839.         OPrmr8_POST
  840.        push hl
  841.         ld l,a
  842.         ld h,_AX/256
  843.         ld l,(hl) ;reg8 addr
  844.         ld a,c
  845.         and (hl) ;op
  846.         ld c,a
  847.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  848.        pop hl
  849.        _PUTm8cLoopC_oldpglx
  850.  
  851.        macro OPrmr16_PRE
  852.         get
  853.         next
  854. ;a=MDregR/M
  855. ;MD=00: cmd reg16,[...]
  856. ;MD=01: cmd reg16,[...+disp8]
  857. ;MD=10: cmd reg16,[...+disp16]
  858. ;MD=11: cmd reg16,r/m ;проще всего
  859.         cp 0b11000000
  860.         jp c,6f;OPrmmemr16
  861.        ld h,a
  862.         rra
  863.         rra
  864.         and 7*2
  865.         ld l,a ;reg16 addr
  866.        ld a,h
  867.         ld h,_AX/256
  868.         ld c,(hl)
  869.         inc l
  870.         ld b,(hl) ;reg16
  871.         and 7
  872.         add a,a
  873.         ld l,a ;rm addr
  874.        ;push hl
  875.         ;ld hl,(hl)
  876.         ;or a
  877.         ;adc hl,bc ;op
  878.        endm
  879.        macro OPrmr16_POST
  880. 6;OPrmmemr16
  881.         ADDRm16_GETm16_for_PUTm16
  882.       push hl
  883.         ld h,_AX/256
  884.         rra
  885.         rra
  886.         and 7*2
  887.         ld l,a ;reg16 addr
  888.         ;ld hl,(hl)
  889.         ;or a
  890.         ;adc hl,bc ;op
  891.        endm
  892.        macro SUBrmr16_POST
  893. 6;SUBrmmemr16
  894.         ADDRm16_GETm16_for_PUTm16
  895.       push hl
  896.         ld h,_AX/256
  897.         rra
  898.         rra
  899.         and 7*2
  900.         ld l,a ;reg16 addr
  901.        push bc
  902.         ld c,(hl)
  903.         inc l
  904.         ld b,(hl) ;reg16
  905.        pop hl
  906.         ex af,af' ;'
  907.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  908.       _PUTm16hlLoopC
  909.        endm
  910.        macro CMPrmr16_POST
  911. 6;CMPrmmemr16
  912.        ADDRm16_GETm16 ;bc=rmmem
  913.         ld h,_AX/256
  914.         rra
  915.         rra
  916.         and 7*2
  917.         ld l,a ;reg16 addr
  918.        push bc
  919.         ld c,(hl)
  920.         inc l
  921.         ld b,(hl) ;reg16
  922.        pop hl ;rmmem
  923.         or a
  924.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  925.        _LoopC
  926.        endm
  927.  
  928.         ALIGNrm
  929. ADDrmr16
  930.         or a
  931.         ex af,af' ;'
  932.         ALIGNrm
  933. ADCrmr16
  934.         OPrmr16_PRE
  935.        push hl
  936.         ld a,(hl)
  937.         inc l
  938.         ld h,(hl)
  939.         ld l,a
  940.         ex af,af' ;'
  941.         ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  942.        _PUTr16hlLoop_
  943.         OPrmr16_POST
  944.         ld a,(hl)
  945.         inc l
  946.         ld h,(hl)
  947.         ld l,a
  948.         ex af,af' ;'
  949.         ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  950.       _PUTm16hlLoopC
  951.  
  952.         ALIGNrm
  953. SUBrmr16
  954.         or a
  955.         ex af,af' ;'
  956.         ALIGNrm
  957. SBBrmr16
  958.         OPrmr16_PRE
  959.        push hl
  960.         ld a,(hl)
  961.         inc l
  962.         ld h,(hl)
  963.         ld l,a
  964.         ex af,af' ;'
  965.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  966.        _PUTr16hlLoop_
  967.         SUBrmr16_POST
  968.  
  969.         ALIGNrm
  970. CMPrmr16
  971.         OPrmr16_PRE
  972.         ld a,(hl)
  973.         inc l
  974.         ld h,(hl)
  975.         ld l,a
  976.         or a
  977.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  978.        _LoopC
  979.         CMPrmr16_POST
  980.  
  981.         ALIGNrm
  982. XORrmr16
  983.         OPrmr16_PRE
  984.        push hl
  985.         ld a,(hl)
  986.         xor c
  987.         ld c,a
  988.         inc l
  989.         ld a,(hl)
  990.         xor b ;op
  991.         ld b,a
  992.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  993.        pop hl
  994.        _PUTr16Loop_
  995.         OPrmr16_POST
  996.         ld a,(hl)
  997.         xor c
  998.         ld c,a
  999.         inc l
  1000.         ld a,(hl)
  1001.         xor b ;op
  1002.         ld b,a
  1003.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  1004.       pop hl
  1005.       _PUTm16LoopC
  1006.  
  1007.         ALIGNrm
  1008. ORrmr16
  1009.         OPrmr16_PRE
  1010.        push hl
  1011.         ld a,(hl)
  1012.         or c
  1013.         ld c,a
  1014.         inc l
  1015.         ld a,(hl)
  1016.         or b ;op
  1017.         ld b,a
  1018.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  1019.        pop hl
  1020.        _PUTr16Loop_
  1021.         OPrmr16_POST
  1022.         ld a,(hl)
  1023.         or c
  1024.         ld c,a
  1025.         inc l
  1026.         ld a,(hl)
  1027.         or b ;op
  1028.         ld b,a
  1029.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  1030.       pop hl
  1031.       _PUTm16LoopC
  1032.  
  1033.         ALIGNrm
  1034. ANDrmr16
  1035.         OPrmr16_PRE
  1036.        push hl
  1037.         ld a,(hl)
  1038.         and c
  1039.         ld c,a
  1040.         inc l
  1041.         ld a,(hl)
  1042.         and b ;op
  1043.         ld b,a
  1044.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  1045.        pop hl
  1046.        _PUTr16Loop_
  1047.         OPrmr16_POST
  1048.         ld a,(hl)
  1049.         and c
  1050.         ld c,a
  1051.         inc l
  1052.         ld a,(hl)
  1053.         and b ;op
  1054.         ld b,a
  1055.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  1056.       pop hl
  1057.       _PUTm16LoopC
  1058.  
  1059.        macro OPr8rm_PRE
  1060.         get
  1061.         next
  1062. ;a=MDregR/M
  1063. ;MD=00: cmd reg8,[...]
  1064. ;MD=01: cmd reg8,[...+disp8]
  1065. ;MD=10: cmd reg8,[...+disp16]
  1066. ;MD=11: cmd reg8,r/m ;проще всего
  1067.         cp 0b11000000
  1068.         jp c,6f;ADDr8rmmem
  1069.         ADDRr8 ;rm addr
  1070.         ld b,(hl)
  1071. 5;OPr8rmok
  1072.         ld l,a
  1073.         ld l,(hl) ;reg8 addr
  1074.         ;op (hl),b
  1075.        endm
  1076.        macro OPr8rm_POST
  1077. 6;OPr8rmmem
  1078.        ADDRm16_GETm8b_keepaf
  1079.        or 0b11000000
  1080.         ld h,_AX/256
  1081.        jp 5b;OPr8rmok
  1082.        endm
  1083.  
  1084.         ALIGNrm
  1085. ADDr8rm
  1086.         or a
  1087.         ex af,af' ;'
  1088.         ALIGNrm
  1089. ADCr8rm
  1090.         OPr8rm_PRE
  1091.         ex af,af' ;'
  1092.         ld a,(hl)
  1093.         adc a,b ;op
  1094.         ld (hl),a
  1095.         KEEPHFCFPARITYOVERFLOW_FROMA
  1096.        _LoopC
  1097.         OPr8rm_POST
  1098.  
  1099.         ALIGNrm
  1100. SUBr8rm
  1101.         or a
  1102.         ex af,af' ;'
  1103.         ALIGNrm
  1104. SBBr8rm
  1105.         OPr8rm_PRE
  1106.         ex af,af' ;'
  1107.         ld a,(hl)
  1108.         sbc a,b ;op
  1109.         ld (hl),a
  1110.         KEEPHFCFPARITYOVERFLOW_FROMA
  1111.        _LoopC
  1112.         OPr8rm_POST
  1113.  
  1114.         ALIGNrm
  1115. CMPr8rm
  1116.         OPr8rm_PRE
  1117.         ld a,(hl)
  1118.         sub b ;op
  1119.         KEEPHFCFPARITYOVERFLOW_FROMA
  1120.        _LoopC
  1121.         OPr8rm_POST
  1122.  
  1123.         ALIGNrm
  1124. XORr8rm
  1125.         OPr8rm_PRE
  1126.         ld a,(hl)
  1127.         xor b ;op
  1128.         ld (hl),a
  1129.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  1130.        _LoopC
  1131.         OPr8rm_POST
  1132.  
  1133.         ALIGNrm
  1134. ORr8rm
  1135.         OPr8rm_PRE
  1136.         ld a,(hl)
  1137.         or b ;op
  1138.         ld (hl),a
  1139.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  1140.        _LoopC
  1141.         OPr8rm_POST
  1142.  
  1143.         ALIGNrm
  1144. ANDr8rm
  1145.         OPr8rm_PRE
  1146.         ld a,(hl)
  1147.         and b ;op
  1148.         ld (hl),a
  1149.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  1150.        _LoopC
  1151.         OPr8rm_POST
  1152.  
  1153.        macro OPr16rm_PRE
  1154.         get
  1155.         next
  1156. ;a=MDregR/M
  1157. ;MD=00: cmd reg16,[...]
  1158. ;MD=01: cmd reg16,[...+disp8]
  1159. ;MD=10: cmd reg16,[...+disp16]
  1160. ;MD=11: cmd reg16,r/m ;проще всего
  1161.         cp 0b11000000
  1162.         jp c,6f;OPr16rmmem
  1163.         ADDRr16_keepa ;rm addr
  1164.         ld c,(hl)
  1165.         inc l
  1166.         ld b,(hl) ;rm
  1167. 5;OPr16rmok
  1168.         rra
  1169.         rra
  1170.         and 7*2
  1171.         ld l,a ;reg16 addr
  1172.        ;push hl
  1173.         ;ld hl,(hl)
  1174.         ;op hl,bc
  1175.        endm
  1176.        macro OPr16rm_POST
  1177. 6;OPr16rmmem
  1178.        ADDRm16_GETm16 ;bc=rmmem
  1179.         ld h,_AX/256
  1180.        jp 5b;OPr16rmok
  1181.        endm
  1182.        macro CMPr16rmPOST
  1183. 6;CMPr16rmmem
  1184.        ADDRm16_GETm16 ;bc=rmmem
  1185.         ld h,_AX/256
  1186.        jp 5b;OPr16rmok
  1187.        endm
  1188.        macro LOGICOPr16rm_POST
  1189. 6;OPr16rmmem
  1190.        ADDRm16_GETm16 ;bc=rmmem
  1191.         ld h,_AX/256
  1192.        jp 5b;OPr16rmok
  1193.        endm
  1194.  
  1195.         ALIGNrm
  1196. ADDr16rm
  1197.         or a
  1198.         ex af,af' ;'
  1199.         ALIGNrm
  1200. ADCr16rm
  1201.         OPr16rm_PRE
  1202.        push hl
  1203.         ld a,(hl)
  1204.         inc l
  1205.         ld h,(hl)
  1206.         ld l,a
  1207.         ex af,af' ;'
  1208.         ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  1209.         ld b,h
  1210.         ld c,l
  1211.        pop hl
  1212.        _PUTr16LoopC
  1213.         OPr16rm_POST
  1214.  
  1215.         ALIGNrm
  1216. SUBr16rm
  1217.         or a
  1218.         ex af,af' ;'
  1219.         ALIGNrm
  1220. SBBr16rm
  1221.         OPr16rm_PRE
  1222.        push hl
  1223.         ld a,(hl)
  1224.         inc l
  1225.         ld h,(hl)
  1226.         ld l,a
  1227.         ex af,af' ;'
  1228.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  1229.         ld b,h
  1230.         ld c,l
  1231.        pop hl
  1232.        _PUTr16LoopC
  1233.         OPr16rm_POST
  1234.  
  1235.         ALIGNrm
  1236. CMPr16rm
  1237.         OPr16rm_PRE
  1238.         ld a,(hl)
  1239.         inc l
  1240.         ld h,(hl)
  1241.         ld l,a
  1242.         or a
  1243.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  1244.        _LoopC
  1245.        CMPr16rmPOST
  1246.  
  1247.         ALIGNrm
  1248. XORr16rm
  1249.         OPr16rm_PRE
  1250.         ld a,(hl)
  1251.         xor c
  1252.         ld c,a
  1253.         inc l
  1254.         ld a,(hl)
  1255.         xor b
  1256.         ld b,a
  1257.         dec l
  1258.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  1259.        _PUTr16LoopC
  1260.         LOGICOPr16rm_POST
  1261.  
  1262.         ALIGNrm
  1263. ORr16rm
  1264.         OPr16rm_PRE
  1265.         ld a,(hl)
  1266.         or c
  1267.         ld c,a
  1268.         inc l
  1269.         ld a,(hl)
  1270.         or b
  1271.         ld b,a
  1272.         dec l
  1273.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  1274.        _PUTr16LoopC
  1275.         LOGICOPr16rm_POST
  1276.  
  1277.         ALIGNrm
  1278. ANDr16rm
  1279.         OPr16rm_PRE
  1280.         ld a,(hl)
  1281.         and c
  1282.         ld c,a
  1283.         inc l
  1284.         ld a,(hl)
  1285.         and b
  1286.         ld b,a
  1287.         dec l
  1288.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  1289.        _PUTr16LoopC
  1290.         LOGICOPr16rm_POST
  1291.  
  1292.        display "alus size=",$-beginalus
  1293. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1294. beginrolls
  1295.  
  1296.         ALIGNrm
  1297. GRP2rm8i8
  1298.         get
  1299.         next
  1300. ;a=MD000R/M: rol r/m
  1301. ;a=MD001R/M: ror r/m
  1302. ;a=MD010R/M: rcl r/m
  1303. ;a=MD011R/M: rcr r/m
  1304. ;a=MD100R/M: shl r/m
  1305. ;a=MD101R/M: shr r/m
  1306. ;a=MD110R/M: ??? r/m
  1307. ;a=MD111R/M: sar r/m
  1308.         cp 0b11000000
  1309.         jr c,GRP2rmmem8i8
  1310.        ADDRr8 ;rm addr
  1311.        push af ;TODO optimize
  1312.         get
  1313.         next
  1314.         ;if SHIFTCOUNTMASK
  1315.         ;and 31
  1316.         ;endif
  1317.         ld b,a
  1318.        pop af
  1319.        ld c,(hl)
  1320.        rla
  1321.        rla
  1322.        rla
  1323.        jr c,GRP2rm8i8_1xx
  1324.        add a,a
  1325.        jp p,GRP2rm8i8_ROL_RCL ;0x0
  1326.        jr c,RCRr8i8
  1327.         call RORci8
  1328.         ld (hl),c
  1329.        _Loop_
  1330. RCRr8i8
  1331.         call RCRci8
  1332.         ld (hl),c
  1333.        _Loop_        
  1334. GRP2rm8i8_ROL_RCL
  1335.        jr c,RCLr8i8
  1336.         call ROLci8
  1337.         ld (hl),c
  1338.        _Loop_
  1339. RCLr8i8
  1340.         call RCLci8
  1341.         ld (hl),c
  1342.        _Loop_
  1343. GRP2rm8i8_1xx
  1344.        add a,a
  1345.        jp p,SHLr8i8
  1346.        jr c,SARr8i8
  1347.         call SHRci8
  1348.         ld (hl),c
  1349.        _Loop_
  1350. SARr8i8
  1351.         call SARci8
  1352. GRP2r8i8q
  1353.         ld (hl),c
  1354.        _Loop_
  1355. SHLr8i8
  1356.         call SHRci8
  1357.         ld (hl),c
  1358.        _Loop_
  1359. GRP2rmmem8i8
  1360.        ADDRm16_GETm8c_for_PUTm8 ;делает ld lx,c
  1361.        push af ;TODO optimize
  1362.         get
  1363.         next
  1364.         ;if SHIFTCOUNTMASK
  1365.         ;and 31
  1366.         ;endif
  1367.         ld b,a
  1368.        pop af
  1369.        rla
  1370.        rla
  1371.        rla
  1372.        jr c,GRP2rmmem8i8_1xx
  1373.        add a,a
  1374.        jp p,GRP2rmmem8i8_ROL_RCL ;0x0
  1375.        jr c,RCRm8i8
  1376.         call RORci8
  1377.         jr GRP2rmmem8i8q
  1378. RCRm8i8
  1379.         call RCRci8
  1380.         jr GRP2rmmem8i8q
  1381. GRP2rmmem8i8_ROL_RCL
  1382.        jr c,RCLm8i8
  1383.         call ROLci8
  1384.         jr GRP2rmmem8i8q
  1385. RCLm8i8
  1386.         call RCLci8
  1387.         jr GRP2rmmem8i8q
  1388. GRP2rmmem8i8_1xx
  1389.        add a,a
  1390.        jp p,SHLm8i8
  1391.        jr c,SARm8i8
  1392.         call SHRci8
  1393. GRP2rmmem8i8q
  1394.        _PUTm8cLoopC_oldpglx
  1395. SARm8i8
  1396.         call SARci8
  1397.         jr GRP2rmmem8i8q
  1398. SHLm8i8
  1399.         call SHLci8
  1400.         jr GRP2rmmem8i8q
  1401.  
  1402. ;For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result.
  1403. ROLci8
  1404. ROL_c_b
  1405.         ex af,af' ;' ;remember ZF
  1406.         ld a,c
  1407. ROLci8loop
  1408.         rlca
  1409.         djnz ROLci8loop
  1410.         ld c,a
  1411.         exx
  1412.         rra
  1413.         ld e,a ;overflow data
  1414.         rla ;restore CF
  1415.         exx
  1416.         ex af,af' ;'
  1417.         ret
  1418. ;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
  1419. RORci8
  1420. ROR_c_b
  1421.         ex af,af' ;' ;remember ZF
  1422.         ld a,c
  1423. RORci8loop
  1424.         rrca
  1425.         djnz RORci8loop
  1426.         ld c,a
  1427.         exx
  1428.         ld e,a ;overflow data
  1429.         exx
  1430.         ex af,af' ;'
  1431.         ret
  1432. ;For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result.
  1433. RCLci8
  1434. RCL_c_b
  1435.         ex af,af' ;' ;remember ZF,CF
  1436.         ld a,c
  1437. RCLci8loop
  1438.         rla
  1439.         djnz RCLci8loop
  1440.         ld c,a
  1441.         exx
  1442.         rra
  1443.         ld e,a ;overflow data
  1444.         rla ;restore CF
  1445.         exx
  1446.         ex af,af' ;'
  1447.         ret
  1448. ;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
  1449. RCRci8
  1450. RCR_c_b
  1451.         ex af,af' ;' ;remember ZF,CF
  1452.         ld a,c
  1453. RCRci8loop
  1454.         rra
  1455.         djnz RCRci8loop
  1456.         ld c,a
  1457.         exx
  1458.         ld e,a ;overflow data
  1459.         exx
  1460.         ex af,af' ;'
  1461.         ret
  1462. ;For left shifts, the OF flag is set to 0 if the most significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1.
  1463. SHLci8
  1464. SHL_c_b
  1465.         ld a,c
  1466. SHLr8i8loop
  1467.         add a,a
  1468.         djnz SHLr8i8loop
  1469.         ld c,a
  1470.         KEEPCFPARITYOVERFLOW_FROMA
  1471.         ret
  1472. ;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
  1473. SHRci8
  1474. SHR_c_b
  1475. SHRr8i8loop
  1476.         srl c
  1477.         djnz SHRr8i8loop
  1478.         ld a,c
  1479.         exx
  1480.         ld d,a ;parity data
  1481.         ld e,a ;overflow data
  1482.         exx
  1483.         ex af,af' ;'
  1484.         ret
  1485. ;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
  1486. SARci8
  1487. SAR_c_b
  1488. SARr8i8loop
  1489.         sra c
  1490.         djnz SARr8i8loop
  1491.         ld a,c
  1492.         exx
  1493.         ld d,a ;parity data
  1494.         ld e,a ;overflow data
  1495.         exx
  1496.         ex af,af' ;'
  1497.         ret
  1498.  
  1499.         ALIGNrm
  1500. GRP2rm81
  1501.         get
  1502.         next
  1503. ;a=MD000R/M: rol r/m
  1504. ;a=MD001R/M: ror r/m
  1505. ;a=MD010R/M: rcl r/m
  1506. ;a=MD011R/M: rcr r/m
  1507. ;a=MD100R/M: shl r/m
  1508. ;a=MD101R/M: shr r/m
  1509. ;a=MD110R/M: ??? r/m
  1510. ;a=MD111R/M: sar r/m
  1511.         cp 0b11000000
  1512.         jr c,GRP2rmmem81
  1513.        ADDRr8 ;rm addr
  1514.        rla
  1515.        rla
  1516.        rla
  1517.        jr c,GRP2rm81_1xx
  1518.        add a,a
  1519.        jp p,GRP2rm81_ROL_RCL ;0x0
  1520. ;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
  1521.        jr c,RCRr8
  1522. ;RORr8
  1523.         ex af,af' ;' ;remember ZF
  1524.         ld a,(hl)
  1525.         rrca
  1526.         ld (hl),a
  1527.         exx
  1528.         ld e,a ;overflow data
  1529.         exx
  1530.         ex af,af' ;'
  1531.        _Loop_
  1532. RCRr8
  1533.         ex af,af' ;' ;remember ZF,CF
  1534.         ld a,(hl)
  1535.         rra
  1536.         ld (hl),a
  1537.         exx
  1538.         ld e,a ;overflow data
  1539.         exx
  1540.         ex af,af' ;'
  1541.        _Loop_
  1542. GRP2rm81_ROL_RCL
  1543. ;For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result.
  1544.        jr c,RCLr8
  1545. ;ROLr8
  1546.         ex af,af' ;' ;remember ZF
  1547.         ld a,(hl)
  1548.         rlca
  1549.         ld (hl),a
  1550.         exx
  1551.         rra
  1552.         ld e,a ;overflow data
  1553.         rla ;restore CF
  1554.         exx
  1555.         ex af,af' ;'
  1556.        _Loop_
  1557. RCLr8
  1558.         ex af,af' ;' ;remember ZF,CF
  1559.         ld a,(hl)
  1560.         rla
  1561.         ld (hl),a
  1562.         exx
  1563.         rra
  1564.         ld e,a ;overflow data
  1565.         rla ;restore CF
  1566.         exx
  1567.         ex af,af' ;'
  1568.        _Loop_
  1569. GRP2rm81_1xx
  1570.        add a,a
  1571.        jp p,SHLr8
  1572.        jr c,SARr8
  1573. ;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
  1574.         srl (hl)
  1575.         ld a,(hl)
  1576.         exx
  1577.         ld d,a ;parity data
  1578.         ld e,a ;overflow data
  1579.         exx
  1580.         ex af,af' ;'
  1581.        _Loop_      
  1582. ;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
  1583. SARr8
  1584.         sra (hl)
  1585.         ld a,(hl)
  1586.         exx
  1587.         ld d,a ;parity data
  1588.         ld e,a ;overflow data
  1589.         exx
  1590.         ex af,af' ;'
  1591.        _Loop_
  1592. ;For left shifts, the OF flag is set to 0 if the most significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1.
  1593. SHLr8
  1594.         ld a,(hl)
  1595.         add a,a
  1596.         jp keephlflagsfroma_loop
  1597.         ;ld (hl),a
  1598.         ;KEEPCFPARITYOVERFLOW_FROMA
  1599.        ;_Loop_
  1600. GRP2rmmem81
  1601.        ADDRm16_GETm8c_for_PUTm8
  1602.        rla
  1603.        rla
  1604.        rla
  1605.        jr c,GRP2rmmem81_1xx
  1606.        add a,a
  1607.        jp p,GRP2rmmem81_ROL_RCL ;0x0
  1608. ;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
  1609.        jr c,RCRm8
  1610. ;RORm8
  1611.         ex af,af' ;' ;remember ZF
  1612.         ld a,c
  1613.         rrca
  1614.        ld c,a
  1615.         exx
  1616.         ld e,a ;overflow data
  1617.         exx
  1618.         ex af,af' ;'
  1619.        _PUTm8cLoopC_oldpglx
  1620. RCRm8
  1621.         ex af,af' ;' ;remember ZF,CF
  1622.         ld a,c
  1623.         rra
  1624.        ld c,a
  1625.         exx
  1626.         ld e,a ;overflow data
  1627.         exx
  1628.         ex af,af' ;'
  1629.        _PUTm8cLoopC_oldpglx
  1630. GRP2rmmem81_ROL_RCL
  1631. ;For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result.
  1632.        jr c,RCLm8
  1633. ;ROLm8
  1634.         ex af,af' ;' ;remember ZF
  1635.         ld a,c
  1636.         rlca
  1637.        ld c,a
  1638.         exx
  1639.         rra
  1640.         ld e,a ;overflow data
  1641.         rla ;restore CF
  1642.         exx
  1643.         ex af,af' ;'
  1644.        _PUTm8cLoopC_oldpglx
  1645. RCLm8
  1646.         ex af,af' ;' ;remember ZF,CF
  1647.         ld a,c
  1648.         rla
  1649.        ld c,a
  1650.         exx
  1651.         rra
  1652.         ld e,a ;overflow data
  1653.         rla ;restore CF
  1654.         exx
  1655.         ex af,af' ;'
  1656.        _PUTm8cLoopC_oldpglx
  1657. GRP2rmmem81_1xx
  1658.        add a,a
  1659.        jp p,SHLm8
  1660.        jr c,SARm8
  1661. ;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
  1662.         srl c
  1663.         ld a,c
  1664.         exx
  1665.         ld d,a ;parity data
  1666.         ld e,a ;overflow data
  1667.         exx
  1668.         ex af,af' ;'
  1669.        _PUTm8cLoopC_oldpglx
  1670. ;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
  1671. SARm8
  1672.         sra c
  1673.         ld a,c
  1674.         exx
  1675.         ld d,a ;parity data
  1676.         ld e,a ;overflow data
  1677.         exx
  1678.         ex af,af' ;'
  1679.        _PUTm8cLoopC_oldpglx
  1680. ;For left shifts, the OF flag is set to 0 if the most significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1.
  1681. SHLm8
  1682.         ld a,c
  1683.         add a,a
  1684.         ld c,a
  1685.         KEEPCFPARITYOVERFLOW_FROMA
  1686.        _PUTm8cLoopC_oldpglx
  1687.  
  1688.         ALIGNrm
  1689. GRP2rm161
  1690.         get
  1691.         next
  1692. ;a=MD000R/M: rol r/m
  1693. ;a=MD001R/M: ror r/m
  1694. ;a=MD010R/M: rcl r/m
  1695. ;a=MD011R/M: rcr r/m
  1696. ;a=MD100R/M: shl r/m
  1697. ;a=MD101R/M: shr r/m
  1698. ;a=MD110R/M: ??? r/m <-- shl
  1699. ;a=MD111R/M: sar r/m
  1700.         cp 0b11000000
  1701.         jp c,GRP2rmmem161
  1702.        ADDRr16_keepa
  1703.        rla
  1704.        rla
  1705.        rla
  1706.        jr c,GRP2rm161_1xx
  1707.        add a,a
  1708.        jp p,GRP2rm161_ROL_RCL ;0x0
  1709. ;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
  1710.        jr c,RCRr16
  1711. ;RORr16
  1712.         ex af,af' ;' ;remember ZF
  1713.         inc hl ;keep ZF
  1714.         ld a,(hl)
  1715.         ld b,a
  1716.         rra
  1717.         dec hl ;keep ZF
  1718.         ld a,(hl)
  1719.         rra
  1720.         ld c,a
  1721.         ld a,b
  1722.         rra ;use CF from C
  1723.         ld b,a
  1724.         exx
  1725.         ld e,a ;overflow data
  1726.         exx
  1727.         jr _ROLr16q
  1728. RCRr16
  1729.         ex af,af' ;' ;remember ZF,CF
  1730.         inc hl ;keep ZF
  1731.         ld a,(hl)
  1732.         rra
  1733.         ld b,a
  1734.         exx
  1735.         ld e,a ;overflow data
  1736.         exx
  1737.         dec hl ;keep ZF
  1738.         ld a,(hl)
  1739.         rra
  1740.         ld c,a
  1741.         jr _ROLr16q
  1742. GRP2rm161_ROL_RCL
  1743. ;For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result.
  1744.        jr c,RCLr16
  1745. ;ROLr16
  1746.         ex af,af' ;' ;remember ZF
  1747.         inc hl ;keep ZF
  1748.         ld a,(hl)
  1749.         ld b,a
  1750.         rla
  1751.         dec hl ;keep ZF
  1752.         ld a,(hl)
  1753.         rla
  1754.         ld c,a
  1755.         ld a,b
  1756.         jr RCLr16_go
  1757. RCLr16
  1758.         ex af,af' ;' ;remember ZF,CF
  1759.         ld a,(hl)
  1760.         rla
  1761.         ld c,a
  1762.         inc hl ;keep ZF
  1763.         ld a,(hl)
  1764.         dec hl ;keep ZF
  1765. RCLr16_go
  1766.         rla
  1767.         ld b,a
  1768.         exx
  1769.         rra
  1770.         ld e,a ;overflow data
  1771.         rla ;restore CF
  1772.         exx
  1773.         jr _ROLr16q
  1774. GRP2rm161_1xx
  1775.        add a,a
  1776.        jp p,SHLr16
  1777.         inc l
  1778.         ld b,(hl)
  1779.        jr c,SARr16
  1780. ;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
  1781. ;SHRr16
  1782.         srl b
  1783.         jr SARr16_go
  1784. ;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
  1785. SARr16
  1786.         sra b
  1787. SARr16_go
  1788.         dec l
  1789.         ld a,(hl)
  1790.         rra
  1791.         ld c,a
  1792. ;чтобы правильно сформировать ZF,SF по b,c:
  1793. ;если c!=0, то set 0,b
  1794.        add a,0xff
  1795.        sbc a,a ;CF=(c!=0)
  1796.        and d;1 ;any number 1..0x7f
  1797.        or b ;CF=0 ;ZF=(bc==0)
  1798.        ld a,(hl)
  1799.        rra ;CF
  1800.         ld a,b
  1801.         exx
  1802.         ld e,a ;overflow data
  1803.         exx
  1804. _ROLr16pfq
  1805.         ld a,c
  1806.         exx
  1807.         ld d,a ;parity data
  1808.         exx
  1809. _ROLr16q
  1810.         ex af,af' ;'
  1811.        _PUTr16Loop_
  1812. ;For left shifts, the OF flag is set to 0 if the most significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1.
  1813. SHLr16
  1814.         ld a,(hl)
  1815.         add a,a
  1816.         ld c,a
  1817.         inc l
  1818.         ld a,(hl)
  1819.         exx
  1820.         ld e,a ;overflow data
  1821.         exx
  1822.         rla
  1823.         ld b,a
  1824.         ld a,c
  1825. ;чтобы правильно сформировать ZF,SF по b,c:
  1826. ;если c!=0, то set 0,b
  1827.        add a,0xff
  1828.        sbc a,a ;CF=(c!=0)
  1829.        and d;1 ;any number 1..0x7f
  1830.        or b ;CF=0 ;ZF=(bc==0)
  1831.        ld a,(hl) ;oldb
  1832.        rla ;CF
  1833.        dec hl ;keep ZF
  1834.         jr _ROLr16pfq
  1835.  
  1836. GRP2rmmem161
  1837.         ADDRm16_GETm16_for_PUTm16
  1838.        push hl
  1839.        rla
  1840.        rla
  1841.        rla
  1842.        jr c,GRP2rmmem161_1xx
  1843.        add a,a
  1844.        jp p,GRP2rmmem161_ROL_RCL ;0x0
  1845. ;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
  1846.        jr c,RCRm16
  1847. ;RORm16
  1848.        ld a,c
  1849.        rra
  1850.        jr RCRm16_go
  1851. RCRm16
  1852.        ex af,af' ;'
  1853.        rla
  1854.        ld l,a ;l0=old CF, keep other flags
  1855.        ex af,af' ;'
  1856.        rr l ;restore CF
  1857. RCRm16_go
  1858.         rr b
  1859.         rr c
  1860.        rl l ;l0=new CF
  1861.        ex af,af' ;'
  1862. _ROLm16cfofq
  1863.        ld a,l
  1864.        rra ;new CF, keep other flags
  1865.         ld a,b
  1866.         exx
  1867.         ld e,a ;overflow data
  1868.         exx
  1869. _ROLm16q
  1870.        ex af,af' ;'
  1871.       pop hl
  1872.        _PUTm16LoopC
  1873. ;For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result.
  1874. GRP2rmmem161_ROL_RCL
  1875.        jr c,RCLm16
  1876. ;ROLm16
  1877.         ld a,b
  1878.         exx
  1879.         ld e,a ;overflow data
  1880.         exx
  1881.        rla
  1882.        jr RCLm16_go
  1883. ;For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result.
  1884. RCLm16
  1885.         ld a,b
  1886.         exx
  1887.         ld e,a ;overflow data
  1888.         exx
  1889.        ex af,af' ;'
  1890.        rla
  1891.        ld l,a ;l0=old CF, keep other flags
  1892.        ex af,af' ;'
  1893.        rr l ;restore CF
  1894. RCLm16_go
  1895.         rl c
  1896.         rl b
  1897.        rl l ;l0=new CF
  1898.        ex af,af' ;'
  1899.        ld a,l
  1900.        rra ;new CF, keep other flags
  1901.        jr _ROLm16q
  1902. GRP2rmmem161_1xx
  1903.        add a,a
  1904.        jp p,SHLm16
  1905.        ld l,c ;for generating CF
  1906.        jr c,SARm16
  1907. ;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
  1908. ;SHRm16
  1909.         srl b
  1910.         jr SARm16_go
  1911. ;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
  1912. SARm16
  1913.         sra b
  1914. SARm16_go
  1915.         rr c
  1916.         ld a,c
  1917. ;чтобы правильно сформировать ZF,SF по b,c:
  1918. ;если c!=0, то set 0,b
  1919.        add a,0xff
  1920.        sbc a,a ;CF=(c!=0)
  1921.        and d;1 ;any number 1..0x7f
  1922.        or b ;CF=0 ;ZF=(bc==0)
  1923.         ld a,c
  1924.         exx
  1925.         ld d,a ;parity data
  1926.         exx
  1927.         jr _ROLm16cfofq
  1928. ;For left shifts, the OF flag is set to 0 if the most significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1.
  1929. SHLm16
  1930.         ld a,h
  1931.         exx
  1932.         ld e,a ;overflow data
  1933.         exx
  1934.         or a
  1935.         adc hl,hl ;CF,ZF,SF
  1936.         ld a,l
  1937.         exx
  1938.         ld d,a ;parity data
  1939.         exx
  1940.         ex af,af' ;'
  1941. GRP2rmmem16i8q
  1942.        _PUTm16hlLoopC
  1943.  
  1944.         ALIGNrm
  1945. GRP2rm16cl
  1946.         get
  1947.         next
  1948. ;a=MD000R/M: rol r/m,cl
  1949. ;a=MD001R/M: ror r/m,cl
  1950. ;a=MD010R/M: rcl r/m,cl
  1951. ;a=MD011R/M: rcr r/m,cl
  1952. ;a=MD100R/M: shl r/m,cl
  1953. ;a=MD101R/M: shr r/m,cl
  1954. ;a=MD110R/M: ???
  1955. ;a=MD111R/M: sar r/m,cl
  1956.         cp 0b11000000
  1957.         jp c,GRP2rmmem16cl
  1958.        ADDRr16_keepa
  1959.        push hl
  1960.         ld (_GRP2rm16cl_hl),hl
  1961.        ld hl,GRP2r16i8q
  1962.        push hl
  1963. _GRP2rm16cl_hl=$+1
  1964.         ld hl,(0) ;ok
  1965.         jr GRP2rm16cl_go
  1966. GRP2rmmem16cl
  1967.         ADDRm16_GETm16_for_PUTm16
  1968.        push hl
  1969.        ld hl,GRP2rmmem16i8q
  1970.        push hl
  1971.         ld h,b
  1972.         ld l,c
  1973. GRP2rm16cl_go
  1974.         ld c,a ;op
  1975.         ld a,(_CL)
  1976.        if SHIFTCOUNTMASK
  1977.        and 0x1f
  1978.        else
  1979.        or a
  1980.        endif
  1981.         jr nz,GRP2rm16cl_no0
  1982.        pop hl ;skip
  1983.        pop hl ;skip
  1984.        _LoopC
  1985. GRP2rm16cl_no0
  1986.         ld b,a
  1987.         ld a,c
  1988.        rla
  1989.        rla
  1990.        rla
  1991.        jr c,GRP2rm16cl_1xx
  1992.        add a,a
  1993.        jr c,GRP2rm16cl_01x
  1994.        jp m,RORhl_b_to_hl
  1995.         jp ROLhl_b_to_hl
  1996. GRP2rm16cl_01x
  1997.        jp m,RCRhl_b_to_hl
  1998.         jp RCLhl_b_to_hl
  1999. GRP2rm16cl_1xx
  2000.        add a,a
  2001.        jp p,SHLhl_b_to_hl
  2002.        jp c,SARhl_b_to_hl
  2003.        jp SHRhl_b_to_hl
  2004.  
  2005.         ALIGNrm
  2006. GRP2rm8cl
  2007.         get
  2008.         next
  2009. ;a=MD000R/M: rol r/m,cl
  2010. ;a=MD001R/M: ror r/m,cl
  2011. ;a=MD010R/M: rcl r/m,cl
  2012. ;a=MD011R/M: rcr r/m,cl
  2013. ;a=MD100R/M: shl r/m,cl
  2014. ;a=MD101R/M: shr r/m,cl
  2015. ;a=MD110R/M: ???
  2016. ;a=MD111R/M: sar r/m,cl
  2017.         cp 0b11000000
  2018.         jr c,GRP2rmmem8cl
  2019.        ADDRr8
  2020.         ld c,(hl)
  2021.        push hl
  2022.        ld hl,GRP2r8i8q
  2023.         jr GRP2rmmem8cl_go
  2024. GRP2rmmem8cl
  2025.         ADDRm16_GETm8c_for_PUTm8
  2026.        push hl
  2027.        ld hl,GRP2rmmem8i8q
  2028. GRP2rmmem8cl_go      
  2029.        push af
  2030.         ld a,(_CL)
  2031.        if SHIFTCOUNTMASK
  2032.        and 31
  2033.        else
  2034.        or a
  2035.        endif
  2036.         jr nz,GRP2rmmem8cl_no0
  2037.        pop af ;skip
  2038.        pop hl ;skip
  2039.        _LoopC
  2040. GRP2rmmem8cl_no0
  2041.         ld b,a
  2042.        pop af
  2043.        ex (sp),hl ;keep return addr, hl=putaddr
  2044.        rla
  2045.        rla
  2046.        rla
  2047.        jr c,GRP2m8cl_1xx
  2048.        add a,a
  2049.        jr c,GRP2m8cl_01x
  2050.        jp m,ROR_c_b
  2051.         jp ROL_c_b
  2052. GRP2m8cl_01x
  2053.        jp m,RCR_c_b
  2054.         jp RCL_c_b
  2055. GRP2m8cl_1xx
  2056.        add a,a
  2057.        jp p,SHL_c_b
  2058.        jp c,SAR_c_b
  2059.         jp SHR_c_b
  2060.  
  2061.         ALIGNrm
  2062. GRP2rm16i8
  2063.         get
  2064.         next
  2065. ;a=MD000R/M: rol r/m,i8
  2066. ;a=MD001R/M: ror r/m,i8
  2067. ;a=MD010R/M: rcl r/m,i8
  2068. ;a=MD011R/M: rcr r/m,i8
  2069. ;a=MD100R/M: shl r/m,i8
  2070. ;a=MD101R/M: shr r/m,i8
  2071. ;a=MD110R/M: ??? <------- shl
  2072. ;a=MD111R/M: sar r/m,i8
  2073.         cp 0b11000000
  2074.         jr c,GRP2rmmem16i8
  2075.        ADDRr16_keepa
  2076.        push hl
  2077.         ld c,(hl)
  2078.         inc l
  2079.         ld b,(hl)
  2080.       ld hl,GRP2r16i8q
  2081.       jr GRP2rm16i8_go
  2082. GRP2rmmem16i8
  2083.         ADDRm16_GETm16_for_PUTm16
  2084.        push hl
  2085.       ld hl,GRP2rmmem16i8q
  2086. GRP2rm16i8_go
  2087.       push hl
  2088.         ld h,b
  2089.         ld l,c
  2090.        rla
  2091.        rla
  2092.        rla
  2093.        jp c,GRP2rmmem16i8_1xx
  2094.        add a,a
  2095.        jr c,GRP2rmmem16i8_01x
  2096.        jp m,RORhli8_to_hl ;TODO once
  2097. ;For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result.
  2098. ROLhli8_to_hl
  2099.         get
  2100.         next
  2101.         ld b,a
  2102. ROLhl_b_to_hl
  2103.         ex af,af' ;' ;remember ZF
  2104.         ld a,h
  2105. _ROLr16i8loop
  2106.         rla
  2107.         ld a,l
  2108.         rla
  2109.         ld l,a
  2110.         ld a,h
  2111.         rla
  2112.         ld h,a
  2113.        djnz _ROLr16i8loop
  2114.         exx
  2115.         rra
  2116.         ld e,a ;overflow data
  2117.         rla ;restore CF
  2118.         exx
  2119.         ex af,af' ;'
  2120.         ret
  2121. ;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
  2122. RORhli8_to_hl
  2123.         get
  2124.         next
  2125.         ld b,a
  2126. RORhl_b_to_hl
  2127.         ex af,af' ;' ;remember ZF
  2128.         ld a,l
  2129. _RORr16i8loop
  2130.         rra
  2131.         ld a,h
  2132.         rra
  2133.         ld h,a
  2134.         ld a,l
  2135.         rra
  2136.         ld l,a
  2137.        djnz _RORr16i8loop
  2138.         ld a,h
  2139.         exx
  2140.         ld e,a ;overflow data
  2141.         exx
  2142.         ex af,af' ;'
  2143.         ret
  2144.  
  2145. GRP2rmmem16i8_01x
  2146.        jp m,RCRhli8_to_hl
  2147. ;For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result.
  2148. RCLhli8_to_hl
  2149.         get
  2150.         next
  2151.         ld b,a
  2152. RCLhl_b_to_hl
  2153.         ex af,af' ;' ;remember ZF,CF
  2154. _RCLr16i8loop
  2155.         ld a,l
  2156.         rla
  2157.         ld l,a
  2158.         ld a,h
  2159.         rla
  2160.         ld h,a
  2161.        djnz _RCLr16i8loop
  2162.         exx
  2163.         rra
  2164.         ld e,a ;overflow data
  2165.         rla ;restore CF
  2166.         exx
  2167.         ex af,af' ;'
  2168.         ret
  2169. ;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
  2170. RCRhli8_to_hl
  2171.         get
  2172.         next
  2173.         ld b,a
  2174. RCRhl_b_to_hl
  2175.         ex af,af' ;' ;remember ZF,CF
  2176. _RCRr16i8loop
  2177.         ld a,h
  2178.         rra
  2179.         ld h,a
  2180.         ld a,l
  2181.         rra
  2182.         ld l,a
  2183.        djnz _RCRr16i8loop
  2184.         ld a,h
  2185.         exx
  2186.         ld e,a ;overflow data
  2187.         exx
  2188.         ex af,af' ;'
  2189.         ret
  2190.  
  2191. ;For left shifts, the OF flag is set to 0 if the most significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1.
  2192. SHLhli8_to_hl
  2193.         get
  2194.         next
  2195.         ld b,a
  2196. SHLhl_b_to_hl
  2197. _SHLr16i8loop
  2198.         or a
  2199.         adc hl,hl ;CF,ZF,SF
  2200.         djnz _SHLr16i8loop
  2201.         exx
  2202.         rra
  2203.         ld e,a ;overflow data
  2204.         rla ;restore CF
  2205.         exx
  2206.         ld a,l
  2207.         exx
  2208.         ld d,a ;parity data
  2209.         exx
  2210.         ex af,af' ;'
  2211.         ret
  2212.  
  2213. GRP2rmmem16i8_1xx
  2214.       add a,a
  2215.       jp p,SHLhli8_to_hl
  2216.        jr c,SARhli8_to_hl
  2217. ;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
  2218. SHRhli8_to_hl
  2219.         get
  2220.         next
  2221.         ld b,a
  2222. SHRhl_b_to_hl
  2223. _SHRr16i8loop
  2224.         srl h
  2225.         rr l
  2226.         djnz _SHRr16i8loop
  2227.      rra
  2228.      ld b,a ;keep CF
  2229.         ld a,l
  2230. ;чтобы правильно сформировать ZF,SF по h,l:
  2231. ;если l!=0, то set h!=0
  2232.        add a,0xff
  2233.        sbc a,a ;CF=(c!=0)
  2234.        and d;1 ;any number 1..0x7f
  2235.        or h ;CF=0 ;ZF=(bc==0)
  2236.      ld a,b
  2237.      rla ;CF
  2238.         ld a,h
  2239.         exx
  2240.         ld e,a ;overflow data
  2241.         exx
  2242.         ld a,l
  2243.         exx
  2244.         ld d,a ;parity data
  2245.         exx
  2246.         ex af,af' ;'
  2247.         ret
  2248. ;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
  2249. SARhli8_to_hl
  2250.         get
  2251.         next
  2252.         ld b,a
  2253. SARhl_b_to_hl
  2254. _SARr16i8loop
  2255.         sra h
  2256.         rr l
  2257.         djnz _SARr16i8loop
  2258.      rra
  2259.      ld b,a ;keep CF
  2260.         ld a,l
  2261. ;чтобы правильно сформировать ZF,SF по h,l:
  2262. ;если l!=0, то set h!=0
  2263.        add a,0xff
  2264.        sbc a,a ;CF=(c!=0)
  2265.        and d;1 ;any number 1..0x7f
  2266.        or h ;CF=0 ;ZF=(bc==0)
  2267.      ld a,b
  2268.      rla ;CF
  2269.         ld a,h
  2270.         exx
  2271.         ld e,a ;overflow data
  2272.         exx
  2273.         ld a,l
  2274.         exx
  2275.         ld d,a ;parity data
  2276.         exx
  2277.         ex af,af' ;'
  2278.         ret
  2279.  
  2280.        display "rolls size=",$-beginrolls
  2281. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2282. beginmuls
  2283.  
  2284. NOTr8 ;no flags
  2285.         ld a,(hl)
  2286.         cpl
  2287.         ld (hl),a
  2288.        _Loop_
  2289. NEGr8
  2290.         xor a
  2291.         sub (hl)
  2292.         ld (hl),a
  2293.         KEEPHFCFPARITYOVERFLOW_FROMA
  2294.        _Loop_
  2295.         ALIGNrm
  2296. GRP38
  2297.         get
  2298.         next
  2299. ;a=MD000R/M: test r/m8,i8 (не верится по формату)
  2300. ;a=MD001R/M: ?
  2301. ;a=MD010R/M: not r/m8
  2302. ;a=MD011R/M: neg r/m8
  2303. ;a=MD100R/M: mul ax,r/m8
  2304. ;a=MD101R/M: imul ax,r/m8
  2305. ;a=MD110R/M: div ax,r/m8
  2306. ;a=MD111R/M: idiv ax,r/m8
  2307.         cp 0b11000000
  2308.         jr c,GRP38mem
  2309.        ADDRr8
  2310.        and 0b00111000
  2311.         jr z,TESTr8i8
  2312.         cp 0b00010000
  2313.         jr z,NOTr8
  2314.         cp 0b00011000
  2315.         jr z,NEGr8
  2316.         cp 0b00100000
  2317.         jp z,MULr8 ;for fbird "mul ah"
  2318.         cp 0b00101000
  2319.         jp z,IMULr8 ;for rogue "imul ah"
  2320.         cp 0b00110000
  2321.         jp z,DIVr8 ;for invaders "div cl"
  2322.         ;cp 0b00111000
  2323.         ;jp z,IDIVr8
  2324.         jr $;PANIC
  2325. MULr8
  2326. ;mul ah: ax=al*ah
  2327.         ld c,(hl) ;reg
  2328. MULrmmem8
  2329.        push de
  2330.         ld b,0
  2331.         ld de,(_AX)
  2332.         ld d,b;0
  2333.         call MUL16 ;HLDE=DE*BC
  2334.        ;ld (_DX),hl ;надо ли?
  2335.         ld (_AX),de
  2336.        pop de
  2337.        _Loop_
  2338. IMULr8
  2339. ;imul ah: ax=+-al*+-ah?
  2340.         ld c,(hl) ;reg
  2341. IMULrmmem8
  2342.        push de
  2343.         ld a,c
  2344.         rla
  2345.         sbc a,a
  2346.         ld b,a
  2347.         ld a,(_AL)
  2348.         ld e,a
  2349.         rla
  2350.         sbc a,a
  2351.         ld d,a
  2352.         call MUL16SIGNED ;HLDE=DE*BC
  2353.        ;ld (_DX),hl ;надо ли?
  2354.         ld (_AX),de
  2355.        pop de
  2356.        _Loop_
  2357. DIVr8
  2358. ;DIV AL,r/m8
  2359. ;Беззнаковое деление AX на r/m8, частное помещается в AL, остаток от деления - в AH
  2360.         ld c,(hl) ;reg
  2361. DIVrmmem8
  2362.        push de
  2363.         ld e,c ;reg
  2364.         ld d,0
  2365.         ld bc,(_AX)
  2366.         ld hl,0
  2367.         call DIV32 ;BC = HLBC/DE, HL = HLBC%DE
  2368.         ld h,l ;остаток
  2369.         ld l,c ;частное
  2370.         ld (_AX),hl
  2371.        pop de
  2372.        _Loop_
  2373.  
  2374. TESTr8i8
  2375.         ld c,(hl)
  2376. TESTrmmemi8
  2377.         get
  2378.         next
  2379.         and c
  2380. ;The OF and CF flags are set to 0. The SF, ZF, and PF flags are set according to the result (see the "Operation" section above). The state of the AF flag is undefined.
  2381.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  2382.        _LoopC
  2383. GRP38mem
  2384.        ADDRm16_GETm8c_for_PUTm8
  2385.        and 0b00111000
  2386.         jr z,TESTrmmemi8
  2387.         cp 0b00010000
  2388.         jr z,NOTrmmem8
  2389.         cp 0b00011000
  2390.         jr z,NEGrmmem8
  2391.         cp 0b00100000
  2392.         jp z,MULrmmem8
  2393.         cp 0b00101000
  2394.         jp z,IMULrmmem8
  2395.         cp 0b00110000
  2396.         jp z,DIVrmmem8
  2397.         ;cp 0b00111000
  2398.         ;jp z,IDIVrmmem8
  2399.         jr $;PANIC
  2400. NOTrmmem8 ;no flags
  2401.         ld a,c
  2402.         cpl
  2403.         ld c,a
  2404.        _PUTm8cLoopC_oldpglx
  2405. NEGrmmem8
  2406.         xor a
  2407.         sub c
  2408.         ld c,a
  2409.         KEEPHFCFPARITYOVERFLOW_FROMA
  2410.        _PUTm8cLoopC_oldpglx
  2411.  
  2412.         ALIGNrm
  2413. GRP316
  2414.         get
  2415.         next
  2416. ;a=MD000R/M: test r/m,i16 (не верится по формату)
  2417. ;a=MD001R/M: ?
  2418. ;a=MD010R/M: not r/m
  2419. ;a=MD011R/M: neg r/m
  2420. ;a=MD100R/M: mul ax,r/m
  2421. ;a=MD101R/M: imul ax,r/m
  2422. ;a=MD110R/M: div ax,r/m
  2423. ;a=MD111R/M: idiv ax,r/m
  2424.         cp 0b11000000
  2425.         jr c,GRP316mem
  2426.        ADDRr16_keepa
  2427. ;TODO rla
  2428.        and 0b00111000
  2429.         jr z,TESTr16i16
  2430.         cp 0b00010000
  2431.         jp z,NOTr16
  2432.         cp 0b00011000
  2433.         jp z,NEGr16
  2434.         cp 0b00100000
  2435.         jp z,MULr16
  2436.         cp 0b00101000
  2437.         jp z,IMULr16
  2438.         cp 0b00110000
  2439.         jp z,DIVr16
  2440.         cp 0b00111000
  2441.         jp z,IDIVr16
  2442.         jr $;PANIC
  2443. TESTr16i16
  2444.         GETr16
  2445. TESTrmmemi16
  2446.         get
  2447.         and c
  2448.         ld c,a
  2449.         get
  2450.         and b
  2451.         ld b,a
  2452. ;The OF and CF flags are set to 0. The SF, ZF, and PF flags are set according to the result. The state of the AF flag is undefined.
  2453.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  2454.        _LoopC
  2455. GRP316mem
  2456.         ADDRm16_GETm16_for_PUTm16
  2457. ;TODO rla
  2458.        and 0b00111000
  2459.         jr z,TESTrmmemi16
  2460.         cp 0b00010000
  2461.         jp z,NOTrmmem16
  2462.         cp 0b00011000
  2463.         jp z,NEGrmmem16
  2464.         cp 0b00100000
  2465.         jp z,MULrmmem16
  2466.         cp 0b00101000
  2467.         jp z,IMULrmmem16
  2468.         cp 0b00110000
  2469.         jp z,DIVrmmem16
  2470.         cp 0b00111000
  2471.         jp z,IDIVrmmem16
  2472.         jr $;PANIC
  2473.  
  2474. ;The CF flag set to 0 if the source operand is 0; otherwise it is set to 1. The OF, SF, ZF, AF, and PF flags are set according to the result
  2475.         macro NEGBCWITHFLAGS
  2476.         xor a
  2477.         ld h,a
  2478.         ld l,a
  2479.         SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
  2480.         ld b,h
  2481.         ld c,l
  2482.         endm
  2483. NEGr16
  2484.        push hl
  2485.         GETr16
  2486.         NEGBCWITHFLAGS
  2487.        pop hl
  2488.        _PUTr16Loop_
  2489.  
  2490. NEGrmmem16
  2491.        push hl
  2492.         NEGBCWITHFLAGS
  2493.        pop hl
  2494.        _PUTm16LoopC
  2495.  
  2496. NOTr16
  2497.         ld a,(hl)
  2498.         cpl
  2499.         ld c,a
  2500.         inc l
  2501.         ld a,(hl)
  2502.         cpl
  2503.         dec l
  2504.         ld b,a ;no flags
  2505.        _PUTr16Loop_
  2506.  
  2507. NOTrmmem16
  2508.         ld a,c
  2509.         cpl
  2510.         ld c,a
  2511.         ld a,b
  2512.         cpl
  2513.         ld b,a ;no flags
  2514.        _PUTm16LoopC
  2515.  
  2516. ;mul cx ;ax*cx -> dxax (set OF,CF if result >=65536)
  2517. MULr16
  2518.         GETr16
  2519. MULrmmem16
  2520.        push de
  2521.         ld de,(_AX);ex de,hl ;de=ax
  2522.         call MUL16 ;HLDE=DE*BC
  2523.         ld (_DX),hl
  2524.         ld (_AX),de
  2525.         ld a,h
  2526.         or l ;0?
  2527.         add a,255 ;set CF if result >=65536
  2528.         sbc a,a ;keep CF
  2529.         srl a ;keep CF
  2530.         exx
  2531.         ld e,a ;overflow (d7 != d6) if CF
  2532.         exx
  2533.         ex af,af' ;'
  2534.        pop de
  2535.        _Loop_
  2536.  
  2537. ;imul cx ;ax*cx -> dxax signed (set OF,CF if result >=32768 or < -32768)
  2538. IMULr16
  2539.         GETr16
  2540. IMULrmmem16
  2541.        push de
  2542.         ld de,(_AX);ex de,hl ;de=ax
  2543.         call IMUL_bc_de_to_hlde
  2544.         ld (_DX),hl ;HSW
  2545.         ld (_AX),de ;LSW
  2546.        pop de
  2547.        _Loop_
  2548.  
  2549. ;div cx ;dxax/cx -> ax частное, dx остаток
  2550. DIVr16
  2551.         GETr16
  2552. DIVrmmem16
  2553.        push de
  2554.         ld d,b
  2555.         ld e,c
  2556.         ld bc,(_AX)
  2557.         ld hl,(_DX)
  2558.         call DIV32 ;BC = HLBC/DE, HL = HLBC%DE
  2559.         ld (_DX),hl
  2560.         ld (_AX),bc
  2561.        pop de
  2562.        _Loop_
  2563.  
  2564. ;idiv cx ;dxax/cx -> ax частное, dx остаток signed (знак остатка равен знаку делимого)
  2565. IDIVr16
  2566.         GETr16
  2567. IDIVrmmem16
  2568.        push de
  2569.         ld d,b
  2570.         ld e,c
  2571.         ld bc,(_AX)
  2572.         ld hl,(_DX)
  2573.         call DIV32SIGNED ;BC = HLBC/DE, HL = HLBC%DE
  2574.         ld (_DX),hl
  2575.         ld (_AX),bc
  2576.        pop de
  2577.        _Loop_
  2578.  
  2579.         ALIGNrm
  2580. TESTrmr8
  2581.         get
  2582.         next
  2583.         cp 0b11000000
  2584.         jr c,TESTrmmemr8
  2585.         ld l,a
  2586.         ld h,_AX/256
  2587.         ld l,(hl) ;reg8 addr
  2588.         ld c,(hl)
  2589.        sub 64
  2590.         ld l,a
  2591.         ld l,(hl) ;rm addr
  2592.         ld a,(hl)
  2593.         and c ;op
  2594.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  2595.        _Loop_
  2596. TESTrmmemr8
  2597.        ADDRm16_GETm8b_keepaf
  2598.        or 0b11000000
  2599.         ld l,a
  2600.         ld h,_AX/256
  2601.         ld l,(hl) ;reg8 addr
  2602.        ld a,b
  2603.         and (hl) ;op
  2604.         KEEPLOGICCFPARITYOVERFLOW_FROMA
  2605.        _LoopC
  2606.  
  2607.         ALIGNrm
  2608. TESTrmr16
  2609.         get
  2610.         next
  2611.         cp 0b11000000
  2612.         jr c,TESTrmmemr16
  2613.        ld h,a
  2614.         rra
  2615.         rra
  2616.         and 7*2
  2617.         ld l,a ;reg16 addr
  2618.        ld a,h
  2619.         ld h,_AX/256
  2620.         ld c,(hl)
  2621.         inc l
  2622.         ld b,(hl) ;reg16
  2623.         and 7
  2624.         add a,a
  2625.         ld l,a ;rm addr
  2626.         ld a,(hl)
  2627.         and c
  2628.         ld c,a
  2629.         inc l
  2630.         ld a,(hl)
  2631.         and b ;op
  2632.         ld b,a
  2633.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  2634.        _Loop_
  2635. TESTrmmemr16
  2636.        ADDRm16_GETm16 ;bc=rmmem
  2637.         rra
  2638.         rra
  2639.         and 7*2
  2640.         ld l,a ;reg16 addr
  2641.         ld h,_AX/256
  2642.         ld a,(hl)
  2643.         and c
  2644.         ld c,a
  2645.         inc l
  2646.         ld a,(hl)
  2647.         and b ;op
  2648.         ld b,a
  2649.         KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
  2650.        _LoopC
  2651.  
  2652.         ALIGNrm
  2653. GRP48
  2654. ;a=MD000R/M: inc r/m8
  2655. ;a=MD001R/M: dec r/m8
  2656.         get
  2657.         next
  2658.        cp 0b11000000
  2659.        jr c,GRP48mem
  2660.        ADDRr8
  2661.        and 0b00111000
  2662.         jr z,INCr8
  2663.         cp 0b00001000
  2664.         jp z,DECr8
  2665.         jr $;PANIC
  2666. GRP48mem
  2667.        ADDRm16_GETm8c_for_PUTm8
  2668.        and 0b00111000
  2669.         jr z,INCrmmem8
  2670.         cp 0b00001000
  2671.         jp z,DECrmmem8
  2672.         jr $;PANIC
  2673.  
  2674. INCr8
  2675.         ex af,af' ;' ;remember CY (keep)
  2676.         ld a,(hl)
  2677.         inc a
  2678.         ld (hl),a
  2679.         KEEPHFCFPARITYOVERFLOW_FROMA
  2680.        _Loop_
  2681. DECr8
  2682.         ex af,af' ;' ;remember CY (keep)
  2683.         ld a,(hl)
  2684.         dec a
  2685.         ld (hl),a
  2686.         KEEPHFCFPARITYOVERFLOW_FROMA
  2687.        _Loop_
  2688.  
  2689. INCrmmem8
  2690.         ex af,af' ;' ;remember CY (keep)
  2691.         inc c
  2692.         ld a,c
  2693.         KEEPHFCFPARITYOVERFLOW_FROMA
  2694.        _PUTm8cLoopC_oldpglx
  2695. DECrmmem8
  2696.         ex af,af' ;' ;remember CY (keep)
  2697.         dec c
  2698.         ld a,c
  2699.         KEEPHFCFPARITYOVERFLOW_FROMA
  2700.        _PUTm8cLoopC_oldpglx
  2701.  
  2702. JMPr16
  2703.         GETr16_de
  2704.         jp JMPr16q
  2705. DECr16
  2706.        push hl
  2707.         GETr16
  2708.         decbcwithflags
  2709.         jr _pophl_PUTr16Loop_
  2710.        ;pop hl
  2711.        ;_PUTr16Loop_
  2712.         ALIGNrm
  2713. GRP416
  2714. ;a=MD000R/M: inc r/m16
  2715. ;a=MD001R/M: dec r/m16
  2716. ;a=MD010R/M: call r/m16
  2717. ;a=MD011R/M: callf m16:16 ;первым идет WORD для IP, потом для CS ;push cs; push ip
  2718. ;a=MD100R/M: jmp r/m16
  2719. ;a=MD101R/M: jmpf m16:16 ;первым идет WORD для IP, потом для CS ;push cs; push ip
  2720. ;a=MD110R/M: push r/m16
  2721. ;a=MD111R/M: ?
  2722.         get
  2723.         next
  2724.        cp 0b11000000
  2725.        jr c,GRP416mem
  2726.        ADDRr16_keepa
  2727.        and 0b00111000
  2728.         jr z,INCr16
  2729.         cp 0b00001000
  2730.         jr z,DECr16
  2731.         cp 0b00010000
  2732.         jr z,CALLr16
  2733.         ;cp 0b00011000
  2734.         ;jp z,CALLFm1616
  2735.         cp 0b00100000
  2736.         ;jr z,JMPr16
  2737.         ;cp 0b00101000
  2738.         ;jp z,JMPFm1616
  2739.         ;cp 0b00110000
  2740.         ;jp z,PUSHr16
  2741.         jr nz,$;PANIC
  2742. INCr16
  2743.        push hl
  2744.         GETr16
  2745.         incbcwithflags
  2746. _pophl_PUTr16Loop_
  2747.        pop hl
  2748.        _PUTr16Loop_
  2749. CALLr16
  2750.         GETr16_hl
  2751.        decodePC
  2752.         ex de,hl ;new IP(PC)
  2753.         ld b,h
  2754.         ld c,l ;=old IP(PC)
  2755.         putmemspBC
  2756. JMPr16q
  2757.        _LoopJP
  2758.  
  2759. GRP416mem
  2760.         ADDRm16_GETm16_for_PUTm16
  2761.        and 0b00111000
  2762.         jr z,INCrmmem16
  2763.         cp 0b00001000
  2764.         jr z,DECrmmem16
  2765.         cp 0b00010000
  2766.         jp z,CALLrmmem16
  2767.         cp 0b00011000
  2768.         jp z,CALLFm1616mem ;высчитывается эффективный адрес, и с этого адреса берутся 4 байта (ip:cs)
  2769.         cp 0b00100000
  2770.         jr z,JMPrmmem16
  2771.         cp 0b00101000
  2772.         jr z,JMPFm1616mem ;высчитывается эффективный адрес, и с этого адреса берутся 4 байта (ip:cs)
  2773.         cp 0b00110000
  2774.         ;jr z,PUSHrmmem16
  2775.         jr nz,$;PANIC
  2776. PUSHrmmem16
  2777.         putmemspBC
  2778.        _LoopC
  2779.  
  2780. INCrmmem16
  2781.        push hl
  2782.         incbcwithflags
  2783. _pophl_PUTm16LoopC
  2784.        pop hl
  2785.        _PUTm16LoopC
  2786. DECrmmem16
  2787.        push hl
  2788.         decbcwithflags
  2789.        jr _pophl_PUTm16LoopC
  2790.  
  2791. JMPrmmem16
  2792.         ld d,b
  2793.         ld e,c
  2794.        _LoopC_JP
  2795. JMPFm1616mem ;высчитывается эффективный адрес, и с этого адреса берутся 4 байта (ip:cs)
  2796. ;уже прочитано 2 байта bc из (hl), но hl не сдвинут
  2797.        push de ;new IP(PC)
  2798.         skip2b_GETm16 ;bc=new CS
  2799.        ld (_CS),bc ;new CS
  2800.        countCS
  2801.        pop de ;new IP(PC)
  2802.        _LoopJP
  2803.  
  2804. CALLrmmem16
  2805.         ld h,b
  2806.         ld l,c
  2807. _CALLrmmem16q
  2808.        decodePC
  2809.         ex de,hl ;new IP(PC)
  2810.         ld b,h
  2811.         ld c,l ;=old IP(PC)
  2812.         putmemspBC
  2813.        _LoopC_JP
  2814. CALLFm1616mem ;высчитывается эффективный адрес, и с этого адреса берутся 4 байта (ip:cs)
  2815. ;уже прочитано 2 байта bc из (hl), но hl не сдвинут
  2816.        push bc ;new IP(PC)
  2817.         skip2b_GETm16 ;bc=new CS
  2818.        push bc
  2819. ;push cs; push ip (адрес после команды)
  2820.         ld bc,(_CS) ;old CS
  2821.         putmemspBC
  2822.        pop bc
  2823.        ld (_CS),bc ;new CS
  2824.        countCS
  2825.        pop hl ;new IP(PC)
  2826.         jp _CALLrmmem16q
  2827.  
  2828.         ALIGNrm
  2829. IMULr16rmi8
  2830.         get
  2831.         next
  2832. ;a=MDregR/M
  2833. ;MD=00: imul reg16,[...],i8
  2834. ;MD=01: imul reg16,[...+disp8],i8
  2835. ;MD=10: imul reg16,[...+disp16],i8
  2836. ;MD=11: imul reg16,r/m,i8 ;проще всего
  2837.        push af
  2838.         cp 0b11000000
  2839.         jp c,IMULr16rmmemi8
  2840.         ADDRr16_nokeepa
  2841.         GETr16 ;bc=r/m
  2842.         jr _IMULr16rmmem_geti8
  2843. IMULr16rmmemi8
  2844.        ADDRm16_GETm16 ;bc=rmmem
  2845. _IMULr16rmmem_geti8
  2846.         get
  2847.         next
  2848.        push de
  2849.         ld e,a
  2850.         rla
  2851.         sbc a,a
  2852.         ld d,a
  2853.         jr _IMULr16rmmem_go
  2854.  
  2855.         ALIGNrm
  2856. IMULr16rmi16
  2857.         get
  2858.         next
  2859. ;a=MDregR/M
  2860. ;MD=00: imul r16,[...],i16
  2861. ;MD=01: imul r16,[...+disp8],i16
  2862. ;MD=10: imul r16,[...+disp16],i16
  2863. ;MD=11: imul r16,r/m,i16 ;проще всего
  2864.        push af
  2865.         cp 0b11000000
  2866.         jp c,IMULr16rmmemi16
  2867.         ADDRr16_nokeepa
  2868.         GETr16 ;bc=r/m
  2869.         jr _IMULr16rmmem_geti16
  2870. IMULr16rmmemi16
  2871.        ADDRm16_GETm16 ;bc=rmmem
  2872. _IMULr16rmmem_geti16
  2873.         getHL
  2874.        push de
  2875.         ex de,hl
  2876. _IMULr16rmmem_go
  2877.         call IMUL_bc_de_to_hlde
  2878.         ld b,d
  2879.         ld c,e
  2880.        pop de
  2881.        pop af
  2882.         rra
  2883.         rra
  2884.         and 7*2
  2885.         ld l,a ;reg16 addr
  2886.         ld h,_AX/256
  2887.        _PUTr16LoopC ;TODO без ld a,l
  2888.  
  2889.         ALIGNrm
  2890. XCHGr16rm
  2891.         get
  2892.         next
  2893. ;a=MDregR/M
  2894. ;MD=00: xchg reg16,[...]
  2895. ;MD=01: xchg reg16,[...+disp8]
  2896. ;MD=10: xchg reg16,[...+disp16]
  2897. ;MD=11: xchg reg16,r/m ;проще всего
  2898.         cp 0b11000000
  2899.         jr c,XCHGr16rmmem
  2900.         ADDRr16_keepa ;rm addr
  2901.       push hl
  2902.         GETr16 ;bc=r/m
  2903.         rra
  2904.         rra
  2905.         and 7*2
  2906.         ld l,a ;reg16 addr
  2907.         ld h,_AX/256
  2908.         SWAPr16
  2909.         jp _pophl_PUTr16Loop_
  2910. XCHGr16rmmem
  2911.         ADDRm16_GETm16_for_PUTm16
  2912.       push hl
  2913.         rra
  2914.         rra
  2915.         and 7*2
  2916.         ld l,a ;reg16 addr
  2917.         ld h,_AX/256
  2918.         SWAPr16
  2919.         jp _pophl_PUTm16LoopC
  2920.  
  2921. XCHGr8rm
  2922.         get
  2923.         next
  2924. ;a=MDregR/M
  2925. ;MD=00: xchg reg8,[...]
  2926. ;MD=01: xchg reg8,[...+disp8]
  2927. ;MD=10: xchg reg8,[...+disp16]
  2928. ;MD=11: xchg reg8,r/m ;проще всего
  2929.         cp 0b11000000
  2930.         jr c,XCHGr8rmmem
  2931.         ADDRr8 ;rm addr
  2932.         ld b,(hl) ;b=r/m
  2933.       push hl
  2934.        or 0b11000000
  2935.         ld l,a
  2936.         ld h,_AX/256
  2937.         ld l,(hl) ;reg8 addr
  2938.         ld a,(hl)
  2939.         ld (hl),b
  2940.        pop hl
  2941.        _PUTr8Loop_
  2942. XCHGr8rmmem
  2943.        ADDRm16_GETm8c_for_PUTm8
  2944.       push hl
  2945.        or 0b11000000
  2946.         ld l,a
  2947.         ld h,_AX/256
  2948.         ld l,(hl) ;reg8 addr
  2949.         ld a,(hl)
  2950.         ld (hl),c
  2951.        pop hl
  2952.        _PUTm8aLoopC_oldpglx
  2953.  
  2954.        display "muls size=",$-beginmuls
  2955.