#define ADC8(a,b) do{a=(a&255)+(b&255)+C; C=a>>8; a&=255;}while(0)
#define ADD16(a,b) do{a=(a&65535)+(b&65535); C=a>>16; a&=65535;}while(0)
//вход:
//BC - делитель, должен быть в диапазоне от 256 до 32768
//DE = -BC
//HL - два байта делимого минус BC, |HL+BC|<BC
//выход:
//A - HL*256/BC
//HL - HL*256%BC-BC
void div_8080(int &a,int &bc, int &de,int &hl){
int C=0;
ADD16(hl,hl); ADD16(hl,bc); if(C) goto S1;
A1: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S2;
A2: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S3;
A3: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S4;
A4: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S5;
A5: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S6;
A6: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S7;
A7: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S8;
A8: ADC8(a,a);
return;
S1: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A2;
S2: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A3;
S3: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A4;
S4: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A5;
S5: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A6;
S6: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A7;
S7: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A8;
S8: ADC8(a,a); ADD16(hl,de);
return;
}
//bb делитель от 256 до 32768
//aa - делимое, aa<65536*bb
void div_32_16(int aa, int bb){
int a,bc,de,hl,C;
hl=aa>>16;//старшие два байта делимого
bc=bb;//делитель
de=-bb&0xFFFF;//-делитель
ADD16(hl,de);//корректируем старшие два байта, потому что деление работает с отрицательным остатком
div_8080(a,bc,de,hl);//делим 256*HL на BC
//PUSH BC
bc=(aa>>8)&255; //перед делением модифицируем данную команду LXI, чтобы загрузить предпоследний байт делимого
ADD16(hl,bc); //суммируем предпоследний байт делимого с остатком
bc=bb;//POP BC
if(C){//если остаток стал положительным, то корректируем остаток и старший байт частного
ADD16(hl,de);
++a;
}
printf("%3X",a);//старший байт частного
div_8080(a,bc,de,hl);//делим дальше
de=aa&255;//перед делением модифицируем данную команду LXI, чтобы загрузить младший байт делимого
ADD16(hl,de);//суммируем младший байт делимого с остатком
if(C)//если стал положительным, то корректируем младший байт частного, иначе корректируем остаток
++a;
else
ADD16(hl,bc);
printf("%02X",a);
printf("%4X",hl);
}