home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1986 / 10 / camplst.oct next >
Text File  |  1986-10-31  |  33KB  |  1,196 lines

  1.  
  2. Listing One
  3.  
  4. /*  
  5. .ll 79
  6.     A Z80 - N320XX translator
  7.     R. A. Campbell - 03/26/86
  8.     TNZH.C - header/global definitions
  9. */
  10.  
  11. #define    BANNER    ";Z80 - NS320XX Translater; RAC 03/26/86\n"
  12.  
  13. #define    NOPCDS    70    /* number of opcodes/registers in table */
  14.  
  15. #define    FGERR    0            /* error or eof fgets return */
  16. #define    CR            0x0d    /* cpm new/line */
  17. #define    COMMBEG        ';'        /* comment marker */
  18. #define    SYMBEND        ':'        /* end of symbol, fluff */
  19. #define    LETTER        'a'
  20. #define    DIGIT        '0'
  21. #define    SPACE        ' '        /* space (or tab) */
  22. #define MAXCODE        150        /* maximum bytes / line of code */
  23. #define    MAXWORD        10
  24.  
  25.  
  26. /* opcode types */
  27. #define    TMASK        0xF000    /* mask to opcode-type */
  28. #define    ISFLG        0xF000    /* is a conditional flag */
  29. #define ISREG        0xE000    /* is a register */
  30. #define    ISSPC        0xD000    /* is a special operation */
  31. #define    ISPBIT        0xA000    /* is a PSR bit operation */
  32. #define    ISBIT        0x9000    /* is a bit operation */
  33. #define    BYTEPS        0x8000    /* is a byte/word pseudo-op */
  34.  
  35. #define    ENDPS        0x7000    /* end pseudo-op */
  36. #define    ISMOV        0x5000    /* is a move instruction */
  37. #define    NOOPRS        0x4000    /* no fancy operands */
  38. #define    ISRET        0x3000    /* is a return instruction */
  39. #define    ISBSR        0x2000    /* is a call/BSR */
  40. #define    ISBR        0x1000    /* is a branch */
  41. #define    NADST        0x0800    /* operation needs destination- B,A */
  42. #define    NASRC        0x0400    /* needs a source */
  43. #define    NAONE        0x0200    /* needs a one, 0=-1, 1=+1 */
  44. #define    ISPRB        0x0100    /* is a problem translation */
  45. #define    ISPOS        0x0008    /* is a +1 */
  46. #define    ISREV        0x0004    /* operands reversed */
  47. /* operand modifiers */
  48. #define    ISPAR        0x0080    /* operand is parenthesized */
  49. #define    ISSYM        0x0040    /* operand is a symbol */
  50.  
  51. /* opmod's */
  52. #define    ISCMP        0x8000    /* is a compare operation */
  53. #define    ISARI        0x4000    /* is an arithmetic oper */
  54. #define    ISXXX        0x2000    /* is call/branch, ?? */
  55. #define    ISNOT        0x1000    /* is a nothing; mov */
  56.  
  57. /* Following are pseudo ops */
  58. #define    BEGINPS        0x64    /* begin procedure */
  59. #define    BLKPS        0x66    /* space block define */
  60. #define    EQUPS        0x70    /* equ pseudo-op */
  61. #define    LOCPS        0x76    /* LOC pseudo-op */
  62. #define    PROCPS        0x78    /* procedure definition */
  63.  
  64. #define    WORDPS        0x7e    /* define a word - 2 bytes */
  65.  
  66.  
  67. #define    SETCFG        0x080e    /* setcfg opcode */
  68.  
  69. char    **argv,            /* input arg pointer */
  70.     symfound,            /* switch for tree finds */
  71.     innamebf[14],        /* for assembling file name */
  72.     outnamebf[14],        /* for output file */
  73.     switbuf[10],        /* for assembling switches */
  74.     wordbuf[MAXWORD+2],    /* for incoming words */
  75.     linebuf[130],        /* incoming line buffer */
  76.     codebuf[130],    /* for output produced */
  77.     tmpbuf[18],        /* temporary buffer */
  78.  
  79.     symsave[18],    /* to save symbol equ's */
  80.  
  81.     opcsave[18],    /* save opcode */
  82.     errorbuf[18],    /* to save errors */
  83.  
  84.     *allocp,        /* next free position */
  85.     symstart,        /* for symbol table start */
  86.     *allocend,        /* last free position */
  87.     cparenth,        /* parenthesis count */
  88.     cerror,            /* current error, if any */
  89.  
  90.     swstinit,        /* initialize, make code, static variables */
  91.     swsym,            /* switch to insert symbol */
  92.     swdebug,        /* debug switch */
  93.     swlist,            /* listing output switch */
  94.     swoutput,        /* output code switch */
  95.     swsymbol;        /* symbol table switch */
  96.  
  97. #ifdef    Z80
  98. char    inbuf[BUFSIZ],        /* for incoming disk data */
  99.     outbuf[BUFSIZ];        /* for output */
  100. #define    long    int
  101.  
  102. #else
  103.  
  104. #define    unsigned    long
  105. #define    inbuf    infd
  106. #define    outbuf    outfd
  107.  
  108. #endif
  109.  
  110. /* integer variables */
  111. int    argc,            /* calling argument count */
  112.     curfile,        /* for counting source files */
  113.     c, t,            /* for actual text characters */
  114.     csize,            /* current data size */
  115.     cursym,            /* current symbol number */
  116.     lsttype,        /* for last instr type */
  117.  
  118.     infd,            /* input file open */
  119.     outfd,            /* output file descriptor */
  120.     copr,            /* index for current operand */
  121.  
  122.     copclass,        /* for current opcode class */
  123.  
  124.     coptype,        /* current opcode type, class AND F000h */
  125.     copmod,            /* for current opcode modifier */
  126.     inbcount,        /* input byte count / pointer */
  127.  
  128.     nlines,            /* for number of lines processed */
  129.  
  130.     passno,            /* pass number */
  131.  
  132.     i, x, xx,        /* miscelaneous transient variables */
  133.     n,            /* counting number for searches */
  134.  
  135.     nerrors,        /* error count */
  136.  
  137.     bquit;            /* set if need to quit */
  138.  
  139. struct    oprs            /* for operands */
  140. {    char    opr[12];        /* for operator */
  141.     int        ofl;        /* for opclass */
  142.  
  143.     int        opm;        /* for op-mods */
  144. }    oprt[4];            /* table for operands */
  145.  
  146. struct key            /* for opcodes */
  147. {    char     inword[6];        /* in-opcode  */
  148.     char    outword[8];        /* out-opcode */
  149.     int        opclass;
  150.     int        opmod;        /* operator modifier */
  151. }    keytab[NOPCDS];
  152.  
  153. /* end of global definitions 03/26/86 */
  154.  
  155.  
  156.  
  157.  
  158.  
  159. /*
  160. .ll 79
  161.     TNZ.C    Translator; NS-320XX from Z80
  162.     by R. A. Campbell, 03/26/86 - main file
  163.     clink TNZ, TNZ2; TNZH= header, TNZO= opcodes
  164. */
  165.  
  166. /* for Z80, uncomment following
  167. */
  168. #define    Z80    1
  169. #include    "bdscio.h"
  170. /* for non-Z80, uncomment following
  171. #include    "niohe.c"
  172. */
  173. /* always */
  174. #include    "tnzh.c"
  175.  
  176. #ifdef    Z80
  177. main( rgc, rgv )
  178. char    *rgc;
  179. char    **rgv;
  180. #else
  181. main( rgc, rgv, mbeg )
  182. char    *rgc;
  183. char    **rgv;
  184. char    *mbeg;
  185. #endif
  186. {    argc = rgc;                /* this foolishness */
  187.     argv = rgv;                /* to get argc,argv as globals */
  188. #ifdef    Z80
  189.     allocp = endext ();            /* initialize free position */
  190.     allocend = topofmem () - 500;        /* allow for stack */
  191. #else
  192.     allocp = mbeg;
  193.     allocend = &rgc - 500;
  194. #endif
  195.     initas ();                /* go initialize */
  196.     printf("  Translating;%9s Options; %s\n", argv[1], switbuf);
  197.     nlines = 0;
  198.     passno = 1;                /* set for first pass */
  199.     doscan ();                /* scan file */
  200. }
  201.  
  202. doscan()                    /* scan input file(s) */
  203. {    curfile = 1;
  204.     nerrors = 0;
  205.     while ( curfile < argc )
  206.     {    strcpy (innamebf,argv[curfile++]);    /* get file name */
  207.         strcat (innamebf,".Z80");
  208. #ifdef    Z80
  209.         if ((infd = fopen (innamebf,inbuf)) == ERROR )
  210. #else
  211.         if (( infd = fopen (innamebf, "R")) == ERROR )
  212. #endif
  213.         {    printf (" Unable to open: %s\n", innamebf);
  214.             exit ();
  215.         }                    /* else, keep going */
  216.         if ( curfile == 2 )            /* gets ++'d above */
  217.             dostart ();
  218.         symsave[0] = 0;
  219.         lsttype = bquit = 0;
  220.         while ( bquit == 0 )
  221.         {    rdline ();        /* get & read the line */
  222.             ++nlines;
  223.             if ( copclass != 0 || symsave[0] != 0 )
  224.                 doline ();        /* to operand(s) */
  225.             if ( t == COMMBEG || cerror != 0 )
  226.             {    if ( t == COMMBEG )    /* else is a \n */
  227.                     chrcat (codebuf, t );
  228.                 if ( t == COMMBEG )
  229.             {while (( t = typeof ((c= getchr ()) )) != '\n' )
  230.                     chrcat (codebuf, c );
  231.                 }
  232.                 if ( cerror != 0 )
  233.                 {    ++nerrors;
  234.                     strcat ( codebuf, ";???");
  235.                 }
  236.             }
  237.             chrcat (codebuf, '\r' );    /* for CP/M */
  238.             chrcat (codebuf, '\n');
  239.             if ( swlist != 0 )
  240.                 listout ();        /* listing output */
  241.             outcode ();
  242.             if (( xx = ( copmod & 0xef00 )) != 0 )
  243.         {if (( copclass & 0xfff0 ) == 0x4200    /* is dec/inc */
  244.                     && csize == 'W' )
  245.                     ; /* ignore, is dec/inc hl, etc. */
  246.                 else
  247.                     lsttype = xx;    /* copy last type */
  248.             }
  249.         }                    /* bquit != 0 */
  250.         dofinish ();
  251.         if ( fclose (inbuf) == -1)
  252.                 printf("\n Unable to close file \n");
  253.     }        /* end of one file */
  254. }        /* end of doscan */
  255.  
  256. rdline()                    /* read line */
  257. {    quitck ();                /* see if should quit */
  258.     csize = i = inbcount = copmod = 0;
  259.     copr = cerror = coptype = copclass = 0;    /* impossible opclass */
  260.     codebuf[0] = opcsave[0] = 0;
  261.     oprt[copr].opr[0] = oprt[copr].ofl = 0;
  262.     if ( fgets (linebuf,inbuf) == FGERR )    /* get a line */
  263.     {    printf ("Unable to Read: %s\n", innamebf );
  264.         bquit++;            /* out of file */
  265.         return;                /* done with file */
  266.     }
  267.     if (( t = getword ( )) == '\n' || t == COMMBEG)
  268.         return;            /* empty line */
  269.     if ( t != SPACE )
  270.         rdsymbol ();        /* read symbol, if there */
  271.     while (( t = getword ( ) ) == SPACE
  272.       || t == SYMBEND )        /* walk to 1st non-space */
  273.             ;        /* skip spaces, tabs */
  274.     if ( t == '\n' || t == 0 || t == COMMBEG )
  275.         return;
  276.     rdopcode ();            /* read opcode, if any */
  277.     if ( t == '\n' || t == 0 || t == COMMBEG )
  278.         return;
  279.     rdoperands ();            /* read operand(s) */
  280. }
  281.  
  282. rdsymbol()                /* do symbol, if present */
  283. {    if (t == LETTER)        /* is symbol */
  284.     {    if ( symsave[0] != 0 )    /* have one hanging */
  285.             strcat ( symsave, "\r\n" );
  286.         strcat (symsave,wordbuf);    /* copy through */
  287.         chrcat ( symsave, ':' );    /* add colon */
  288.     }
  289. }
  290.  
  291. rdopcode()                /* read opcode, if any */
  292. {    if ( t != LETTER )
  293.         return;
  294.     cwdbftl ();
  295.     if ( ( n = binary ( wordbuf) ) >= 0 )
  296.     {     copclass = keytab[n].opclass;
  297.         coptype = copclass & TMASK;
  298.         copmod = keytab[n].opmod;
  299.         strcat (opcsave, keytab[n].outword);
  300.         if (( copclass & ISPRB) != 0 )
  301.             ++cerror;        /* is problem opcode */
  302.         if ( coptype == ENDPS )
  303.             ++bquit;
  304.     }
  305.     else
  306.     {    strcat (opcsave,wordbuf);
  307.         copclass = NOOPRS;    /* put something in */
  308.         ++cerror;        /* unknown opcode */
  309.     }
  310. }
  311.  
  312. rdoperands()                /* read operands */
  313. {
  314.  
  315. oprnew:                    /* clear flags */
  316.     cparenth = 0;
  317. oprcont:
  318.     switch (( t = getword () ) )    /* see what it is */
  319.     { case LETTER:            /* see if is symbol or register */
  320.         strcpy ( tmpbuf, wordbuf );    /* save */
  321.         cwdbftl ();            /* convert to lower case */
  322.         if ( ( n = binary ( wordbuf ) ) >= 0
  323.           && ( keytab[n].opclass & ISREG) == ISREG )    /* reg-flag */
  324.         {    oprt[copr].opm = keytab[n].opmod;
  325.             xx =  keytab[n].opclass;
  326.             oprt[copr].ofl |= xx;
  327.             if ( xx == 0xe052 )
  328.                 strcpy ( oprt[copr].opr, keytab[n].outword );
  329.             else
  330.                 strcat (oprt[copr].opr, keytab[n].outword );
  331.             if (( xx & ISPRB ) != 0 )
  332.                 ++cerror;
  333.             if ( (xx & TMASK) == ISREG    /* is register only */
  334.               && csize == 0 )        /* 1st size, dest */
  335.             {    xx &= 3;        /* strip to size */
  336.                 if ( xx == 1 )
  337.                     csize = 'B';
  338.                 else if ( xx == 2 )
  339.                     csize = 'W';
  340.             }
  341.         }
  342.         else
  343.         {    strcpy ( oprt[copr].opr,tmpbuf );
  344.             oprt[copr].ofl |= ISSYM;    /* mark as symbol */
  345.         }
  346.         goto oprcont;
  347.     case DIGIT:
  348.         chrcat (oprt[copr].opr, c );
  349.     while (( t = typeof (( c = getchr ()))) == DIGIT || t == LETTER )
  350.             chrcat ( oprt[copr].opr, c );
  351.         ugetch ();
  352.         goto oprcont;
  353.     case '(':
  354.         oprt[copr].ofl |= ISPAR;    /* mark as paren, fall thru */
  355.         chrcat (oprt[copr].opr, c);    /* symbol will overwrite */
  356.         goto oprcont;
  357.     case '+':
  358.     case '-':
  359.         if (( oprt[copr].ofl & (ISPAR|ISREG)) == (ISPAR|ISREG) )
  360.         {    oprt[copr].ofl |= ISPOS;    /* final paren */
  361.             chrcat ( oprt[copr].opr, ')' );    
  362.         }    /* have an (IX+?), make (IX)+/- ? */
  363.         chrcat (oprt[copr].opr, c);        /* copy through */
  364.         goto oprcont;
  365.     case ')':
  366.     if (( oprt[copr].ofl & 0xff78) == ISREG ) /* not if EX (SP),?? */
  367.         chrcat (oprt[copr].opr, c); /* not; (IY+), (SP) copy */
  368.         goto oprcont;
  369.     case ''':            /* ASCII string/char, transfer */
  370.         chrcat (oprt[copr].opr, c );
  371.         if (( c = getchr ()) == ''' )    /* have a '''? */
  372.             chrcat ( oprt[copr].opr, c );
  373.         else
  374.             ugetch ();            /* no, go back */
  375.         while (( c = getchr ()) != ''' )
  376.             chrcat ( oprt[copr].opr, c );    /* put in ASCII */
  377.         chrcat ( oprt[copr].opr, c );    /* put in terminating ''' */
  378.         goto oprcont;
  379.     case SPACE:                /* ignore it */
  380.         goto oprcont;
  381.     case ',':        /* to permit mixes of strings and bytes */
  382.         if ( coptype == BYTEPS )
  383.         {    chrcat (oprt[copr].opr, c );
  384.             goto oprcont;
  385.         }
  386.         else
  387.             goto oprend;
  388.     case '\n': case COMMBEG:
  389.             return;            /* done */
  390.     default:
  391.         chrcat (oprt[copr].opr, c );    /* copy char */
  392.         goto oprcont;
  393.     }                    /* end of switch t */
  394. oprend:
  395.     if ( copr == 3 )
  396.         return;                /* done!!!! */
  397.     ++copr;                    /* inc current operand */
  398.     oprt[copr].opr[0] = 0;
  399.     oprt[copr].ofl = 0;            /* clear out next oprt's */
  400.     goto oprnew;
  401. }
  402.  
  403. doline()                    /* put out operands */
  404. {    i = 0;
  405.     dosym ();
  406.     chrcat ( codebuf, '\t' );        /* tab over */
  407.     spcchk ();                /* check for special operations */
  408.     if ( coptype == ISSPC )
  409.         dospcs ();            /* do special operations */
  410.     else if ( coptype <= ISRET )        /* program flow oper */
  411.         doprfl ();
  412.     else
  413.         doarmov ();            /* arith/move operation */
  414.     if ( i != 0 )
  415.         chrcat ( codebuf, '\t' );
  416. }
  417.  
  418. dosym()
  419. {    i = 0;
  420.     if ( symsave[0] != 0 )
  421.     {    strcpy ( codebuf, symsave );
  422.         symsave[0] = 0;            /* null for next time */
  423.     }
  424. }
  425.  
  426. spcchk()        /* check for special operations, check size */
  427. {    if ( copr == 0 )
  428.     {    if ( coptype == ISBR )
  429.       {    if ( (oprt[0].ofl & TMASK) == ISREG )
  430.         /* compute absol addrs */
  431.         {    strcat ( codebuf, "ADDR    Q_start,R7\r\n" );
  432.             strcat ( codebuf, "\tADD.D    R7," );
  433.             if ( oprt[0].opm == 12 )
  434.                 strcat ( codebuf, "R3" );
  435.             else if ( oprt[0].opm == 13 )
  436.                 strcat ( codebuf, "R4" );
  437.             else
  438.                 strcat ( codebuf, "R5" );
  439.             strcat ( codebuf, "\r\n\t" );
  440.             coptype = NOOPRS; /* don't add "R" to opcode */
  441.             strcpy ( opcsave, "JUMP" );    /* go do armov */
  442.         }
  443.         else if ( oprt[0].ofl == 0 )    /* is an absolute jump */
  444.         {    coptype = NOOPRS; /* don't add "R" to opcode */
  445.             strcpy ( opcsave, "JUMP" );
  446.         }
  447.       }    /* end of ISBR */
  448.         else if ( coptype == ISPBIT )
  449.         {    if (( xx = copmod & 0xf ) == 1 )
  450.             {    csize = 'B';
  451.                 strcpy ( oprt[0].opr, "1" ); /* carry bit */
  452.             }
  453.             else if ( xx = 12 )
  454.             {    csize = 'W';
  455.                 strcpy ( oprt[0].opr, "800H" );    /* intrupt */
  456.             }
  457.         }
  458.         else if (( copclass & 0xf3ff ) == 0x4032 )    /* push/pop */
  459.         {    csize = 'D';            /* double size */
  460.             if ( oprt[copr].ofl == 0xE031 )    /* push/pop AF */
  461.             {    copclass &= 0x0f0f;    /* strip type */
  462.                 copclass |= 0xd032; /* special#3, W-size */
  463.                 coptype = ISSPC;
  464.                 csize = 'B';    /* 2-byte, 1-word push/pops */
  465.             }
  466.         }
  467.         else if ( (oprt[0].ofl & ISPAR ) != 0 )
  468.             csize = 'B';    /* something (HL) */
  469.     }                /* end of copr == 0 */
  470.     else                /* copr != 0 */
  471.     {    xx = oprt[1].ofl & 3;
  472.         if (( x = oprt[0].ofl & 3 ) != 0
  473.           && xx != 0 )             /* two sizes */
  474.         {    if (x != xx )        /* two different sizes */
  475.             csize = 'B';
  476.         }
  477.         else if ( xx == 2 && (oprt[1].ofl & ISPAR ) != 0 )
  478.             csize = 'B';
  479.         else if ( x == 2 && (oprt[0].ofl & ISPAR ) != 0 )
  480.             csize = 'B';
  481.         /* is LD HL,SYMB? */
  482.         if ( ( copclass & ISREV ) != 0 )
  483.         {    strcpy ( tmpbuf, oprt[0].opr );
  484.             strcpy ( oprt[0].opr, oprt[1].opr );
  485.             strcpy ( oprt[1].opr, tmpbuf );    /* reverse operands */
  486.         }
  487.         if ( coptype == ISMOV && x == 2 && oprt[1].ofl == ISSYM )
  488.         {    csize = 0;
  489.             strcpy ( opcsave, "ADDR" );    /* need address */
  490.         }
  491.         if ( coptype != ISSPC && oprt[0].ofl == 0xe052 )
  492.             /* move to R7 */
  493.         {    strcat ( codebuf, "SPR.D    SP,R7\r\n\t" );    
  494.             strcat ( codebuf, opcsave );    /* do to R7 */
  495.             if ( csize != 0 )        /* is ADDR? */
  496.                 strcat ( codebuf, ".W" );
  497.             chrcat (codebuf, 9 );        /* tab */
  498.             strcat ( codebuf, oprt[1].opr );
  499.             strcat ( codebuf, ",R7\r\n\t" );
  500.             strcpy ( oprt[0].opr, "R7" );    /* do to R7 */
  501.             csize = 'D';            /* make long */
  502.             strcpy ( opcsave, "LPR" );    /* > LPR.W SP,?? */
  503.             strcpy ( oprt[1].opr, "SP" );    /* is now TOS */
  504.         }    /* above is a LD/ADD SP,?? - not an EX */
  505.         else if ( coptype != ISSPC &&  oprt[1].ofl == 0xe052 )
  506.         {    if ( coptype == ISMOV )        /* is an ld ??,sp */
  507.             {    strcpy ( opcsave, "SPR" ); /* > SPR.D SP,?? */
  508.                 csize = 'D';        /* make long */
  509.                 strcpy ( oprt[1].opr, "SP" ); /* is now TOS */
  510.             }
  511.             else        /* is an add ??,sp */
  512.     {strcat ( codebuf, "SPR.D    SP,R7\r\n\t" );    /* move to R7 */
  513.     strcpy ( oprt[1].opr, "R7" );    /* change operand */
  514.             }
  515.         }
  516.  
  517.     }
  518. }
  519.  
  520. dospcs()            /* do special operations */
  521. {    int    sptype;
  522.     if ((sptype=( copclass & 0x00f0) ) == 0x0010 )    /* is an EX DE,HL */
  523.     {    strcat ( codebuf, "MOV.D\t");        /* or EX (SP),?? */
  524.         strcat ( codebuf, oprt[0].opr );
  525.         strcat ( codebuf, ",R7\r\n\t");
  526.         csize = 'D';                /* make long */
  527.         doarmov ();
  528.         strcat ( codebuf, "\r\n\tMOV.D\tR7,");
  529.         strcat ( codebuf, oprt[1].opr );
  530.         chrcat ( codebuf, '\t');
  531.     }
  532.     else if ( sptype == 0x0030 )            /* is a push/pop AF */
  533.     {    if (( copclass & NADST ) != 0 )        /* is a push AF */
  534.     {strcat (codebuf, "MOVQ.W    0,TOS\r\n\t" );    /* two bytes */
  535.             doarmov ();        /* then push 'A', then PSR */
  536.             strcat (codebuf, "\r\n\tSPR.B\tPSR,TOS");
  537.         }    /* push AF so if pop BC, A > B */
  538.         else        /* is pop AF; A > B,D,H; PSR > C,E,L */
  539.         {    strcat (codebuf, "AND.B\t0xfd,TOS\r\n\t");
  540.             strcat (codebuf, "LPR.B\tPSR,TOS\r\n\t");
  541.             doarmov ();            /* now pop 'A' */
  542.             strcat ( codebuf, "\r\n\t");        
  543.             strcat (codebuf, "MOV.W    TOS,R7" );/* two bytes */
  544.         }    /* strip 'T' bit , then pop; C,E,L into PSR */
  545.     }
  546.      else
  547.         doarmov ();        /* so get something */
  548. }
  549.  
  550. doarmov()
  551. {    if ( opcsave[0] != 0 )
  552.     {    ++i;            /* have something */
  553.         strcat ( codebuf, opcsave );
  554.         if ( csize == 0        /* have no size */
  555.           && (copclass & (NASRC|NADST)) != 0 )    /* should have */
  556.             csize = 'B';
  557.         if ( csize != 0 )
  558.         {    chrcat ( codebuf, '.' );
  559.             chrcat ( codebuf, csize );
  560.         }
  561.         chrcat ( codebuf, '\t' );
  562.     }
  563.     xx = copr;
  564.     while ( xx != 0 )
  565.     {    strcat ( codebuf, oprt[xx].opr );
  566.         chrcat ( codebuf, ',' );
  567.         --xx;
  568.     }
  569.     if ( copr == 0 )
  570.     {    if ((copclass & NAONE ) != 0 )
  571.         {    if ((copclass & ISPOS ) != 0 )    /* ADDQ/ASH +1, */
  572.                 strcat (codebuf, "+1");
  573.             else                /* ADDQ/ASH/ACB -1 */
  574.                 strcat (codebuf, "-1");
  575.             if (( copclass & NADST ) == 0 )
  576.                 chrcat ( codebuf, ',' ); /* dont need 2 */
  577.         }
  578.         if (( copclass & NASRC ) != 0 )
  579.         {    if (( x = copclass & 3 ) == 3 )
  580.                 strcat ( codebuf, "RB" ); /* djnz */
  581.             if ( x == 2 )
  582.                 strcat ( codebuf, "TOS" );
  583.             else if ( x == 1 )
  584.                 strcat ( codebuf, "R0");
  585.             if (( copclass & NADST )== 0 || oprt[xx].opr[0] != 0)
  586.                 chrcat ( codebuf, ',' ); /* dont need 2 */
  587.         }
  588.     }
  589.     if ( oprt[xx].opr[0] != 0 )
  590.         strcat ( codebuf, oprt[xx].opr );
  591.     if ( copr == 0 && ( copclass & NADST) != 0 )
  592.     {    if ((copclass & 3 ) == 2 )
  593.             strcat ( codebuf, ",TOS" );
  594.         else
  595.             strcat ( codebuf, ",R0" );
  596.     }
  597. }
  598.  
  599. doprfl()
  600. {    ++i;            /* have something */
  601.     if ( coptype == ISRET && oprt[0].opr[0] != 0 )
  602.         dofprfl ();            /* have a cond return */
  603.     else if ( coptype == ISBSR && copr != 0 )
  604.         dofprfl ();            /* have a cond call */
  605.     else    /* have uncond call, return or cond. BR; handle here */
  606.     {    if ( copr != 0 )    /* have a conditional BR */
  607.         {    i = oprt[0].ofl & 7;
  608.             docond ( i + 10 );
  609.             strcat ( codebuf, tmpbuf ); /* copy docond */
  610.         }
  611.         else
  612.         {    strcat ( codebuf, opcsave );
  613.             if ( coptype == ISBR )    /* have only a 'B' */
  614.                 chrcat ( codebuf, 'R' );
  615.         }
  616.         chrcat ( codebuf, '\t' );
  617.         if ( oprt[copr].opr[0] != 0 )
  618.             strcat ( codebuf, oprt[copr].opr );
  619.         else    /* have a unconditional ret */
  620.             lsttype = 0;    /* clear last-type */
  621.     }
  622. }
  623.  
  624. /* on conditional calls or returns, perform test (reversed)
  625.     over call or return, put in branch symbol.
  626.     ie;
  627.     CALL    Z,SYMB
  628.     becomes;
  629.     BNE    XYZ#
  630.     BSR    SYMB
  631. XYZ#:
  632. */
  633. dofprfl()                /* do fancy program-flow */
  634. {
  635.     i = oprt[0].ofl & 7;        /* isolate condition */
  636.     docond ( i );            /* do the conditional */
  637.     strcat ( codebuf, tmpbuf );    /* now put in */
  638.     strcat ( codebuf, "\t" );        /* do short branch */
  639.     sprintf ( tmpbuf, "XYZ%d",++cursym );    /* put in branch destination */
  640.     strcat (codebuf, tmpbuf );
  641.     strcat ( codebuf, "\r\n" );        /* new line */
  642.     chrcat ( codebuf, '\t' );        /* tab over */
  643.     strcat ( codebuf, opcsave );    /* put out opcode */
  644.     if ( coptype == ISBSR )        /* have a conditional call*/
  645.     {    chrcat ( codebuf, '\t' );
  646.         strcat ( codebuf, oprt[copr].opr );
  647.     }
  648.     strcat (symsave, tmpbuf );    /* put in for next line */
  649.     chrcat ( symsave, ':' );    /* add colon */
  650. }
  651. /*    i's 1 to 6 = comp flags reversed.
  652.     10 - 16 = comp flags
  653.     20 - 26 = arithm flags reversed.
  654.     30 - 36 = arithm flags.
  655.     Remember, Z-80 comps are; A vs ??, NS are ?? vs R0,
  656.     Ie., reversed.
  657. */
  658. docond( cond )
  659. int    cond;
  660. {    i = cond % 10;                /* see what is */
  661.     if ( lsttype == ISARI )
  662.     {    if ( i == 1 || i == 2 )        /* is a C, NC test */
  663.             cond += 20;        /* make arithmet test */
  664.         else                /* do zero, sign test */
  665.         strcat (codebuf,"CMPQ.B    0,R0\r\n\t");    /* compare */
  666.     }
  667.     else if ( lsttype != ISXXX && lsttype != ISCMP )
  668.     {    strcat (codebuf,"CMPQ.B    0,R0\r\n\t");    /* compare */
  669.     }
  670.     chrcat ( codebuf, 'B' );    /* OK to put in now */
  671.     switch ( cond )
  672.     {    case    1:        /* are for reversed compar flags */
  673.             strcpy (tmpbuf,"LS");    /* orig=C > LS */
  674.             break;
  675.         case    2:
  676.             strcpy (tmpbuf,"HI");    /* orig=NC > HI */
  677.             break;
  678.         case    3:
  679.             strcpy (tmpbuf,"NE");    /* orig=Z > NE */
  680.             break;
  681.         case    4:
  682.             strcpy (tmpbuf,"EQ");    /* orig=NZ > EQ */
  683.             break;
  684.         case    5:
  685.             strcpy (tmpbuf,"LE");    /* orig=M > LE 0 */
  686.             break;
  687.         case    6:
  688.             strcpy (tmpbuf,"GT");    /* orig=P > GT 0 */
  689.             break;
  690.         case    11:        /* are for direct cmp flags */
  691.             strcpy (tmpbuf,"HI");    /* orig=C > HI */
  692.             break;
  693.         case    12:
  694.             strcpy (tmpbuf,"LS");    /* orig=NC > LS */
  695.             break;
  696.         case    13:
  697.             strcpy (tmpbuf,"EQ");    /* orig=Z > NE */
  698.             break;
  699.         case    14:
  700.             strcpy (tmpbuf,"NE");    /* orig=NZ > EQ */
  701.             break;
  702.         case    15:
  703.             strcpy (tmpbuf,"GT");    /* orig=M > GT 00H */
  704.             break;
  705.         case    16:
  706.             strcpy (tmpbuf,"LE");    /* orig=P > LE 00H */
  707.             break;
  708.         case    21:        /* are for reversed arith flags */
  709.             strcpy (tmpbuf,"CC");    /* orig=C > CC */
  710.             break;
  711.         case    22:
  712.             strcpy (tmpbuf,"CS");    /* orig=NC > CS */
  713.             break;
  714.         case    31:        /* are direct arith flags */
  715.             strcpy (tmpbuf,"CS");    /* orig=C > CS */
  716.             break;
  717.         case    32:
  718.             strcpy (tmpbuf,"CC");    /* orig=NC > CC */
  719.             break;
  720.         default:
  721.             strcpy ( tmpbuf,"??");
  722.             ++cerror;
  723.     }
  724. }
  725.  
  726. chrcat( ptr, chr )            /* character concatenate */
  727. char    *ptr;
  728. char    chr;
  729. {
  730.     while ( *ptr != 0)
  731.         ++ptr;            /* go to null */
  732.     *ptr++ = chr;
  733.     *ptr = 0;
  734. }
  735.  
  736. /*    end of TNZ.C        03/26/86, R. A. Campbell */
  737.  
  738.  
  739.  
  740.  
  741.  
  742. /*
  743. .ll 79
  744.     TNZ2.C I/O routines and utilities
  745.     TNZH.C    is header/definitions,
  746.     TNZO.C    is opcode/register table
  747.     for Z80 to NS-320XX Translater
  748.     CLINK - TNZ, TNZ2 -    R. A. Campbell; 03/26/86
  749. */
  750.  
  751. /*     If Z80,  uncomment following two lines
  752. */
  753. #define    Z80 1
  754. #include    "bdscio.h"
  755. /* if not Z80, uncomment following line
  756. #include    "niohe.c"
  757. */
  758. /* always; */
  759. #include    "tnzh.c"
  760.  
  761. initas()            /* check input mode, open disk files */
  762. {    int    lnum;        /* declare local n */
  763.     printf(BANNER);
  764.     if (argc < 2)
  765.     {    printf(" Aborting;  No Filename(s) specified \n");
  766.         exit ();
  767.     }
  768.     switbuf[0] = 0;        /* rescue switches */
  769.     if (  *argv[argc-1] == '-' )
  770.     {    strcpy (switbuf,argv[argc-1]);
  771.         argc--;        /* decrm arg count */
  772.     }
  773.     i = swlist = swsymbol = swdebug = bquit = 0;
  774.     cursym = swstinit = 0;
  775.     swoutput = 'M';
  776.     if (( t = switbuf[i++] ) != 0 )
  777.     {    while ( ( t = switbuf[i++] ) != 0 )
  778.         {    switch ( t )
  779.             { case '0':    /* turn off all switches */
  780.                 {    swsymbol = swlist = NULL;
  781.                     swoutput = swdebug = NULL;
  782.                     break;
  783.                 }
  784.             case 'D':    /* CP/M capitalizes */
  785.                 {    swsymbol = swlist = swdebug = t;
  786.                     swoutput = 0;
  787.                     break;
  788.                 }
  789.             case 'L':    /* listing output */
  790.                 swlist = t;
  791.                 break;
  792.             case ',':
  793.                 break;        /* walk over commas */
  794.             default:
  795.                 badswitch ();
  796.             }
  797.         }
  798.     }
  799.     if ( swoutput != 0 )            /* are to output? */
  800.         {    strcpy (outnamebf,argv[1]); /* setup output name */
  801.             strcat (outnamebf,".N32");  /* translated output */
  802. #ifdef    Z80
  803.             if (( outfd = fcreat (outnamebf,outbuf)) == ERROR )
  804. #else
  805.             if (( outfd = fopen (outnamebf, "W" )) == ERROR )
  806. #endif
  807.             {    printf (" Unable to open: %s\n", outnamebf);
  808.                 exit ();
  809.             }
  810.         }
  811. #ifdef    Z80
  812.     if ((infd = fopen ("TNZO.C",inbuf)) == ERROR )
  813. #else
  814.     if ((infd = fopen ("TNZO.C", "R")) == ERROR)
  815. #endif
  816.         {    printf ("Unable to open Table File\n");
  817.             exit ();
  818.         }
  819.     lnum = 0;
  820.     while ( bquit == NULL && (fgets (linebuf,inbuf) != FGERR )
  821.             && (lnum < NOPCDS))    /* chck one line of opcd table */
  822.     {    inbcount = 0;                /* start line */
  823.         t = getword ( );
  824.         if (t == LETTER)
  825.         {    strcpy ( keytab[lnum].inword, wordbuf);
  826.             while ( getword () == SPACE )    /* ignore tab/space */
  827.                 ;            /* next word */
  828.             strcpy ( keytab[lnum].outword, wordbuf);
  829.             keytab[lnum].opclass = getint ();
  830.             keytab[lnum].opmod = getint ();
  831.             lnum++;
  832.         }
  833.     }                    /* keep reading file */
  834.     if ( infd = fclose (inbuf) == -1 )    /* close file */
  835.         printf("\n Unable to close OPC file \n");
  836. }
  837.  
  838. badswitch()
  839. {    printf( "Incorrect switches; %s \n", switbuf);
  840.     printf(" Must start with a '-', minus\n");
  841.     printf("Choices are; 0= no outputs, errors only;\n");
  842.     printf(" D= debug; L= listing;\n");
  843.     exit ();
  844. }
  845.  
  846. #ifdef    Z80
  847. quitck()            /* check for user quitting */
  848. {    char    c;
  849.     if ( kbhit () )        /* character waiting? */
  850.     {    c = getchar ();
  851.         if ( c < ' ' )    /* a control char ? */
  852.             exit ();
  853.     }
  854. }
  855. #endif
  856.  
  857. listout()                /* printouts for listing */
  858. {    x = 0;
  859.     if ( swdebug != 0 )
  860.     {    printf ("I= ");        /* indicat input text */
  861.         printf("%s",linebuf);    /* print source text */
  862.         printf ("O= ");        /* indicate output */
  863.     }
  864.     printf("%s",codebuf);        /* print source text */
  865. }
  866.  
  867. chnpage()    /* increment line count, new page?? */
  868. {
  869. }
  870.  
  871. outcode()                /* output code */
  872. {    if ( swoutput == 0 )
  873.         return;            /* not to output */
  874.     i = 0;
  875.     while ( codebuf[i] != 0 )
  876.     {    if ( putc ( codebuf[i++] , outbuf ) == ERROR )
  877.         {    printf("\n Aborting; Write Error \n");
  878.             exit ();
  879.         }
  880.     }
  881. }
  882.  
  883. dostart()                /* output id stuff at beginning of file */
  884. {    pout ( BANNER );        /* identify translation */
  885.     pout ( "\tSTATIC 0" );    /* RA is in real R4; safe, comparison */
  886.     pout ( "RC:    BYTE" );    /* stored high - low, reverse */
  887.     pout ( "RB:    BYTE" );    /* make longs, if pointer */
  888.     pout ( "    WORD" );    /* for pointers */
  889.     pout ( "RE:    BYTE" );
  890.     pout ( "RD:    BYTE" );
  891.     pout ( "    WORD" );    /* for pointers */
  892.     pout ( "RL:    BYTE" );
  893.     pout ( "RH:    BYTE" );
  894.     pout ( "    WORD" );    /* for pointers */
  895.     pout ( "RX:    LONG" );
  896.     pout ( "RY:    LONG" );
  897.     pout ( "\tPROGRAM" );
  898.     pout ( "Q_start:\tJUMP    Q_shell" );
  899.     pout ( "\tIMPORT    Q_shell" );    /* nlint puts in # */
  900.     pout ( "Qmain:" );        /* for linking & (HL) jumps */
  901. }
  902.  
  903. pout ( ptr )
  904. char    *ptr;
  905. {    strcpy ( codebuf, ptr);
  906.     strcat ( codebuf, "\r\n" );
  907.     if ( swdebug != 0 || swlist != 0 )
  908.         printf ( "%s", codebuf );
  909.     outcode ();        
  910. }
  911. dofinish()
  912. {
  913.     for ( x = 0; x<128; ++x )
  914.         putchr (CPMEOF);
  915.     fflush ( outbuf );
  916.     fclose ( outbuf );
  917.     printf (" %d Lines Processed, %d Problems\n", nlines, nerrors );
  918. }
  919.  
  920. binary( sptr )    /* find word in keytab[0] .. tab [n-1] */
  921. char *sptr;
  922. {    register long low, high, mid, cond;
  923.     low    = 0;
  924.     high = NOPCDS -1;
  925.     while (low <= high)
  926.     {    mid = (low + high) / 2;
  927.         if (( cond = strcmp( sptr, keytab[mid].inword)) < 0)
  928.             high = mid -1;
  929.         else if (cond > 0)
  930.             low = mid + 1;
  931.         else
  932.             return mid;
  933.     }
  934.     return -1;
  935. }
  936.  
  937. putchr( chr )
  938. char    chr;
  939. {    if ( putc ( chr,outbuf ) == ERROR )
  940.     {    printf("\n Write Error \n");
  941.         fclose ( outbuf );
  942.         exit ();
  943.     }
  944. }
  945.  
  946. getint()            /* get integer from input */
  947. {    int    val, ishex, sign;
  948.     unsigned valh;
  949.     char    c;
  950.     ishex = val = valh = 0;
  951.     sign    = 1;
  952.     while ( (c = getchr ()) == ' ' || c == '\t' )
  953.         ;        /* skip white space */
  954.     ugetch ();        /* back up */
  955.     if ( c == '+' )
  956.         ;        /* ignore it */
  957.     else if ( c == '-' )
  958.         sign = -1;
  959.     if ( isdigit (c) == 0 )
  960.         return valh;
  961.     while ( isdigit (c = getchr () ) 
  962.         || (( c = toupper (c)-7) > '9' && c < '@')
  963.         || c == 'X'-7 || c == 'H'-7 )    /* is digit/H,X */
  964.         {    if ( c == 'X'-7 || c == 'H'-7 )                ishex = 1;
  965.             else
  966.             {    val = val * 10 + c - '0';
  967.                 valh=(valh<<4) + c-'0';
  968.             }
  969.         }
  970.     if ( ishex != 0 )
  971.         return valh;
  972.     val *= sign;
  973.     return val;
  974. }
  975.  
  976. cwdbftl()        /* convert word buffer to lower case */
  977. {    x = 0;
  978.     while ( ( c = wordbuf[x] ) != 0 )
  979.     {    if (c >= 'A' && c <= 'Z') /* conv upper to lower */
  980.         wordbuf[x] = c + 32;
  981.         x++;
  982.     }
  983. }
  984.  
  985. getword( )            /* get word from input */
  986. {    char    *w;        /* put in wordbuf */
  987.     int lim,    t;
  988.     lim = MAXWORD;
  989.     w = wordbuf;
  990.     if ( ( t = typeof ( *w++ = c = getchr () ) ) != LETTER) 
  991.     {    *w = '\0';
  992.         return t;
  993.     }
  994.     while (--lim > 0)
  995.     {    t = typeof ( *w++ = c = getchr () );
  996.         if ( t != LETTER && t != DIGIT 
  997.           && t != '.' && t != '_' )
  998.         {    ugetch ();
  999.             break;
  1000.         }
  1001.     }
  1002.     *( w-1 ) = '\0';
  1003.     if ( cerror == 0 )        /* copy for error report */
  1004.         strcpy (errorbuf, wordbuf );
  1005.     if ( lim > 0 )
  1006.         return LETTER;
  1007.     while ( t = typeof ( getchr () ) == LETTER || t == DIGIT )
  1008.         ;            /* walk over rest of word */
  1009.     ugetch ();
  1010.     return LETTER ;
  1011. }
  1012.  
  1013. ugetch()
  1014. {    inbcount--;
  1015. }
  1016.  
  1017. getchr()        /* get character from disk file */
  1018. {    int        c;
  1019.     c = getdin ();    /* get input from disk file */
  1020.     if ( c == 0 || c == EOF || c == CPMEOF )
  1021.     {    c = '\n';    /* new line */
  1022.         bquit++;
  1023.     }
  1024.     return ( c );
  1025. }
  1026.  
  1027. getdin()            /* get character from disk file */
  1028. {    int    c;
  1029.     c = linebuf [inbcount++] & 0x7F;
  1030.     return c;
  1031. }
  1032.  
  1033. typeof(c)            /* return type of ASCII character */
  1034. char    c;
  1035. {    if ( c >= 'a' && c <= 'z') 
  1036.         return LETTER;
  1037.     else if ( c >= 'A' && c <= 'Z' )
  1038.         return LETTER;
  1039.     else if ( c >= '0' && c <= '9' )
  1040.         return DIGIT;            /* if digit */
  1041.     else if ( c == SPACE || c == '\t' )
  1042.         return SPACE;
  1043.     else if ( c == 0xa || c ==0xd )
  1044.         return '\n';            /* an end of line!!! */
  1045.     else
  1046.         return c;
  1047. }
  1048.  
  1049. /*    end TNZ2.C    03/26/86        */
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057. /* Input/ output opcodes for Z80 to NS320XX Translater, 
  1058.  
  1059. /* MUST BE IN ALPHABETICAL ORDER FOR BINARY SEARCH TO WORK
  1060. /* FIRST CHAR OF LINE MUST BE 'LETTER' OTHERWISE
  1061. /* LINE SKIPPED,  RAC  03/26/86. HAS 70 entries
  1062.  
  1063. /* classes are (all numbers in hex) */
  1064.  
  1065. /* TMASK =    0Xf000    -    mask for type of opc/operand */
  1066. /* ISFLG =    0XF000    -    is a flag */
  1067. /* ISREG =    0XE000    -    is a register */
  1068. /* ISSPC =    0XD000    -    is a special operation; EX, */
  1069. /* ISPBIT=    0XA000    -    is a PSR bit operation */
  1070. /* ISBIT =    0X9000    -    is a bit operation */
  1071. /* BYTEPS=    0X8000    -    define byte(s) */
  1072. /* ENDPS =    0X7000    -    end pseudo-operator */
  1073. /* ISMOV =    0X5000    -    is a ld/mov instruction */
  1074. /* NOOPRS =    0X4000    -    simple opcode, no fancy stuff */
  1075. /* these prog-flow must be from 0X1000 to 0X3000 */
  1076. /* ISRET =    0X3000    -    is a return instruction */
  1077. /* ISBSR =    0X2000    -    is a call/branch to subroutine */
  1078. /* ISBR     =    0X1000    -    is a branch/jump */
  1079. /* modifiers */
  1080. /* NADST =    0X0800    -    needs a destination */
  1081. /* NASRC =    0X0400    -    needs a source */
  1082. /* NAONE =    0X0200    -    needs a +1 or -1 */
  1083. /* ISPRB =    0X0100    -    may be a problem */
  1084. /* ISPOS =    0X0008    -    is a +1 */
  1085. /* ISREV =    0X0004    -    operands reversed */
  1086. /* opmod modifiers */
  1087. /* ISCMP =    0X8000    -    is a comparision, re flags */
  1088. /* ISARI =    0X4000    -    is an arithmetic */
  1089. /* ISXXX =    0X2000    -    is altering; call */
  1090. /* ISNOT =    0X1000    -    is a 'nothing' operation re flags */
  1091. /* ISLOG =    0X0800    -    is a logical operation */
  1092. /* Following are pseudo-ops  */
  1093.  
  1094.  
  1095.  
  1096. /* REGISTERS
  1097. /* Z-80    = NS-320XX
  1098. /* A, AF    = R0
  1099. /* C, BC    = R1
  1100. /* E, DE    = R2
  1101. /* L, HL    = R3
  1102. /* IX        = R4
  1103. /* IY        = R5 */
  1104.  
  1105. /* name - opcode - class - mod - comment    */
  1106.  
  1107. a    R0    0xe001    0x0000    /* single register, use R0 */
  1108. adc    ADDC    0x4801    0x4000    /* opcode + data byte */    
  1109. add    ADD    0x4801    0x4000    /* may need byte dest */
  1110. af    R0    0xe031    0x0000    /* double register, R0 & spc */
  1111. and AND    0x4801    0x0800
  1112.  
  1113. b    RB    0xe001    0x0000    /* register 'B' */
  1114. bc    R1    0xe002    0x0000    /* double register 'BC' */
  1115. bit    TBIT    0x4005    0x0000    /* test bit */
  1116.  
  1117. c    R1    0xe001    0x0000    /* register 'C', also carry flag */
  1118. call    BSR    0x2000    0x2000
  1119. ccf    BICPSR    0xa101    0x0001    /* compl carry flag, psr bit 1 */
  1120. cp    CMP    0x4801    0x8000
  1121. cpl    COM    0x4c01    0x0800
  1122.  
  1123. d    RD    0xe001    0x0000
  1124. de    R2    0xe002    0x0000    /* register */
  1125. dec    ADDQ    0x4200    0x4000    /* needs a -1 */
  1126. defb    BYTE    0x8000    0x1000    /* define byte(s) */
  1127. defi    WORD    0x8000    0x1000    /* define item(bytes reversed) */
  1128. defs    BLK.B    0x4000    0x1000    /* define space */
  1129. defw    WORD    0x8000    0x1000    /* define two-byte word */
  1130. di    BICPSR    0xa400    0x100c    /* clear psr bit indicated */
  1131. djnz    ACB    0x4603    0x1000    /* decrement B, jump if not zero */
  1132.  
  1133.  
  1134. e    R2    0xe001    0x0000
  1135. ei    BISPSR    0xa002    0x000c    /* set 12th bit */
  1136. end    END    0x7000    0x1000    /* pseudo op */
  1137. equ    EQU    0x4000    0x0000    /* pseudo op */
  1138. ex    MOV    0xd012    0x1000    /* special operation, word-size */
  1139. extrn    EXTRN    0x4000    0x0000
  1140.  
  1141. h    RH    0xe001    0x0000
  1142. halt    WAIT    0x4000    0x1000
  1143. hl    R3    0xe002    0x000c    /* register */
  1144.  
  1145. in    NOP    0x4100    0x0000
  1146. inc    ADDQ    0x4208    0x4000    /* needs a +1 */
  1147. ix    R4    0xe002    0x000d
  1148. iy    R5    0xe002    0x000e    /* IX, IY registers */
  1149.  
  1150. jp    B    0x1020    0x1000
  1151. jr    B    0x1020    0xl000
  1152.  
  1153. l    R3    0xe001    0x0000
  1154. ld    MOV    0x5000    0x1000
  1155. lddr    MOV    0xd091    0x8000
  1156. ldir    MOV    0xd071    0x8000    /* special, byte sized */
  1157. loff    LOFF    0x4000    0x1000    /* turn printer on/ off */
  1158. lon    LON    0x4000    0x1000    
  1159.  
  1160. m    LS    0xf105    0x0000
  1161.  
  1162. nc    CC    0xf102    0x0000
  1163. neg    NEG    0x4c01    0x0800
  1164. nop    NOP    0x4000    0x1000
  1165. nz    NE    0xf004    0x0000
  1166.  
  1167. or    OR    0x4801    0x0800
  1168. org    LOC    0x4000    0x0000    /* org pseudo-op */
  1169. out    NOP    0x4100    0x0000
  1170.  
  1171.  
  1172. p    HI    0xf106    0x0000
  1173. pop    MOV    0x4432    0x1000    /* needs source */
  1174. push    MOV    0x4832    0x1000    /* needs destination */
  1175.  
  1176. res    BIC    0x4005    0x1000
  1177. ret    RET 0x3000    0x1000
  1178. rl    ROT    0x4219    0x0800
  1179. rla    ROT    0x4b19    0x0800
  1180. rlc    ROT    0x4219    0x0800
  1181. rlca    ROT    0x4b19    0x0800
  1182. rr    ROT    0x4211    0x0800
  1183. rra    ROT    0x4b11    0x0800
  1184. rrca    ROT    0x4b11    0x0800
  1185.  
  1186. sbc    SUBC    0x4801    0x4000
  1187. scf    BISPSR    0xa001    0x4001    /* set carry bit  */
  1188. set    BIS    0x4005    0x1000
  1189. sp    TOS    0xe052    0x0000    /* privileged register */
  1190. sub    SUB    0x4801    0x4000
  1191.  
  1192. xor    XOR    0x4801    0x0800
  1193.  
  1194. z    EQ    0xf003    0x0000
  1195.  
  1196.