#include cc.def/1 extern int xsp; extern int glbflag; /* Begin a comment line for the assembler */ comment() { outbyte(';'); } /* Print all assembler info before any code is generated */ header() { comment(); outstr("small-c compiler rev 2.0(mod 1)"); nl(); } /* Print any assembler stuff needed after all code */ trailer() { int saddr; if(glbflag == 0) return; /* no trailer if no globals */ saddr = getlabel(); ot("XEQ "); printlabel(saddr); nl(); printlabel(saddr); col(); nl(); ol("lxi sp,0"); ol("call rdparam"); ol("call ArgSetup"); /* to pass parm line to main */ ol("lhld ccArgc"); ol("push h"); ol("lxi h,ccArgv"); ol("push h"); ol("call main"); ol("call SYS"); ol("DB RETOP"); ol("nlst"); ol("copy setup.a"); ol("copy C80LIB.A"); ol("lst"); } /* Fetch a static memory cell into the primary register */ getmem(sym) char *sym; { if((sym[ident]!=pointer)&(sym[type]==cchar)) {ot("LDA "); outstr(sym+name); nl(); call("ccsxt"); } else {ot("LHLD "); outstr(sym+name); nl(); } } /* Fetch the address of the specified symbol */ /* into the primary register */ getloc(sym) char *sym; { int *off; immed(); off = &sym[offset]; outdec( *off -xsp); nl(); ol("DAD SP"); } /* Store the primary register into the specified */ /* static memory cell */ putmem(sym) char *sym; { if((sym[ident]!=pointer)&(sym[type]==cchar)) {ol("MOV A,L"); ot("STA "); } else ot("SHLD "); outstr(sym+name); nl(); } /* Store the specified object type in the primary register */ /* at the address on the top of the stack */ putstk(typeobj) char typeobj; { pop(); if(typeobj==cchar) { ol("MOV A,L"); ol("STAX D"); } else call("ccpint"); } /* Fetch the specified object type indirect through the */ /* primary register into the primary register */ indirect(typeobj) char typeobj; { if(typeobj==cchar) { ol("MOV L,M"); ol("MVI H,0"); } else call("ccgint"); } /* Swap the primary and secondary registers */ swap() { ol("XCHG"); } /* Print partial instruction to get an immediate value */ /* into the primary register */ immed() { ot("LXI H,"); } /* Push the primary register onto the stack */ push() { ol("PUSH H"); xsp=xsp-2; } /* Pop the top of the stack into the secondary register */ pop() { ol("POP D"); xsp=xsp+2; } /* Swap the primary register and the top of the stack */ swapstk() { ol("XTHL"); } /* Call the specified subroutine name */ call(sname) char *sname; { ot("CALL "); outstr(sname); nl(); } /* Return from subroutine */ ret() { ol("RET"); } /* Perform subroutine call to value on top of stack */ callstk() { immed(); outstr("$+2"); /*CHANGED FROM $+5 FOR PTDOS ASSM */ nl(); swapstk(); ol("PCHL"); xsp=xsp+2; } /* Jump to specified internal label number */ jump(label) int label; { ot("JMP "); printlabel(label); nl(); } /* Test the primary register and jump if false to label */ testjump(label) int label; { ol("MOV A,H"); ol("ORA L"); ot("JZ "); printlabel(label); nl(); } /* Print pseudo-op to define a byte */ defbyte() { ot("DB "); } /*Print pseudo-op to define storage */ defstorage() { ot("DS "); } /* Print pseudo-op to define a word */ defword() { ot("DW "); } /* Modify the stack pointer to the new value indicated */ modstk(newsp) int newsp; { int k; k=newsp-xsp; if(k==0)return newsp; if(k>=0) {if(k<7) {if(k&1) {ol("INX SP"); k--; } while(k) {ol("POP B"); k=k-2; } return newsp; } } if(k<0) {if(k>-7) {if(k&1) {ol("DCX SP"); k++; } while(k) {ol("PUSH B"); k=k+2; } return newsp; } } swap(); immed();outdec(k);nl(); ol("DAD SP"); ol("SPHL"); swap(); return newsp; } /* Double the primary register */ doublereg() { ol("DAD H"); } /* Add the primary and secondary registers */ /* (results in primary) */ add() { ol("DAD D"); } /* Subtract the primary register from the secondary */ /* (results in primary) */ sub() { call("ccsub"); } /* Multiply the primary and secondary registers */ /* (results in primary */ mult() { call("ccmult"); } /* Divide the secondary register by the primary */ /* (quotient in primary, remainder in secondary) */ div() { call("ccdiv"); } /* Compute remainder (mod) of secondary register divided */ /* by the primary */ /* (remainder in primary, quotient in secondary) */ mod() { div(); swap(); } /* Inclusive 'or' the primary and the secondary registers */ /* (results in primary) */ or() {call("ccor");} /* Exclusive 'or' the primary and seconday registers */ /* (results in primary) */ xor() {call("ccxor");} /* 'And' the primary and secondary registers */ /* (results in primary) */ and() {call("ccand");} /* logical and operation for && operator */ land() { call ("ccland"); } /* land */ /* Arithmetic shift right the secondary register number of */ /* times in primary (results in primary) */ asr() {call("ccasr");} /* Arithmetic left shift the secondary register number of */ /* times in primary (results in primary) */ asl() {call("ccasl");} /* Form two's complement of primary register */ neg() {call("ccneg");} /* Form one's complement of primary register */ com() {call("cccom");} /* Increment the primary register by one */ inc() {ol("INX H");} /* Decrement the primary register by one */ dec() {ol("DCX H");} /* Following are the conditional operators */ /* They compare the secondary register against the primary */ /* and put a literal 1 in the primary if the condition is */ /* true, otherwise they clear the primary register */ /* Test for equal */ eq() {call("cceq");} /* Test for not equal */ ne() {call("ccne");} /* Test for less than (signed) */ lt() {call("cclt");} /* Test for less than or equal to (signed) */ le() {call("ccle");} /* Test for greater than (signed) */ gt() {call("ccgt");} /* Test for greater than or equal to (signed) */ ge() {call("ccge");} /* Test for less than (unsigned) */ ult() {call("ccult");} /* Test for less than or equal to (unsigned) */ ule() {call("ccule");} /* Test for greater than (unsigned) */ ugt() {call("ccugt");} /* Test for greater than or equal to (unsigned) */ uge() {call("ccuge");} /* <<<<< End of compiler >>>>> */