/* ** arithmetic routines prefaced with "zz" to keep M80 ** assembler from generating error msgs when this is compiled */ /* ** add primary and secondary registers (result in primary) */ zzadd() {ol("DAD D");} /* ** subtract primary from secondary register (result in primary) */ zzsub() {zzcall("CCSUB");} /* ** multiply primary and secondary registers (result in primary) */ zzmult() {zzcall("CCMULT");} /* ** divide secondary by primary register ** (quotient in primary, remainder in secondary) */ zzdiv() {zzcall("CCDIV");} /* ** remainder of secondary/primary ** (remainder in primary, quotient in secondary) */ zzmod() {zzdiv();swap();} /* ** inclusive "or" primary and secondary registers ** (result in primary) */ zzor() {zzcall("CCOR");} /* ** exclusive "or" the primary and secondary registers ** (result in primary) */ zzxor() {zzcall("CCXOR");} /* ** "and" primary and secondary registers ** (result in primary) */ zzand() {zzcall("CCAND");} /* ** logical negation of primary register */ lneg() {zzcall("CCLNEG");} /* ** arithmetic shift right secondary register ** number of bits given in primary register ** (result in primary) */ zzasr() {zzcall("CCASR");} /* ** arithmetic shift left secondary register ** number of bits given in primary register ** (result in primary) */ zzasl() {zzcall("CCASL");} /* ** two's complement primary register */ neg() {zzcall("CCNEG");} /* ** one's complement primary register */ com() {zzcall("CCCOM");} /* ** increment primary register by one object of whatever size */ inc(n) int n; { while(1) { ol("INX H"); if(--n < 1) break; } } /* ** decrement primary register by one object of whatever size */ dec(n) int n; { while(1) { ol("DCX H"); if(--n < 1) break; } } /* ** test for equal to */ zzeq() {zzcall("CCEQ");} /* ** test for equal to zero */ eq0(label) int label; { ol("MOV A,H"); ol("ORA L"); ot("JNZ "); printlabel(label); nl(); } /* ** test for not equal to */ zzne() {zzcall("CCNE");} /* ** test for not equal to zero */ ne0(label) int label; { ol("MOV A,H"); ol("ORA L"); ot("JZ "); printlabel(label); nl(); } /* ** test for less than (signed) */ zzlt() {zzcall("CCLT");} /* ** test for less than to zero */ lt0(label) int label; { ol("XRA A"); ol("ORA H"); ot("JP "); printlabel(label); nl(); } /* ** test for less than or equal to (signed) */ zzle() {zzcall("CCLE");} /* ** test for less than or equal to zero */ le0(label) int label; { ol("MOV A,H"); ol("ORA L"); ol("JZ $+8"); ol("XRA A"); ol("ORA H"); ot("JP "); printlabel(label); nl(); } /* ** test for greater than (signed) */ zzgt() {zzcall("CCGT");} /* ** test for greater than to zero */ gt0(label) int label; { ol("XRA A"); ol("ORA H"); ot("JM "); printlabel(label); nl(); ol("ORA L"); ot("JZ "); printlabel(label); nl(); } /* ** test for greater than or equal to (signed) */ zzge() {zzcall("CCGE");} /* ** test for gteater than or equal to zero */ ge0(label) int label; { ol("XRA A"); ol("ORA H"); ot("JM "); printlabel(label); nl(); } /* ** test for less than (unsigned) */ ult() {zzcall("CCULT");} /* ** test for less than to zero (unsigned) */ ult0(label) int label; { ot("JMP "); printlabel(label); nl(); } /* ** test for less than or equal to (unsigned) */ ule() {zzcall("CCULE");} /* ** test for greater than (unsigned) */ ugt() {zzcall("CCUGT");} /* ** test for greater than or equal to (unsigned) */ uge() {zzcall("CCUGE");} #ifdef OPTIMIZE peephole(ptr) char *ptr; { while(*ptr) { #ifdef TAB if(streq(ptr, "\tLXI H,0\n\tDAD SP\n\tCALL CCGINT")) { if(streq(ptr+30, "\tXCHG;;")) {pp2();ptr=ptr+38;} else {pp1();ptr=ptr+30;} } else if(streq(ptr, "\tLXI H,2\n\tDAD SP\n\tCALL CCGINT")) { if(streq(ptr+30, "\tXCHG;;")) {pp3(pp2);ptr=ptr+38;} else {pp3(pp1);ptr=ptr+30;} } else if(optimize) { if(streq(ptr, "\tDAD SP\n\tCALL CCGINT")) { ol("CALL CCDSGI"); ptr=ptr+21; } else if(streq(ptr, "\tDAD D\n\tCALL CCGINT")) { ol("CALL CCDDGI"); ptr=ptr+20; } else if(streq(ptr, "\tDAD SP\n\tCALL CCGCHAR")) { ol("CALL CCDSGC"); ptr=ptr+22; } else if(streq(ptr, "\tDAD D\n\tCALL CCGCHAR")) { ol("CALL CCDDGC"); ptr=ptr+21; } else if(streq(ptr, "\tDAD SP\n\tMOV D,H\n\tMOV E,L\n\tCALL CCGINT\n\tINX H\n\tCALL CCPINT")) { ol("CALL CCINCI"); ptr=ptr+59; } else if(streq(ptr, "\tDAD SP\n\tMOV D,H\n\tMOV E,L\n\tCALL CCGINT\n\tDCX H\n\tCALL CCPINT")) { ol("CALL CCDECI"); ptr=ptr+59; } else if(streq(ptr, "\tDAD SP\n\tMOV D,H\n\tMOV E,L\n\tCALL CCGCHAR\n\tINX H\n\tMOV A,L\n\tSTAX D")) { ol("CALL CCINCC"); ptr=ptr+64; } else if(streq(ptr, "\tDAD SP\n\tMOV D,H\n\tMOV E,L\n\tCALL CCGCHAR\n\tDCX H\n\tMOV A,L\n\tSTAX D")) { ol("CALL CCDECC"); ptr=ptr+64; } else if(streq(ptr, "\tDAD D\n\tPOP D\n\tCALL CCPINT")) { #ifdef M80 ol("CALL CCDDPI"); /* unique name in six characters */ #else /* M80 */ ol("CALL CCDDPDPI"); #endif /* M80 */ ptr=ptr+27; } else if(streq(ptr, "\tDAD D\n\tPOP D\n\tMOV A,L\n\tSTAX D")) { #ifdef M80 ol("CALL CCDDPC"); /* unique name in six characters */ #else /* M80 */ ol("CALL CCDDPDPC"); #endif /* M80 */ ptr=ptr+31; } else if(streq(ptr, "\tPOP D\n\tCALL CCPINT")) { ol("CALL CCPDPI"); ptr=ptr+20; } else if(streq(ptr, "\tPOP D\n\tMOV A,L\n\tSTAX D")) { ol("CALL CCPDPC"); ptr=ptr+24; } /* additional optimizing logic goes here */ #else /* TAB */ if(streq(ptr," LXI H,0\n DAD SP\n CALL CCGINT")) { if(streq(ptr+30, " XCHG;;")) {pp2();ptr=ptr+38;} else {pp1();ptr=ptr+30;} } else if(streq(ptr," LXI H,2\n DAD SP\n CALL CCGINT")) { if(streq(ptr+30, " XCHG;;")) {pp3(pp2);ptr=ptr+38;} else {pp3(pp1);ptr=ptr+30;} } else if(optimize) { if(streq(ptr, " DAD SP\n CALL CCGINT")) { ol("CALL CCDSGI"); ptr=ptr+21; } else if(streq(ptr, " DAD D\n CALL CCGINT")) { ol("CALL CCDDGI"); ptr=ptr+20; } else if(streq(ptr, " DAD SP\n CALL CCGCHAR")) { ol("CALL CCDSGC"); ptr=ptr+22; } else if(streq(ptr, " DAD D\n CALL CCGCHAR")) { ol("CALL CCDDGC"); ptr=ptr+21; } else if(streq(ptr, " DAD SP\n MOV D,H\n MOV E,L\n CALL CCGINT\n INX H\n CALL CCPINT")) { ol("CALL CCINCI"); ptr=ptr+59; } else if(streq(ptr, " DAD SP\n MOV D,H\n MOV E,L\n CALL CCGINT\n DCX H\n CALL CCPINT")) { ol("CALL CCDECI"); ptr=ptr+59; } else if(streq(ptr, " DAD SP\n MOV D,H\n MOV E,L\n CALL CCGCHAR\n INX H\n MOV A,L\n STAX D")) { ol("CALL CCINCC"); ptr=ptr+64; } else if(streq(ptr, " DAD SP\n MOV D,H\n MOV E,L\n CALL CCGCHAR\n DCX H\n MOV A,L\n STAX D")) { ol("CALL CCDECC"); ptr=ptr+64; } else if(streq(ptr, " DAD D\n POP D\n CALL CCPINT")) { #ifdef M80 ol("CALL CCDDPI"); /* unique name in six characters */ #else /* M80 */ ol("CALL CCDDPDPI"); #endif /* M80 */ ptr=ptr+27; } else if(streq(ptr, " DAD D\n POP D\n MOV A,L\n STAX D")) { #ifdef M80 ol("CALL CCDDPC"); /* unique name in six characters */ #else /* M80 */ ol("CALL CCDDPDPC"); #endif /* M80 */ ptr=ptr+31; } else if(streq(ptr, " POP D\n CALL CCPINT")) { ol("CALL CCPDPI"); ptr=ptr+20; } else if(streq(ptr, " POP D\n MOV A,L\n STAX D")) { ol("CALL CCPDPC"); ptr=ptr+24; } /* additional optimizing logic goes here */ #endif /* TAB */ else cout(*ptr++, output); } else cout(*ptr++, output); } } pp1() { ol("POP H"); ol("PUSH H"); } pp2() { ol("POP D"); ol("PUSH D"); } #ifdef FULLC pp3(pp) int (*pp)(); { ol("POP B"); (*pp)(); ol("PUSH B"); } #else /* FULLC */ pp3(pp) int pp; { ol("POP B"); pp(); ol("PUSH B"); } #endif /* FULLC */ #endif /* OPTIMIZE */