beginmovs
ALIGNrm
MOVrm8i8
get
next
;a=MD000R/M: mov r/m,i8
;MD=00: mov [...],i8
;MD=01: mov [...+disp8],i8
;MD=10: mov [...+disp16],i8
;MD=11: mov r/m,i8 ;проще всего, но не имеет смысла (есть короткий код)
cp 0b11000000
;jr c,MOVrmmemi8
jr nc,MOVr8i8
;MOVrmmemi8
;UNTESTED
ADDRm16_for_PUTm8a_nokeepaf
get
next
_PUTm8aLoopC_oldpglx
MOVr8i8
UNTESTED
sub 64
ld l,a
ld h,_AX/256
ld l,(hl) ;rm addr
get
next
ld (hl),a
_Loop_
ALIGNrm
MOVrm16i16
get
next
;a=MD000R/M: mov r/m,i16
;MD=00: mov [...],i16
;MD=01: mov [...+disp8],i16
;MD=10: mov [...+disp16],i16
;MD=11: mov r/m,i16 ;проще всего, но не имеет смысла (есть короткий код)
cp 0b11000000
;jr c,MOVrmmemi16
jr nc,MOVr16i16
;MOVrmmemi16
;UNTESTED
ADDRm16_for_PUTm16_nokeepaf
getBC
_PUTm16LoopC
MOVr16i16
UNTESTED
ADDRr16_nokeepa ;rm addr
getBC
_PUTr16Loop_
ALIGNrm
MOVrmr8
get
next
;a=MDregR/M
;MD=00: mov [...],reg8
;MD=01: mov [...+disp8],reg8
;MD=10: mov [...+disp16],reg8
;MD=11: mov r/m,reg8 ;проще всего
cp 0b11000000
jr c,MOVrmmemr8
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld c,(hl)
sub 64
ld l,a
ld l,(hl) ;rm addr
ld (hl),c
_Loop_
MOVrmmemr8
push af
ADDRm16_for_PUTm8a_nokeepaf
pop af
or 0b11000000
ld c,a
ld b,_AX/256
ld a,(bc) ;reg8 addr
ld c,a
ld a,(bc)
_PUTm8aLoopC_oldpglx
ALIGNrm
MOVrmr16
get
next
;a=MDregR/M
;MD=00: mov [...],reg16
;MD=01: mov [...+disp8],reg16
;MD=10: mov [...+disp16],reg16
;MD=11: mov r/m,reg16 ;проще всего
cp 0b11000000
jr c,MOVrmmemr16
ld h,a
rra
rra
and 7*2
ld l,a
ld a,h
ld h,_AX/256
ld c,(hl)
inc l
ld b,(hl) ;reg16
and 7
add a,a
ld l,a ;rm addr
_PUTr16Loop_
MOVrmmemr16
ADDRm16_for_PUTm16
push hl
rra
rra
and 7*2
ld l,a
ld h,_AX/256
ld c,(hl)
inc l
ld b,(hl) ;reg16
pophl_PUTm16LoopC
pop hl
_PUTm16LoopC
ALIGNrm
POPrm16
UNTESTED
get
next
cp 0b11000000
jr nc,$ ;not mem ;datatrnf c1: pop %cx (non-standard)
ADDRm16_for_PUTm16_nokeepaf
push hl
getmemspBC
; pop hl
;_PUTm16LoopC
jr pophl_PUTm16LoopC
ALIGNrm
MOVr8rm
get
next
;a=MDregR/M
;MD=00: mov reg8,[...]
;MD=01: mov reg8,[...+disp8]
;MD=10: mov reg8,[...+disp16]
;MD=11: mov reg8,r/m ;проще всего
cp 0b11000000
jp c,MOVr8rmmem
ADDRr8 ;rm addr
ld c,(hl)
ld l,a
ld l,(hl) ;reg8 addr
ld (hl),c
_Loop_
MOVr8rmmem
ADDRm16_GETm8b_keepaf
or 0b11000000
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld (hl),b
_LoopC
ALIGNrm
MOVr16rm
get
next
;a=MDregR/M
;MD=00: mov reg16,[...]
;MD=01: mov reg16,[...+disp8]
;MD=10: mov reg16,[...+disp16]
;MD=11: mov reg16,r/m ;проще всего
cp 0b11000000
jr c,MOVr16rmmem
ADDRr16_keepa
ld c,(hl)
inc l
ld b,(hl) ;rm
rra
rra
and 7*2
ld l,a ;reg16 addr
_PUTr16Loop_
MOVr16rmmem
ADDRm16_GETm16 ;bc=rmmem
rra
rra
and 7*2
ld l,a ;reg16 addr
ld h,_AX/256
_PUTr16LoopC_AisL
ALIGNrm
MOVsregrm16
;UNTESTED
get
next
;a=MDregR/M
;MD=00: mov sreg,[...]
;MD=01: mov sreg,[...+disp8]
;MD=10: mov sreg,[...+disp16]
;MD=11: mov sreg,r/m ;проще всего
cp 0b11000000
jr c,MOVsregrmmem
ADDRr16_keepa
ld c,(hl)
inc l
ld b,(hl) ;rm
jr MOVsregrmq
MOVsregrmmem
ADDRm16_GETm16 ;bc=rmmem
ld h,_AX/256
MOVsregrmq
rra
rra
and 7*2
add a,_ES&0xff
ld l,a
ld (hl),c
inc l
ld (hl),b
;count?S
xor a
sla c
rl b
rla
sla c
rl b
rla
sla c
rl b
rla
sla c
rl b
rla
set 5,l ;0x11 -> 0x31
ld (hl),b
dec l
ld (hl),c
res 4,l
ld (hl),a
_LoopC
ALIGNrm
MOVrm16sreg
;UNTESTED
get
next
;a=MDregR/M
;MD=00: mov [...],sreg16
;MD=01: mov [...+disp8],sreg16
;MD=10: mov [...+disp16],sreg16
;MD=11: mov r/m,sreg16 ;проще всего
cp 0b11000000
jr c,MOVrmmemsreg
ld h,a
rra
rra
and 7*2
add a,_ES&0xff
ld l,a ;sreg16 addr
ld a,h
ld h,_ES/256
ld c,(hl)
inc l
ld b,(hl)
and 7
add a,a
ld l,a ;rm addr
_PUTr16Loop_
MOVrmmemsreg
ADDRm16_for_PUTm16
push hl
rra
rra
and 7*2
add a,_ES&0xff ;единственное отличие от MOVrmmemr16
ld l,a ;sreg16 addr
ld h,_ES/256
ld c,(hl)
inc l
ld b,(hl)
pop hl
_PUTm16LoopC
display "movs size=",$-beginmovs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
beginalus
ALIGNrm
GRP1rmi8
get
next
;a=MD000R/M: add r/m,i8
;a=MD001R/M: or r/m,i8
;a=MD010R/M: adc r/m,i8
;a=MD011R/M: sbb r/m,i8
;a=MD100R/M: and r/m,i8
;a=MD101R/M: sub r/m,i8
;a=MD110R/M: xor r/m,i8
;a=MD111R/M: cmp r/m,i8
cp 0b11000000
jr c,GRP1rmmemi8
ADDRr8
rla
rla
rla
jr c,GRP1rmi8_1xx
add a,a
jp p,GRP1rmi8_ADD_ADC
jr c,SBBrmi8
get
or (hl)
jr GRP1rmi8logicstoreq
SBBrmi8
ex af,af' ;' ;old CF for sbb
get
SUBrmi8
ld c,a
ld a,(hl)
sbc a,c
jr GRP1rmi8storeq
GRP1rmi8_ADD_ADC
jr nc,ADDrmi8 ;CF=0 for add
ex af,af' ;' ;old CF for adc
ADDrmi8
get
adc a,(hl)
GRP1rmi8storeq
ld (hl),a
GRP1rmi8q
KEEPHFCFPARITYOVERFLOW_FROMA
next ;doesn't keep SF
_LoopC
GRP1rmi8_1xx
add a,a
get
jp p,GRP1rmi8_AND_XOR
jr nc,SUBrmi8 ;CF=0 for sub
;CMPrmi8
ld c,a
ld a,(hl)
sub c
jr GRP1rmi8q
GRP1rmi8_AND_XOR
jr c,XORrmi8
and (hl)
GRP1rmi8logicstoreq
ld (hl),a
KEEPLOGICCFPARITYOVERFLOW_FROMA
next ;doesn't keep SF
_LoopC
XORrmi8
xor (hl)
jr GRP1rmi8logicstoreq
GRP1rmmemi8
ADDRm16_GETm8c_for_PUTm8
rla
rla
rla
jr c,GRP1rmmemi8_1xx
add a,a
jp p,GRP1rmmemi8_ADD_ADC
jr c,SBBrmmemi8
get
or c
jr GRP1rmmemi8logicstoreq
SBBrmmemi8
ex af,af' ;' ;old CF for sbb
get
SUBrmmemi8
ld b,a
ld a,c ;rmmem
sbc a,b
jr GRP1rmmemi8storeq
GRP1rmmemi8_ADD_ADC
jr nc,ADDrmmemi8 ;CF=0 for add
ex af,af' ;' ;old CF for adc
ADDrmmemi8
get
adc a,c
GRP1rmmemi8storeq
ld c,a
KEEPHFCFPARITYOVERFLOW_FROMA
next ;doesn't keep SF
_PUTm8cLoopC_oldpglx
GRP1rmmemi8_1xx
add a,a
get
jp p,GRP1rmmemi8_AND_XOR
jr nc,SUBrmmemi8 ;CF=0 for sub
;CMPrmmemi8
ld b,a
ld a,c
sub b
KEEPHFCFPARITYOVERFLOW_FROMA
next ;doesn't keep SF
_LoopC
GRP1rmmemi8_AND_XOR
jr c,XORrmmemi8
and c
GRP1rmmemi8logicstoreq
ld c,a
KEEPLOGICCFPARITYOVERFLOW_FROMA
next ;doesn't keep SF
_PUTm8cLoopC_oldpglx
XORrmmemi8
xor c
jr GRP1rmmemi8logicstoreq
GRP1rmi16_ADD_ADC
jr nc,ADDr16i16 ;CF=0 for add
ex af,af' ;' ;old CF for adc
ADDr16i16
get
next
ld c,a
get
ld b,a
ADCr16bc
ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
GRP1rmi16q
next
GRP2r16i8q
_PUTr16hlLoop_
ALIGNrm
GRP1rmi16
get
next
;a=MD000R/M: add r/m,i16
;a=MD001R/M: or r/m,i16
;a=MD010R/M: adc r/m,i16
;a=MD011R/M: sbb r/m,i16
;a=MD100R/M: and r/m,i16
;a=MD101R/M: sub r/m,i16
;a=MD110R/M: xor r/m,i16
;a=MD111R/M: cmp r/m,i16
cp 0b11000000
jp c,GRP1rmmemi16
ADDRr16_keepa
push hl
GETr16_hl
rla
rla
rla
jr c,GRP1rmi16_1xx
add a,a
jp p,GRP1rmi16_ADD_ADC
jr c,SBBr16i16
;ORr16i16
get
next
or l
ld l,a
get
or h
jp GRP1rmi16logicq
SBBr16i16
ex af,af' ;' ;old CF for sbb
get
SUBr16i16
next
ld c,a
get
ld b,a
SBCr16bc
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
jp GRP1rmi16q
GRP1rmi16_1xx
add a,a
get
jp p,GRP1rmi16_AND_XOR
jr nc,SUBr16i16 ;CF=0 for sub
CMPr16i16
next
ld c,a
get
CMPr16hlac
ld b,a
or a
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
pop hl ;skip
next
_LoopC
GRP1rmi16_AND_XOR
next
jr c,XORr16i16
;ANDr16i16
and l
ld l,a
get
and h
GRP1rmi16logicq
ld h,a
KEEPLOGICCFPARITYOVERFLOW_FROMHL_AisH
next
_PUTr16hlLoop_
XORr16i16
xor l
ld l,a
get
xor h
jr GRP1rmi16logicq
GRP1rmmemi16_ADD_ADC
jr nc,ADDrmmemi16 ;CF=0 for add
ex af,af' ;' ;old CF for adc
ADDrmmemi16
get
next
ld c,a
get
ld b,a
ADCrmmem16bc
ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
GRP1rmmemi16q
next
_PUTm16hlLoopC
GRP1rmmemi16
ADDRm16_GETm16_for_PUTm16
push hl
ld h,b
ld l,c
rla
rla
rla
jr c,GRP1rmmemi16_1xx
add a,a
jp p,GRP1rmmemi16_ADD_ADC
jr c,SBBrmmemi16
;ORrmmemi16
get
next
or l
ld l,a
get
or h
jr GRP1rmmemi16logicq
SBBrmmemi16
ex af,af' ;' ;old CF for sbb
get
SUBrmmemi16
next
ld c,a
get
ld b,a
SBBrmmem16bc
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
jp GRP1rmmemi16q
GRP1rmmemi16_1xx
add a,a
get
jp p,GRP1rmmemi16_AND_XOR
jr nc,SUBrmmemi16
jp CMPr16i16
GRP1rmmemi16_AND_XOR
next
jr c,XORrmmemi16
;ANDrmmemi16
and l
ld l,a
get
and h
GRP1rmmemi16logicq
ld h,a
KEEPLOGICCFPARITYOVERFLOW_FROMHL_AisH
next
_PUTm16hlLoopC
XORrmmemi16
xor l
ld l,a
get
xor h
jr GRP1rmmemi16logicq
ALIGNrm
GRP1rm16i8 ;операнд расширяется со знаком (проверено)
get
next
;a=MD000R/M: add r/m,i8
;a=MD010R/M: adc r/m,i8
;a=MD011R/M: sbb r/m,i8
;a=MD101R/M: sub r/m,i8
;a=MD111R/M: cmp r/m,i8
cp 0b11000000
jr c,GRP1rmmem16i8
ADDRr16_keepa
push hl
GETr16_hl
rla
rla
rla
jr c,GRP1rm16i8_1xx
add a,a
jp p,GRP1rm16i8_ADD_ADC
jr nc,$ ;no OR
;jr c,SBBr16i8
ex af,af' ;'
SUBr16i8
ex af,af' ;'
SBBr16i8
get
ld c,a
rla
sbc a,a
ld b,a
ex af,af' ;'
jp SBCr16bc ;там next
GRP1rm16i8_ADD_ADC
jr c,ADCr16i8
;ADDr16i8
ex af,af' ;'
ADCr16i8
get
ld c,a
rla
sbc a,a
ld b,a
ex af,af' ;'
jp ADCr16bc ;там next
GRP1rm16i8_1xx
add a,a
;jp p,$ ;no AND,XOR??? used in para512!
jp p,GRP1rm16i8_AND_XOR
jr nc,SUBr16i8
CMPr16i8
get
ld c,a
rla
sbc a,a
jp CMPr16hlac ;там next
GRP1rm16i8_AND_XOR
UNTESTED
jr c,XORr16i8
get
ld c,a
and l
ld l,a
ld a,c
rla
sbc a,a
and h
jp GRP1rmi16logicq ;al=result ;там next
XORr16i8
get
ld c,a
xor l
ld l,a
ld a,c
rla
sbc a,a
xor h
jp GRP1rmi16logicq ;al=result ;там next
GRP1rmmem16i8
ADDRm16_GETm16_for_PUTm16
push hl
ld h,b
ld l,c
rla
rla
rla
jr c,GRP1rmmem16i8_1xx
add a,a
jp p,GRP1rmmem16i8_ADD_ADC
;jr c,SBBrmmem16i8
jr nc,$ ;no OR
ex af,af' ;'
SUBrmmem16i8
ex af,af' ;'
SBBrmmem16i8
get
ld c,a
rla
sbc a,a
ld b,a
ex af,af' ;'
jp SBBrmmem16bc ;там next
GRP1rmmem16i8_ADD_ADC
jr c,ADCrmmem16i8
;ADDrmmem16i8
ex af,af' ;'
ADCrmmem16i8
get
ld c,a
rla
sbc a,a
ld b,a
ex af,af' ;'
jp ADCrmmem16bc ;там next
GRP1rmmem16i8_1xx
add a,a
;jp p,$ ;no AND,XOR??? used in pchela!
jp p,GRP1rmmem16i8_AND_XOR
jr nc,SUBrmmem16i8
jr CMPr16i8
GRP1rmmem16i8_AND_XOR
UNTESTED
jr c,XORrmmem16i8
get
ld c,a
and l
ld l,a
ld a,c
rla
sbc a,a
and h
jp GRP1rmmemi16logicq ;al=result ;там next
XORrmmem16i8
get
ld c,a
xor l
ld l,a
ld a,c
rla
sbc a,a
xor h
jp GRP1rmmemi16logicq ;al=result ;там next
;ld h,a
;KEEPLOGICCFPARITYOVERFLOW_FROMHL_AisH
;next
;_PUTm16hlLoopC
;--------------- alu single calls
macro OPrmr8_PRE
get
next
;a=MDregR/M
;MD=00: cmd [...],reg8
;MD=01: cmd [...+disp8],reg8
;MD=10: cmd [...+disp16],reg8
;MD=11: cmd r/m,reg8 ;проще всего
cp 0b11000000
jp c,6f;OPrmmemr8
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld c,(hl)
sub 64
ld l,a
ld l,(hl) ;rm addr
;op (hl),c
endm
macro OPrmr8_POST
6;OPrmmemr8
ADDRm16_GETm8c_for_PUTm8
or 0b11000000
;ld l,a
;ld h,_AX/256
;ld l,(hl) ;reg8 addr
;op c,(hl)
endm
ALIGNrm
ADDrmr8
if DEBUG03
jr $ ;code 00
endif
or a
ex af,af' ;'
ALIGNrm
ADCrmr8
OPrmr8_PRE
ex af,af' ;'
ld a,(hl)
adc a,c ;op
ld (hl),a
KEEPHFCFPARITYOVERFLOW_FROMA
_Loop_
OPrmr8_POST
push hl
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ex af,af' ;'
ld a,c
adc a,(hl) ;op
ld c,a
KEEPHFCFPARITYOVERFLOW_FROMA
pop hl
_PUTm8cLoopC_oldpglx
ALIGNrm
SUBrmr8
or a
ex af,af' ;'
ALIGNrm
SBBrmr8
OPrmr8_PRE
ex af,af' ;'
ld a,(hl)
sbc a,c ;op
ld (hl),a
KEEPHFCFPARITYOVERFLOW_FROMA
_Loop_
OPrmr8_POST
push hl
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ex af,af' ;'
ld a,c
sbc a,(hl) ;op
ld c,a
KEEPHFCFPARITYOVERFLOW_FROMA
pop hl
_PUTm8cLoopC_oldpglx
ALIGNrm
CMPrmr8
OPrmr8_PRE
ld a,(hl)
sub c ;op
KEEPHFCFPARITYOVERFLOW_FROMA
_Loop_
6;CMPrmmemr8
ADDRm16_GETm8b_keepaf
or 0b11000000
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld a,b
sub (hl) ;op
KEEPHFCFPARITYOVERFLOW_FROMA
_LoopC
ALIGNrm
XORrmr8
OPrmr8_PRE
ld a,c
xor (hl) ;op
ld (hl),a
KEEPLOGICCFPARITYOVERFLOW_FROMA
_Loop_
OPrmr8_POST
push hl
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld a,c
xor (hl) ;op
ld c,a
KEEPLOGICCFPARITYOVERFLOW_FROMA
pop hl
_PUTm8cLoopC_oldpglx
ALIGNrm
ORrmr8
OPrmr8_PRE
ld a,c
or (hl) ;op
ld (hl),a
KEEPLOGICCFPARITYOVERFLOW_FROMA
_Loop_
OPrmr8_POST
push hl
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld a,c
or (hl) ;op
ld c,a
KEEPLOGICCFPARITYOVERFLOW_FROMA
pop hl
_PUTm8cLoopC_oldpglx
ALIGNrm
ANDrmr8
OPrmr8_PRE
ld a,c
and (hl) ;op
ld (hl),a
KEEPLOGICCFPARITYOVERFLOW_FROMA
_Loop_
OPrmr8_POST
push hl
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld a,c
and (hl) ;op
ld c,a
KEEPLOGICCFPARITYOVERFLOW_FROMA
pop hl
_PUTm8cLoopC_oldpglx
macro OPrmr16_PRE
get
next
;a=MDregR/M
;MD=00: cmd reg16,[...]
;MD=01: cmd reg16,[...+disp8]
;MD=10: cmd reg16,[...+disp16]
;MD=11: cmd reg16,r/m ;проще всего
cp 0b11000000
jp c,6f;OPrmmemr16
ld h,a
rra
rra
and 7*2
ld l,a ;reg16 addr
ld a,h
ld h,_AX/256
ld c,(hl)
inc l
ld b,(hl) ;reg16
and 7
add a,a
ld l,a ;rm addr
;push hl
;ld hl,(hl)
;or a
;adc hl,bc ;op
endm
macro OPrmr16_POST
6;OPrmmemr16
ADDRm16_GETm16_for_PUTm16
push hl
ld h,_AX/256
rra
rra
and 7*2
ld l,a ;reg16 addr
;ld hl,(hl)
;or a
;adc hl,bc ;op
endm
macro SUBrmr16_POST
6;SUBrmmemr16
ADDRm16_GETm16_for_PUTm16
push hl
ld h,_AX/256
rra
rra
and 7*2
ld l,a ;reg16 addr
push bc
ld c,(hl)
inc l
ld b,(hl) ;reg16
pop hl
ex af,af' ;'
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
_PUTm16hlLoopC
endm
macro CMPrmr16_POST
6;CMPrmmemr16
ADDRm16_GETm16 ;bc=rmmem
ld h,_AX/256
rra
rra
and 7*2
ld l,a ;reg16 addr
push bc
ld c,(hl)
inc l
ld b,(hl) ;reg16
pop hl ;rmmem
or a
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
_LoopC
endm
ALIGNrm
ADDrmr16
or a
ex af,af' ;'
ALIGNrm
ADCrmr16
OPrmr16_PRE
push hl
ld a,(hl)
inc l
ld h,(hl)
ld l,a
ex af,af' ;'
ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
_PUTr16hlLoop_
OPrmr16_POST
ld a,(hl)
inc l
ld h,(hl)
ld l,a
ex af,af' ;'
ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
_PUTm16hlLoopC
ALIGNrm
SUBrmr16
or a
ex af,af' ;'
ALIGNrm
SBBrmr16
OPrmr16_PRE
push hl
ld a,(hl)
inc l
ld h,(hl)
ld l,a
ex af,af' ;'
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
_PUTr16hlLoop_
SUBrmr16_POST
ALIGNrm
CMPrmr16
OPrmr16_PRE
ld a,(hl)
inc l
ld h,(hl)
ld l,a
or a
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
_LoopC
CMPrmr16_POST
ALIGNrm
XORrmr16
OPrmr16_PRE
push hl
ld a,(hl)
xor c
ld c,a
inc l
ld a,(hl)
xor b ;op
ld b,a
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
pop hl
_PUTr16Loop_
OPrmr16_POST
ld a,(hl)
xor c
ld c,a
inc l
ld a,(hl)
xor b ;op
ld b,a
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
pop hl
_PUTm16LoopC
ALIGNrm
ORrmr16
OPrmr16_PRE
push hl
ld a,(hl)
or c
ld c,a
inc l
ld a,(hl)
or b ;op
ld b,a
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
pop hl
_PUTr16Loop_
OPrmr16_POST
ld a,(hl)
or c
ld c,a
inc l
ld a,(hl)
or b ;op
ld b,a
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
pop hl
_PUTm16LoopC
ALIGNrm
ANDrmr16
OPrmr16_PRE
push hl
ld a,(hl)
and c
ld c,a
inc l
ld a,(hl)
and b ;op
ld b,a
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
pop hl
_PUTr16Loop_
OPrmr16_POST
ld a,(hl)
and c
ld c,a
inc l
ld a,(hl)
and b ;op
ld b,a
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
pop hl
_PUTm16LoopC
macro OPr8rm_PRE
get
next
;a=MDregR/M
;MD=00: cmd reg8,[...]
;MD=01: cmd reg8,[...+disp8]
;MD=10: cmd reg8,[...+disp16]
;MD=11: cmd reg8,r/m ;проще всего
cp 0b11000000
jp c,6f;ADDr8rmmem
ADDRr8 ;rm addr
ld b,(hl)
5;OPr8rmok
ld l,a
ld l,(hl) ;reg8 addr
;op (hl),b
endm
macro OPr8rm_POST
6;OPr8rmmem
ADDRm16_GETm8b_keepaf
or 0b11000000
ld h,_AX/256
jp 5b;OPr8rmok
endm
ALIGNrm
ADDr8rm
or a
ex af,af' ;'
ALIGNrm
ADCr8rm
OPr8rm_PRE
ex af,af' ;'
ld a,(hl)
adc a,b ;op
ld (hl),a
KEEPHFCFPARITYOVERFLOW_FROMA
_LoopC
OPr8rm_POST
ALIGNrm
SUBr8rm
or a
ex af,af' ;'
ALIGNrm
SBBr8rm
OPr8rm_PRE
ex af,af' ;'
ld a,(hl)
sbc a,b ;op
ld (hl),a
KEEPHFCFPARITYOVERFLOW_FROMA
_LoopC
OPr8rm_POST
ALIGNrm
CMPr8rm
OPr8rm_PRE
ld a,(hl)
sub b ;op
KEEPHFCFPARITYOVERFLOW_FROMA
_LoopC
OPr8rm_POST
ALIGNrm
XORr8rm
OPr8rm_PRE
ld a,(hl)
xor b ;op
ld (hl),a
KEEPLOGICCFPARITYOVERFLOW_FROMA
_LoopC
OPr8rm_POST
ALIGNrm
ORr8rm
OPr8rm_PRE
ld a,(hl)
or b ;op
ld (hl),a
KEEPLOGICCFPARITYOVERFLOW_FROMA
_LoopC
OPr8rm_POST
ALIGNrm
ANDr8rm
OPr8rm_PRE
ld a,(hl)
and b ;op
ld (hl),a
KEEPLOGICCFPARITYOVERFLOW_FROMA
_LoopC
OPr8rm_POST
macro OPr16rm_PRE
get
next
;a=MDregR/M
;MD=00: cmd reg16,[...]
;MD=01: cmd reg16,[...+disp8]
;MD=10: cmd reg16,[...+disp16]
;MD=11: cmd reg16,r/m ;проще всего
cp 0b11000000
jp c,6f;OPr16rmmem
ADDRr16_keepa ;rm addr
ld c,(hl)
inc l
ld b,(hl) ;rm
5;OPr16rmok
rra
rra
and 7*2
ld l,a ;reg16 addr
;push hl
;ld hl,(hl)
;op hl,bc
endm
macro OPr16rm_POST
6;OPr16rmmem
ADDRm16_GETm16 ;bc=rmmem
ld h,_AX/256
jp 5b;OPr16rmok
endm
macro CMPr16rmPOST
6;CMPr16rmmem
ADDRm16_GETm16 ;bc=rmmem
ld h,_AX/256
jp 5b;OPr16rmok
endm
macro LOGICOPr16rm_POST
6;OPr16rmmem
ADDRm16_GETm16 ;bc=rmmem
ld h,_AX/256
jp 5b;OPr16rmok
endm
ALIGNrm
ADDr16rm
if DEBUG03
jr $ ;code 03
endif
or a
ex af,af' ;'
ALIGNrm
ADCr16rm
OPr16rm_PRE
push hl
ld a,(hl)
inc l
ld h,(hl)
ld l,a
ex af,af' ;'
ADCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
ld b,h
ld c,l
pop hl
_PUTr16LoopC
OPr16rm_POST
ALIGNrm
SUBr16rm
or a
ex af,af' ;'
ALIGNrm
SBBr16rm
OPr16rm_PRE
push hl
ld a,(hl)
inc l
ld h,(hl)
ld l,a
ex af,af' ;'
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
ld b,h
ld c,l
pop hl
_PUTr16LoopC
OPr16rm_POST
ALIGNrm
CMPr16rm
OPr16rm_PRE
ld a,(hl)
inc l
ld h,(hl)
ld l,a
or a
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
_LoopC
CMPr16rmPOST
ALIGNrm
XORr16rm
OPr16rm_PRE
ld a,(hl)
xor c
ld c,a
inc l
ld a,(hl)
xor b
ld b,a
dec l
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
_PUTr16LoopC
LOGICOPr16rm_POST
ALIGNrm
ORr16rm
OPr16rm_PRE
ld a,(hl)
or c
ld c,a
inc l
ld a,(hl)
or b
ld b,a
dec l
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
_PUTr16LoopC
LOGICOPr16rm_POST
ALIGNrm
ANDr16rm
OPr16rm_PRE
ld a,(hl)
and c
ld c,a
inc l
ld a,(hl)
and b
ld b,a
dec l
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
_PUTr16LoopC
LOGICOPr16rm_POST
display "alus size=",$-beginalus
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
beginrolls
ALIGNrm
GRP2rm8i8
get
next
;a=MD000R/M: rol r/m
;a=MD001R/M: ror r/m
;a=MD010R/M: rcl r/m
;a=MD011R/M: rcr r/m
;a=MD100R/M: shl r/m
;a=MD101R/M: shr r/m
;a=MD110R/M: ??? r/m <-- shl
;a=MD111R/M: sar r/m
cp 0b11000000
jr c,GRP2rmmem8i8
ADDRr8 ;rm addr
push af ;TODO optimize
get
next
;if SHIFTCOUNTMASK
;and 31
;endif
ld b,a
pop af
ld c,(hl)
rla
rla
rla
jr c,GRP2rm8i8_1xx
add a,a
jp p,GRP2rm8i8_ROL_RCL ;0x0
jr c,RCRr8i8
call RORci8
ld (hl),c
_Loop_
RCRr8i8
call RCRci8
ld (hl),c
_Loop_
GRP2rm8i8_ROL_RCL
jr c,RCLr8i8
call ROLci8
ld (hl),c
_Loop_
RCLr8i8
call RCLci8
ld (hl),c
_Loop_
GRP2rm8i8_1xx
add a,a
jp p,SHLr8i8
jr c,SARr8i8
call SHRci8
ld (hl),c
_Loop_
SARr8i8
call SARci8
GRP2r8i8q
ld (hl),c
_Loop_
SHLr8i8
call SHLci8
ld (hl),c
_Loop_
GRP2rmmem8i8
ADDRm16_GETm8c_for_PUTm8 ;делает ld lx,c
push af ;TODO optimize
get
next
;if SHIFTCOUNTMASK
;and 31
;endif
ld b,a
pop af
rla
rla
rla
jr c,GRP2rmmem8i8_1xx
add a,a
jp p,GRP2rmmem8i8_ROL_RCL ;0x0
jr c,RCRm8i8
call RORci8
jr GRP2rmmem8i8q
RCRm8i8
call RCRci8
jr GRP2rmmem8i8q
GRP2rmmem8i8_ROL_RCL
jr c,RCLm8i8
call ROLci8
jr GRP2rmmem8i8q
RCLm8i8
call RCLci8
jr GRP2rmmem8i8q
GRP2rmmem8i8_1xx
add a,a
jp p,SHLm8i8
jr c,SARm8i8
call SHRci8
GRP2rmmem8i8q
_PUTm8cLoopC_oldpglx
SARm8i8
call SARci8
jr GRP2rmmem8i8q
SHLm8i8
call SHLci8
jr GRP2rmmem8i8q
;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.
ROLci8
ROL_c_b
ex af,af' ;' ;remember ZF
ld a,c
ROLci8loop
rlca
djnz ROLci8loop
ld c,a
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
ex af,af' ;'
ret
;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
RORci8
ROR_c_b
ex af,af' ;' ;remember ZF
ld a,c
RORci8loop
rrca
djnz RORci8loop
ld c,a
exx
ld e,a ;overflow data
exx
ex af,af' ;'
ret
;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.
RCLci8
RCL_c_b
ex af,af' ;' ;remember ZF,CF
ld a,c
RCLci8loop
rla
djnz RCLci8loop
ld c,a
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
ex af,af' ;'
ret
;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
RCRci8
RCR_c_b
ex af,af' ;' ;remember ZF,CF
ld a,c
RCRci8loop
rra
djnz RCRci8loop
ld c,a
exx
ld e,a ;overflow data
exx
ex af,af' ;'
ret
;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.
SHLci8
SHL_c_b
ld a,c
SHLr8i8loop
add a,a
djnz SHLr8i8loop
ld c,a
KEEPCFPARITYOVERFLOW_FROMA
ret
;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
SHRci8
SHR_c_b
SHRr8i8loop
srl c
djnz SHRr8i8loop
ld a,c
exx
ld d,a ;parity data
ld e,a ;overflow data
exx
ex af,af' ;'
ret
;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
SARci8
SAR_c_b
SARr8i8loop
sra c
djnz SARr8i8loop
ld a,c
exx
ld d,a ;parity data
ld e,a ;overflow data
exx
ex af,af' ;'
ret
ALIGNrm
GRP2rm81
get
next
;a=MD000R/M: rol r/m
;a=MD001R/M: ror r/m
;a=MD010R/M: rcl r/m
;a=MD011R/M: rcr r/m
;a=MD100R/M: shl r/m
;a=MD101R/M: shr r/m
;a=MD110R/M: ??? r/m
;a=MD111R/M: sar r/m
cp 0b11000000
jr c,GRP2rmmem81
ADDRr8 ;rm addr
rla
rla
rla
jr c,GRP2rm81_1xx
add a,a
jp p,GRP2rm81_ROL_RCL ;0x0
;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
jr c,RCRr8
;RORr8
ex af,af' ;' ;remember ZF
ld a,(hl)
rrca
ld (hl),a
exx
ld e,a ;overflow data
exx
ex af,af' ;'
_Loop_
RCRr8
ex af,af' ;' ;remember ZF,CF
ld a,(hl)
rra
ld (hl),a
exx
ld e,a ;overflow data
exx
ex af,af' ;'
_Loop_
GRP2rm81_ROL_RCL
;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.
jr c,RCLr8
;ROLr8
ex af,af' ;' ;remember ZF
ld a,(hl)
rlca
ld (hl),a
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
ex af,af' ;'
_Loop_
RCLr8
ex af,af' ;' ;remember ZF,CF
ld a,(hl)
rla
ld (hl),a
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
ex af,af' ;'
_Loop_
GRP2rm81_1xx
add a,a
jp p,SHLr8
jr c,SARr8
;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
srl (hl)
ld a,(hl)
exx
ld d,a ;parity data
ld e,a ;overflow data
exx
ex af,af' ;'
_Loop_
;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
SARr8
sra (hl)
ld a,(hl)
exx
ld d,a ;parity data
ld e,a ;overflow data
exx
ex af,af' ;'
_Loop_
;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.
SHLr8
ld a,(hl)
add a,a
jp keephlflagsfroma_loop
;ld (hl),a
;KEEPCFPARITYOVERFLOW_FROMA
;_Loop_
GRP2rmmem81
ADDRm16_GETm8c_for_PUTm8
rla
rla
rla
jr c,GRP2rmmem81_1xx
add a,a
jp p,GRP2rmmem81_ROL_RCL ;0x0
;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
jr c,RCRm8
;RORm8
ex af,af' ;' ;remember ZF
ld a,c
rrca
ld c,a
exx
ld e,a ;overflow data
exx
ex af,af' ;'
_PUTm8cLoopC_oldpglx
RCRm8
ex af,af' ;' ;remember ZF,CF
ld a,c
rra
ld c,a
exx
ld e,a ;overflow data
exx
ex af,af' ;'
_PUTm8cLoopC_oldpglx
GRP2rmmem81_ROL_RCL
;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.
jr c,RCLm8
;ROLm8
ex af,af' ;' ;remember ZF
ld a,c
rlca
ld c,a
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
ex af,af' ;'
_PUTm8cLoopC_oldpglx
RCLm8
ex af,af' ;' ;remember ZF,CF
ld a,c
rla
ld c,a
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
ex af,af' ;'
_PUTm8cLoopC_oldpglx
GRP2rmmem81_1xx
add a,a
jp p,SHLm8
jr c,SARm8
;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
srl c
ld a,c
exx
ld d,a ;parity data
ld e,a ;overflow data
exx
ex af,af' ;'
_PUTm8cLoopC_oldpglx
;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
SARm8
sra c
ld a,c
exx
ld d,a ;parity data
ld e,a ;overflow data
exx
ex af,af' ;'
_PUTm8cLoopC_oldpglx
;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.
SHLm8
ld a,c
add a,a
ld c,a
KEEPCFPARITYOVERFLOW_FROMA
_PUTm8cLoopC_oldpglx
ALIGNrm
GRP2rm161
get
next
;a=MD000R/M: rol r/m
;a=MD001R/M: ror r/m
;a=MD010R/M: rcl r/m
;a=MD011R/M: rcr r/m
;a=MD100R/M: shl r/m
;a=MD101R/M: shr r/m
;a=MD110R/M: ??? r/m <-- shl
;a=MD111R/M: sar r/m
cp 0b11000000
jp c,GRP2rmmem161
ADDRr16_keepa
rla
rla
rla
jr c,GRP2rm161_1xx
add a,a
jp p,GRP2rm161_ROL_RCL ;0x0
;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
jr c,RCRr16
;RORr16
ex af,af' ;' ;remember ZF
inc hl ;keep ZF
ld a,(hl)
ld b,a
rra
dec hl ;keep ZF
ld a,(hl)
rra
ld c,a
ld a,b
rra ;use CF from C
ld b,a
exx
ld e,a ;overflow data
exx
jr _ROLr16q
RCRr16
ex af,af' ;' ;remember ZF,CF
inc hl ;keep ZF
ld a,(hl)
rra
ld b,a
exx
ld e,a ;overflow data
exx
dec hl ;keep ZF
ld a,(hl)
rra
ld c,a
jr _ROLr16q
GRP2rm161_ROL_RCL
;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.
jr c,RCLr16
;ROLr16
ex af,af' ;' ;remember ZF
inc hl ;keep ZF
ld a,(hl)
ld b,a
rla
dec hl ;keep ZF
ld a,(hl)
rla
ld c,a
ld a,b
jr RCLr16_go
RCLr16
ex af,af' ;' ;remember ZF,CF
ld a,(hl)
rla
ld c,a
inc hl ;keep ZF
ld a,(hl)
dec hl ;keep ZF
RCLr16_go
rla
ld b,a
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
jr _ROLr16q
GRP2rm161_1xx
add a,a
jp p,SHLr16
inc l
ld b,(hl)
jr c,SARr16
;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
;SHRr16
srl b
jr SARr16_go
;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
SARr16
sra b
SARr16_go
dec l
ld a,(hl)
rra
ld c,a
;чтобы правильно сформировать ZF,SF по b,c:
;если c!=0, то set 0,b
add a,0xff
sbc a,a ;CF=(c!=0)
and d;1 ;any number 1..0x7f
or b ;CF=0 ;ZF=(bc==0)
ld a,(hl)
rra ;CF
ld a,b
exx
ld e,a ;overflow data
exx
_ROLr16pfq
ld a,c
exx
ld d,a ;parity data
exx
_ROLr16q
ex af,af' ;'
_PUTr16Loop_
;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.
SHLr16
ld a,(hl)
add a,a
ld c,a
inc l
ld a,(hl)
exx
ld e,a ;overflow data
exx
rla
ld b,a
ld a,c
;чтобы правильно сформировать ZF,SF по b,c:
;если c!=0, то set 0,b
add a,0xff
sbc a,a ;CF=(c!=0)
and d;1 ;any number 1..0x7f
or b ;CF=0 ;ZF=(bc==0)
ld a,(hl) ;oldb
rla ;CF
dec hl ;keep ZF
jr _ROLr16pfq
GRP2rmmem161
ADDRm16_GETm16_for_PUTm16
push hl
rla
rla
rla
jr c,GRP2rmmem161_1xx
add a,a
jp p,GRP2rmmem161_ROL_RCL ;0x0
;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
jr c,RCRm16
;RORm16
ld a,c
rra
jr RCRm16_go
RCRm16
ex af,af' ;'
rla
ld l,a ;l0=old CF, keep other flags
ex af,af' ;'
rr l ;restore CF
RCRm16_go
rr b
rr c
rl l ;l0=new CF
ex af,af' ;'
_ROLm16cfofq
ld a,l
rra ;new CF, keep other flags
ld a,b
exx
ld e,a ;overflow data
exx
_ROLm16q
ex af,af' ;'
pop hl
_PUTm16LoopC
;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.
GRP2rmmem161_ROL_RCL
jr c,RCLm16
;ROLm16
ld a,b
exx
ld e,a ;overflow data
exx
rla
jr RCLm16_go
;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.
RCLm16
ld a,b
exx
ld e,a ;overflow data
exx
ex af,af' ;'
rla
ld l,a ;l0=old CF, keep other flags
ex af,af' ;'
rr l ;restore CF
RCLm16_go
rl c
rl b
rl l ;l0=new CF
ex af,af' ;'
ld a,l
rra ;new CF, keep other flags
jr _ROLm16q
GRP2rmmem161_1xx
add a,a
jp p,SHLm16
ld l,c ;for generating CF
jr c,SARm16
;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
;SHRm16
srl b
jr SARm16_go
;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
SARm16
sra b
SARm16_go
rr c
ld a,c
;чтобы правильно сформировать ZF,SF по b,c:
;если c!=0, то set 0,b
add a,0xff
sbc a,a ;CF=(c!=0)
and d;1 ;any number 1..0x7f
or b ;CF=0 ;ZF=(bc==0)
ld a,c
exx
ld d,a ;parity data
exx
jr _ROLm16cfofq
;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.
SHLm16
ld a,h
exx
ld e,a ;overflow data
exx
or a
adc hl,hl ;CF,ZF,SF
ld a,l
exx
ld d,a ;parity data
exx
ex af,af' ;'
GRP2rmmem16i8q
_PUTm16hlLoopC
ALIGNrm
GRP2rm16cl
get
next
;a=MD000R/M: rol r/m,cl
;a=MD001R/M: ror r/m,cl
;a=MD010R/M: rcl r/m,cl
;a=MD011R/M: rcr r/m,cl
;a=MD100R/M: shl r/m,cl
;a=MD101R/M: shr r/m,cl
;a=MD110R/M: ??? <-- shl
;a=MD111R/M: sar r/m,cl
cp 0b11000000
jp c,GRP2rmmem16cl
ADDRr16_keepa
push hl
ld (_GRP2rm16cl_hl),hl
ld hl,GRP2r16i8q
push hl
_GRP2rm16cl_hl=$+1
ld hl,(0) ;ok
jr GRP2rm16cl_go
GRP2rmmem16cl
ADDRm16_GETm16_for_PUTm16
push hl
ld hl,GRP2rmmem16i8q
push hl
ld h,b
ld l,c
GRP2rm16cl_go
ld c,a ;op
ld a,(_CL)
if SHIFTCOUNTMASK
and 0x1f
else
or a
endif
jr nz,GRP2rm16cl_no0
pop hl ;skip
pop hl ;skip
_LoopC
GRP2rm16cl_no0
ld b,a
ld a,c
rla
rla
rla
jr c,GRP2rm16cl_1xx
add a,a
jr c,GRP2rm16cl_01x
jp m,RORhl_b_to_hl
jp ROLhl_b_to_hl
GRP2rm16cl_01x
jp m,RCRhl_b_to_hl
jp RCLhl_b_to_hl
GRP2rm16cl_1xx
add a,a
jp p,SHLhl_b_to_hl
jp c,SARhl_b_to_hl
jp SHRhl_b_to_hl
ALIGNrm
GRP2rm8cl
get
next
;a=MD000R/M: rol r/m,cl
;a=MD001R/M: ror r/m,cl
;a=MD010R/M: rcl r/m,cl
;a=MD011R/M: rcr r/m,cl
;a=MD100R/M: shl r/m,cl
;a=MD101R/M: shr r/m,cl
;a=MD110R/M: ???
;a=MD111R/M: sar r/m,cl
cp 0b11000000
jr c,GRP2rmmem8cl
ADDRr8
ld c,(hl)
push hl
ld hl,GRP2r8i8q
jr GRP2rmmem8cl_go
GRP2rmmem8cl
ADDRm16_GETm8c_for_PUTm8
push hl
ld hl,GRP2rmmem8i8q
GRP2rmmem8cl_go
push af
ld a,(_CL)
if SHIFTCOUNTMASK
and 31
else
or a
endif
jr nz,GRP2rmmem8cl_no0
pop af ;skip
pop hl ;skip
_LoopC
GRP2rmmem8cl_no0
ld b,a
pop af
ex (sp),hl ;keep return addr, hl=putaddr
rla
rla
rla
jr c,GRP2m8cl_1xx
add a,a
jr c,GRP2m8cl_01x
jp m,ROR_c_b ;TODO jp m один раз
jp ROL_c_b
GRP2m8cl_01x
jp m,RCR_c_b
jp RCL_c_b
GRP2m8cl_1xx
add a,a
jp p,SHL_c_b
jp c,SAR_c_b
jp SHR_c_b
ALIGNrm
GRP2rm16i8
get
next
;a=MD000R/M: rol r/m,i8
;a=MD001R/M: ror r/m,i8
;a=MD010R/M: rcl r/m,i8
;a=MD011R/M: rcr r/m,i8
;a=MD100R/M: shl r/m,i8
;a=MD101R/M: shr r/m,i8
;a=MD110R/M: ??? <------- shl
;a=MD111R/M: sar r/m,i8
cp 0b11000000
jr c,GRP2rmmem16i8
ADDRr16_keepa
push hl
ld c,(hl)
inc l
ld b,(hl)
ld hl,GRP2r16i8q
jr GRP2rm16i8_go
GRP2rmmem16i8
ADDRm16_GETm16_for_PUTm16
push hl
ld hl,GRP2rmmem16i8q
GRP2rm16i8_go
push hl
ld h,b
ld l,c
rla
rla
rla
jp c,GRP2rmmem16i8_1xx
add a,a
jr c,GRP2rmmem16i8_01x
jp m,RORhli8_to_hl ;TODO once
;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.
ROLhli8_to_hl
get
next
ld b,a
ROLhl_b_to_hl
ex af,af' ;' ;remember ZF
ld a,h
_ROLr16i8loop
rla
ld a,l
rla
ld l,a
ld a,h
rla
ld h,a
djnz _ROLr16i8loop
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
ex af,af' ;'
ret
;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
RORhli8_to_hl
get
next
ld b,a
RORhl_b_to_hl
ex af,af' ;' ;remember ZF
ld a,l
_RORr16i8loop
rra
ld a,h
rra
ld h,a
ld a,l
rra
ld l,a
djnz _RORr16i8loop
ld a,h
exx
ld e,a ;overflow data
exx
ex af,af' ;'
ret
GRP2rmmem16i8_01x
jp m,RCRhli8_to_hl
;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.
RCLhli8_to_hl
get
next
ld b,a
RCLhl_b_to_hl
ex af,af' ;' ;remember ZF,CF
_RCLr16i8loop
ld a,l
rla
ld l,a
ld a,h
rla
ld h,a
djnz _RCLr16i8loop
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
ex af,af' ;'
ret
;For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
RCRhli8_to_hl
get
next
ld b,a
RCRhl_b_to_hl
ex af,af' ;' ;remember ZF,CF
_RCRr16i8loop
ld a,h
rra
ld h,a
ld a,l
rra
ld l,a
djnz _RCRr16i8loop
ld a,h
exx
ld e,a ;overflow data
exx
ex af,af' ;'
ret
;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.
SHLhli8_to_hl
get
next
ld b,a
SHLhl_b_to_hl
_SHLr16i8loop
or a
adc hl,hl ;CF,ZF,SF
djnz _SHLr16i8loop
exx
rra
ld e,a ;overflow data
rla ;restore CF
exx
ld a,l
exx
ld d,a ;parity data
exx
ex af,af' ;'
ret
GRP2rmmem16i8_1xx
add a,a
jp p,SHLhli8_to_hl
jr c,SARhli8_to_hl
;For the SHR instruction, the OF flag is set to the most-significant bit of the original operand. (result7 xor result6)
SHRhli8_to_hl
get
next
ld b,a
SHRhl_b_to_hl
_SHRr16i8loop
srl h
rr l
djnz _SHRr16i8loop
rra
ld b,a ;keep CF
ld a,l
;чтобы правильно сформировать ZF,SF по h,l:
;если l!=0, то set h!=0
add a,0xff
sbc a,a ;CF=(c!=0)
and d;1 ;any number 1..0x7f
or h ;CF=0 ;ZF=(bc==0)
ld a,b
rla ;CF
ld a,h
exx
ld e,a ;overflow data
exx
ld a,l
exx
ld d,a ;parity data
exx
ex af,af' ;'
ret
;For the SAR instruction, the OF flag is cleared for all 1-bit shifts. (result7 xor result6)
SARhli8_to_hl
get
next
ld b,a
SARhl_b_to_hl
_SARr16i8loop
sra h
rr l
djnz _SARr16i8loop
rra
ld b,a ;keep CF
ld a,l
;чтобы правильно сформировать ZF,SF по h,l:
;если l!=0, то set h!=0
add a,0xff
sbc a,a ;CF=(c!=0)
and d;1 ;any number 1..0x7f
or h ;CF=0 ;ZF=(bc==0)
ld a,b
rla ;CF
ld a,h
exx
ld e,a ;overflow data
exx
ld a,l
exx
ld d,a ;parity data
exx
ex af,af' ;'
ret
display "rolls size=",$-beginrolls
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
beginmuls
NOTr8 ;no flags
ld a,(hl)
cpl
ld (hl),a
_Loop_
NEGr8
xor a
sub (hl)
ld (hl),a
KEEPHFCFPARITYOVERFLOW_FROMA
_Loop_
ALIGNrm
GRP38
get
next
;a=MD000R/M: test r/m8,i8 (не верится по формату)
;a=MD001R/M: ?
;a=MD010R/M: not r/m8
;a=MD011R/M: neg r/m8
;a=MD100R/M: mul ax,r/m8
;a=MD101R/M: imul ax,r/m8
;a=MD110R/M: div ax,r/m8
;a=MD111R/M: idiv ax,r/m8
cp 0b11000000
jp c,GRP38mem
ADDRr8
and 0b00111000
jp z,TESTr8i8
cp 0b00010000
jr z,NOTr8
cp 0b00011000
jr z,NEGr8
cp 0b00100000
jp z,MULr8 ;for fbird "mul ah"
cp 0b00101000
jp z,IMULr8 ;for rogue "imul ah"
cp 0b00110000
jp z,DIVr8 ;for invaders "div cl"
cp 0b00111000
jp z,IDIVr8 ;for pitman
if debug_stop = 0
jp PANIC
else
jr $
endif
MULr8
;mul ah: ax=al*ah
ld c,(hl) ;reg
MULrmmem8
push de
ld b,0
ld de,(_AX)
ld d,b;0
call MUL16 ;HLDE=DE*BC
;ld (_DX),hl ;надо ли?
ld (_AX),de
pop de
_Loop_
IMULr8
;imul ah: ax=+-al*+-ah?
ld c,(hl) ;reg
IMULrmmem8
UNTESTED
push de
ld a,c
rla
sbc a,a
ld b,a
ld a,(_AL)
ld e,a
rla
sbc a,a
ld d,a
call MUL16SIGNED ;HLDE=DE*BC
;ld (_DX),hl ;надо ли?
ld (_AX),de
pop de
_Loop_
DIVr8
;DIV AL,r/m8
;Беззнаковое деление AX на r/m8, частное помещается в AL, остаток от деления - в AH
ld c,(hl) ;reg
DIVrmmem8
UNTESTED
push de
ld e,c ;reg
ld d,0
ld bc,(_AX)
ld hl,0
call DIV32 ;BC = HLBC/DE, HL = HLBC%DE
ld h,l ;остаток
ld l,c ;частное
ld (_AX),hl
pop de
_Loop_
IDIVr8
;IDIV AL,r/m8
;знаковое деление AX на r/m8, частное помещается в AL, остаток от деления - в AH
ld c,(hl) ;reg
IDIVrmmem8
UNTESTED
push de
ld e,c ;reg
ld a,c
rla
sbc a,a
ld d,a
;ld d,0
ld bc,(_AX)
ld a,b
rla
sbc a,a
ld h,a
ld l,a
;ld hl,0
call DIV32SIGNED ;BC = HLBC/DE, HL = HLBC%DE
ld h,l ;остаток
ld l,c ;частное
ld (_AX),hl
pop de
_Loop_
TESTr8i8
ld c,(hl)
TESTrmmemi8
get
next
and c
;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.
KEEPLOGICCFPARITYOVERFLOW_FROMA
_LoopC
GRP38mem
ADDRm16_GETm8c_for_PUTm8
and 0b00111000
jr z,TESTrmmemi8
cp 0b00010000
jr z,NOTrmmem8
cp 0b00011000
jr z,NEGrmmem8
cp 0b00100000
jp z,MULrmmem8
cp 0b00101000
jp z,IMULrmmem8
cp 0b00110000
jp z,DIVrmmem8
cp 0b00111000
jp z,IDIVrmmem8
if debug_stop = 0
jp PANIC
else
jr $
endif
NOTrmmem8 ;no flags
ld a,c
cpl
ld c,a
_PUTm8cLoopC_oldpglx
NEGrmmem8
xor a
sub c
ld c,a
KEEPHFCFPARITYOVERFLOW_FROMA
_PUTm8cLoopC_oldpglx
ALIGNrm
GRP316
get
next
;a=MD000R/M: test r/m,i16 (не верится по формату)
;a=MD001R/M: ?
;a=MD010R/M: not r/m
;a=MD011R/M: neg r/m
;a=MD100R/M: mul ax,r/m
;a=MD101R/M: imul ax,r/m
;a=MD110R/M: div ax,r/m
;a=MD111R/M: idiv ax,r/m
cp 0b11000000
jr c,GRP316mem
ADDRr16_keepa
;TODO rla
and 0b00111000
jr z,TESTr16i16
cp 0b00010000
jp z,NOTr16
cp 0b00011000
jp z,NEGr16
cp 0b00100000
jp z,MULr16
cp 0b00101000
jp z,IMULr16
cp 0b00110000
jp z,DIVr16
cp 0b00111000
jp z,IDIVr16
if debug_stop = 0
jp PANIC
else
jr $
endif
TESTr16i16
UNTESTED
GETr16
; jr TESTrmmemi16_skip
TESTrmmemi16
;UNTESTED
;TESTrmmemi16_skip
get
next
and c
ld c,a
get
next
and b
ld b,a
;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.
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
_LoopC
GRP316mem
ADDRm16_GETm16_for_PUTm16
;TODO rla
and 0b00111000
jr z,TESTrmmemi16
cp 0b00010000
jp z,NOTrmmem16
cp 0b00011000
jp z,NEGrmmem16
cp 0b00100000
jp z,MULrmmem16
cp 0b00101000
jp z,IMULrmmem16
cp 0b00110000
jp z,DIVrmmem16
cp 0b00111000
jp z,IDIVrmmem16
if debug_stop = 0
jp PANIC
else
jr $
endif
;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
macro NEGBCWITHFLAGS
xor a
ld h,a
ld l,a
SBCHLBC_KEEPCFPARITYOVERFLOW_FROMHL
ld b,h
ld c,l
endm
NEGr16
UNTESTED
push hl
GETr16
NEGBCWITHFLAGS
pop hl
_PUTr16Loop_
NEGrmmem16
UNTESTED
push hl
NEGBCWITHFLAGS
pop hl
_PUTm16LoopC
NOTr16
ld a,(hl)
cpl
ld c,a
inc l
ld a,(hl)
cpl
dec l
ld b,a ;no flags
_PUTr16Loop_
NOTrmmem16
ld a,c
cpl
ld c,a
ld a,b
cpl
ld b,a ;no flags
_PUTm16LoopC
;mul cx ;ax*cx -> dxax (set OF,CF if result >=65536)
MULr16
GETr16
MULrmmem16
;UNTESTED
push de
ld de,(_AX);ex de,hl ;de=ax
call MUL16 ;HLDE=DE*BC
ld (_DX),hl
ld (_AX),de
ld a,h
or l ;0?
add a,255 ;set CF if result >=65536
sbc a,a ;keep CF
srl a ;keep CF
exx
ld e,a ;overflow (d7 != d6) if CF
exx
ex af,af' ;'
pop de
_Loop_
;imul cx ;ax*cx -> dxax signed (set OF,CF if result >=32768 or < -32768)
IMULr16
GETr16
IMULrmmem16
UNTESTED
push de
ld de,(_AX);ex de,hl ;de=ax
call IMUL_bc_de_to_hlde
ld (_DX),hl ;HSW
ld (_AX),de ;LSW
pop de
_Loop_
;div cx ;dxax/cx -> ax частное, dx остаток (надо ffff ffff/0001 = ffff, остаток ffff, а не остаток 0)
DIVr16
GETr16
DIVrmmem16
UNTESTED
push de
ld d,b
ld e,c
ld bc,(_AX)
ld hl,(_DX)
call DIV32 ;BC = HLBC/DE, HL = HLBC%DE
ld (_DX),hl
ld (_AX),bc
pop de
_Loop_
;idiv cx ;dxax/cx -> ax частное, dx остаток signed (знак остатка равен знаку делимого)
IDIVr16
GETr16
IDIVrmmem16
UNTESTED
push de
ld d,b
ld e,c
ld bc,(_AX)
ld hl,(_DX)
call DIV32SIGNED ;BC = HLBC/DE, HL = HLBC%DE
ld (_DX),hl
ld (_AX),bc
pop de
_Loop_
ALIGNrm
TESTrmr8
UNTESTED
get
next
cp 0b11000000
jr c,TESTrmmemr8
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld c,(hl)
sub 64
ld l,a
ld l,(hl) ;rm addr
ld a,(hl)
and c ;op
KEEPLOGICCFPARITYOVERFLOW_FROMA
_Loop_
TESTrmmemr8
ADDRm16_GETm8b_keepaf
or 0b11000000
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld a,b
and (hl) ;op
KEEPLOGICCFPARITYOVERFLOW_FROMA
_LoopC
ALIGNrm
TESTrmr16
UNTESTED
get
next
cp 0b11000000
jr c,TESTrmmemr16
ld h,a
rra
rra
and 7*2
ld l,a ;reg16 addr
ld a,h
ld h,_AX/256
ld c,(hl)
inc l
ld b,(hl) ;reg16
and 7
add a,a
ld l,a ;rm addr
ld a,(hl)
and c
ld c,a
inc l
ld a,(hl)
and b ;op
ld b,a
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
_Loop_
TESTrmmemr16
UNTESTED
ADDRm16_GETm16 ;bc=rmmem
rra
rra
and 7*2
ld l,a ;reg16 addr
ld h,_AX/256
ld a,(hl)
and c
ld c,a
inc l
ld a,(hl)
and b ;op
ld b,a
KEEPLOGICCFPARITYOVERFLOW_FROMBC_AisB
_LoopC
ALIGNrm
GRP48
;a=MD000R/M: inc r/m8
;a=MD001R/M: dec r/m8
get
next
cp 0b11000000
jr c,GRP48mem
ADDRr8
and 0b00111000
;and 0b00001000 ;Валерий Лис: На 8086 глянул, как работает, он делает DEC всем mod_reg>0. Но это ошибка на современных процессорах и вызывает исключение
jr z,INCr8
;cp 0b00001000
jp nz,DECr8
if debug_stop = 0
jp PANIC
else
jr $
endif
GRP48mem
ADDRm16_GETm8c_for_PUTm8
and 0b00111000
;and 0b00001000 ;Валерий Лис: На 8086 глянул, как работает, он делает DEC всем mod_reg>0. Но это ошибка на современных процессорах и вызывает исключение
jr z,INCrmmem8
;cp 0b00001000
jp nz,DECrmmem8
;TODO fe 27 for blockage?
;TODO fe 70 for atom?
if debug_stop = 0
jp PANIC
else
jr $
endif
INCr8
ex af,af' ;' ;remember CY (keep)
ld a,(hl)
inc a
ld (hl),a
KEEPHFCFPARITYOVERFLOW_FROMA
_Loop_
DECr8
ex af,af' ;' ;remember CY (keep)
ld a,(hl)
dec a
ld (hl),a
KEEPHFCFPARITYOVERFLOW_FROMA
_Loop_
INCrmmem8
;UNTESTED
ex af,af' ;' ;remember CY (keep)
inc c
ld a,c
KEEPHFCFPARITYOVERFLOW_FROMA
_PUTm8cLoopC_oldpglx
DECrmmem8
;UNTESTED
ex af,af' ;' ;remember CY (keep)
dec c
ld a,c
KEEPHFCFPARITYOVERFLOW_FROMA
_PUTm8cLoopC_oldpglx
JMPr16
UNTESTED
GETr16_de
jp JMPr16q
DECr16
push hl
GETr16
decbcwithflags
jr _pophl_PUTr16Loop_
;pop hl
;_PUTr16Loop_
ALIGNrm
GRP416
;a=MD000R/M: inc r/m16
;a=MD001R/M: dec r/m16
;a=MD010R/M: call r/m16
;a=MD011R/M: callf m16:16 ;первым идет WORD для IP, потом для CS ;push cs; push ip
;a=MD100R/M: jmp r/m16
;a=MD101R/M: jmpf m16:16 ;первым идет WORD для IP, потом для CS ;push cs; push ip
;a=MD110R/M: push r/m16
;a=MD111R/M: ?
get
next
cp 0b11000000
jp c,GRP416mem
ADDRr16_keepa
and 0b00111000
jr z,INCr16
cp 0b00001000
jr z,DECr16
cp 0b00010000
jr z,CALLr16
;cp 0b00011000
;jp z,CALLFm1616 ;for vc???
cp 0b00100000
jr z,JMPr16
;cp 0b00101000
;jp z,JMPFm1616
;cp 0b00110000
;jp z,PUSHr16
if debug_stop = 0
jp nz,PANIC
else
jr nz,$
endif
INCr16
push hl
GETr16
incbcwithflags
_pophl_PUTr16Loop_
pop hl
_PUTr16Loop_
CALLr16
GETr16_hl
decodePC
ex de,hl ;new IP(PC)
ld b,h
ld c,l ;=old IP(PC)
putmemspBC
JMPr16q
_LoopJP
GRP416mem
ADDRm16_GETm16_for_PUTm16
and 0b00111000
jr z,INCrmmem16
cp 0b00001000
jr z,DECrmmem16
cp 0b00010000
jp z,CALLrmmem16
cp 0b00011000
jp z,CALLFm1616mem ;высчитывается эффективный адрес, и с этого адреса берутся 4 байта (ip:cs)
cp 0b00100000
jr z,JMPrmmem16
cp 0b00101000
jp z,JMPFm1616mem ;высчитывается эффективный адрес, и с этого адреса берутся 4 байта (ip:cs)
cp 0b00110000
;jr z,PUSHrmmem16
if debug_stop = 0
jp nz,PANIC
else
jr nz,$
endif
PUSHrmmem16
putmemspBC
_LoopC
INCrmmem16
push hl
incbcwithflags
_pophl_PUTm16LoopC
pop hl
_PUTm16LoopC
DECrmmem16
push hl
decbcwithflags
jr _pophl_PUTm16LoopC
JMPrmmem16
UNTESTED
ld d,b
ld e,c
_LoopC_JP
JMPFm1616mem ;высчитывается эффективный адрес, и с этого адреса берутся 4 байта (ip:cs)
UNTESTED
;уже прочитано 2 байта bc из (hl), но hl не сдвинут
push bc ;new IP(PC)
skip2b_GETm16 ;bc=new CS
ld (_CS),bc ;new CS
countCS
pop de ;new IP(PC)
_LoopJP
;CALLFm1616
;GETr16
;какой сегмент???
CALLrmmem16
;UNTESTED
ld h,b
ld l,c
_CALLrmmem16q
decodePC
ex de,hl ;new IP(PC)
ld b,h
ld c,l ;=old IP(PC)
putmemspBC
_LoopC_JP
CALLFm1616mem ;высчитывается эффективный адрес, и с этого адреса берутся 4 байта (ip:cs)
UNTESTED
;уже прочитано 2 байта bc из (hl), но hl не сдвинут
push bc ;new IP(PC)
skip2b_GETm16 ;bc=new CS
push bc
;push cs; push ip (адрес после команды)
ld bc,(_CS) ;old CS
putmemspBC
pop bc
ld (_CS),bc ;new CS
countCS
pop hl ;new IP(PC)
jp _CALLrmmem16q
ALIGNrm
IMULr16rmi8
UNTESTED
get
next
;a=MDregR/M
;MD=00: imul reg16,[...],i8
;MD=01: imul reg16,[...+disp8],i8
;MD=10: imul reg16,[...+disp16],i8
;MD=11: imul reg16,r/m,i8 ;проще всего
push af
cp 0b11000000
jp c,IMULr16rmmemi8
ADDRr16_nokeepa
GETr16 ;bc=r/m
jr _IMULr16rmmem_geti8
IMULr16rmmemi8
ADDRm16_GETm16 ;bc=rmmem
_IMULr16rmmem_geti8
UNTESTED
get
next
push de
ld e,a
rla
sbc a,a
ld d,a
jr _IMULr16rmmem_go
ALIGNrm
IMULr16rmi16
UNTESTED
get
next
;a=MDregR/M
;MD=00: imul r16,[...],i16
;MD=01: imul r16,[...+disp8],i16
;MD=10: imul r16,[...+disp16],i16
;MD=11: imul r16,r/m,i16 ;проще всего
push af
cp 0b11000000
jp c,IMULr16rmmemi16
ADDRr16_nokeepa
GETr16 ;bc=r/m
jr _IMULr16rmmem_geti16
IMULr16rmmemi16
ADDRm16_GETm16 ;bc=rmmem
_IMULr16rmmem_geti16
getHL
push de
ex de,hl
_IMULr16rmmem_go
call IMUL_bc_de_to_hlde
ld b,d
ld c,e
pop de
pop af
rra
rra
and 7*2
ld l,a ;reg16 addr
ld h,_AX/256
_PUTr16LoopC ;TODO без ld a,l
ALIGNrm
XCHGr16rm
;UNTESTED
get
next
;a=MDregR/M
;MD=00: xchg reg16,[...]
;MD=01: xchg reg16,[...+disp8]
;MD=10: xchg reg16,[...+disp16]
;MD=11: xchg reg16,r/m ;проще всего
cp 0b11000000
jr c,XCHGr16rmmem
GOOD
ADDRr16_keepa ;rm addr
push hl
GETr16 ;bc=r/m
rra
rra
and 7*2
ld l,a ;reg16 addr
;ld h,_AX/256 ;уже есть в ADDRr16_keepa
SWAPr16
jp _pophl_PUTr16Loop_
XCHGr16rmmem
UNTESTED
ADDRm16_GETm16_for_PUTm16
push hl
rra
rra
and 7*2
ld l,a ;reg16 addr
ld h,_AX/256
SWAPr16
jp _pophl_PUTm16LoopC
ALIGNrm
XCHGr8rm
;UNTESTED
get
next
;a=MDregR/M
;MD=00: xchg reg8,[...]
;MD=01: xchg reg8,[...+disp8]
;MD=10: xchg reg8,[...+disp16]
;MD=11: xchg reg8,r/m ;проще всего
cp 0b11000000
jr c,XCHGr8rmmem
GOOD
ADDRr8 ;rm addr
ld b,(hl) ;b=r/m
push hl
or 0b11000000
ld l,a
;ld h,_AX/256 ;есть в ADDRr8
ld l,(hl) ;reg8 addr
ld a,(hl)
ld (hl),b
pop hl
_PUTr8Loop_
XCHGr8rmmem
UNTESTED
ADDRm16_GETm8c_for_PUTm8
push hl
or 0b11000000
ld l,a
ld h,_AX/256
ld l,(hl) ;reg8 addr
ld a,(hl)
ld (hl),c
pop hl
_PUTm8aLoopC_oldpglx
display "muls size=",$-beginmuls