?login_element?

Subversion Repositories NedoOS

Rev

Rev 1291 | Blame | Compare with Previous | Last modification | View Log | Download

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