home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------- */
- /* Copyright (C) 1991 by Natürlich! */
- /* This file is copyrighted! */
- /* Refer to the documentation for details. */
- /* ---------------------------------------------------------------------- */
- /* Code that tokenizes and differentiates between MACRO calls and */
- /* real life 6502 assembler mnemos. Also tokenizes directives */
-
- #if OS == MSDOS
- # define _brk xbrk
- #endif
-
-
- /* These are all the characters that happen to appear in 6502 mnemos */
- extern byte
- _adc[],_and[],_asl[],_bcc[],_bcs[],_beq[],_bit[],_bmi[],_bne[],
- _bpl[],_bra[],_brk[],_bvc[],_bvs[],_clc[],_cld[],_cli[],_clv[],
- _cmp[],_cpx[],_cpy[],_dea[],_dec[],_dex[],_dey[],_eor[],_ina[],
- _inc[],_inx[],_iny[],_jmp[],_jsr[],_lda[],_ldx[],_ldy[],_lsr[],
- _nop[],_ora[],_pha[],_php[],_phx[],_phy[],_pla[],_plp[],_plx[],
- _ply[],_rol[],_ror[],_rti[],_rts[],_sbc[],_sec[],_sed[],_sei[],
- _sta[],_stx[],_sty[],_stz[],_tax[],_tay[],_trb[],_tsb[],_tsx[],
- _txa[],_txs[],_tya[];
-
- /* -------------------------------------------------------------- */
- /* We use the first character of the instruction (or macro call) */
- /* to decide on a (struct instr) that happens to keep the remain- */
- /* ing two letters. If a match is made, a alphabetically index is */
- /* sent over. */
- /* [this looked pretty fast in the beginning, but...] */
- /* -------------------------------------------------------------- */
- #if BIGENDIAN
- # define drop( b, a) ( ((word) (a) << 8) | (word) (b))
- #else
- # define drop( a, b) ( ((word) (a) << 8) | (word) (b))
- #endif
-
- #define EOA { 0, 0 }
-
- struct instr
- {
- word d;
- byte huge *tab;
- };
-
- static struct instr
- a_[] =
- {
- { drop('D','C'), _adc }, { drop('N','D'), _and },
- { drop('S','L'), _asl }, EOA
- },
- b_[] =
- {
- { drop('C','C'), _bcc }, { drop('C','S'), _bcs },
- { drop('E','Q'), _beq }, { drop('I','T'), _bit },
- { drop('M','I'), _bmi }, { drop('N','E'), _bne },
- { drop('P','L'), _bpl }, { drop('R','K'), _brk },
- { drop('R','A'), _bra }, { drop('V','C'), _bvc },
- { drop('V','S'), _bvs }, EOA
- },
- c_[] =
- {
- { drop('L','C'), _clc }, { drop('L','D'), _cld },
- { drop('L','I'), _cli }, { drop('L','V'), _clv },
- { drop('M','P'), _cmp }, { drop('P','X'), _cpx },
- { drop('P','Y'), _cpy }, EOA
- },
- d_[] =
- {
- { drop('E','A'), _dea }, { drop('E','C'), _dec },
- { drop('E','X'), _dex }, { drop('E','Y'), _dey }, EOA
- },
- e_[] =
- {
- { drop('O','R'), _eor }, EOA
- },
- i_[] =
- {
- { drop('N','A'), _ina }, { drop('N','C'), _inc },
- { drop('N','X'), _inx }, { drop('N','Y'), _iny }, EOA
- },
- j_[] =
- {
- { drop('M','P'), _jmp }, { drop('S','R'), _jsr }, EOA
- },
- l_[] =
- {
- { drop('D','A'), _lda }, { drop('D','X'), _ldx },
- { drop('D','Y'), _ldy }, { drop('S','R'), _lsr }, EOA
- },
- n_[] =
- {
- { drop('O','P'), _nop }, EOA
- },
- o_[] =
- {
- { drop('R','A'), _ora }, EOA
- },
- p_[] =
- {
- { drop('H','A'), _pha }, { drop('H','P'), _php },
- { drop('H','X'), _phx }, { drop('H','Y'), _phy },
- { drop('L','A'), _pla }, { drop('L','P'), _plp },
- { drop('L','X'), _plx }, { drop('L','Y'), _ply }, EOA
- },
- r_[] =
- {
- { drop('O','L'), _rol }, { drop('O','R'), _ror },
- { drop('T','I'), _rti }, { drop('T','S'), _rts }, EOA
- },
- s_[] =
- {
- { drop('B','C'), _sbc }, { drop('E','C'), _sec },
- { drop('E','D'), _sed }, { drop('E','I'), _sei },
- { drop('T','A'), _sta }, { drop('T','X'), _stx },
- { drop('T','Y'), _sty }, { drop('T','Z'), _stz }, EOA
- },
- t_[] =
- {
- { drop('A','X'), _tax }, { drop('A','Y'), _tay },
- { drop('R','B'), _trb }, { drop('S','B'), _tsb },
- { drop('S','X'), _tsx }, { drop('X','A'), _txa },
- { drop('X','S'), _txs }, { drop('Y','A'), _tya }, EOA
- },
-
- *i_arr[] =
- {
- (struct instr *) 0, a_, b_, c_, d_, e_, i_,
- j_, l_, n_, o_, p_, r_, s_, t_
- };
-
- /* Indexes for the Instruction_ARRay, note that i_arr[0] = 0 */
- static int
- starters[] =
- {
- /* 0 1 2 3 4 5 6 7 8 9 : ? @ */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- /* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
- 1,2,3,4,5,0,0,0,6,7,0,8,0,9,10,11,0,12,13,14,0,0,0,0,0,0,
- /* _ */
- 0,0,0,0,0
- };
-
- macro_suckin()
- {
- register byte *p = (byte *) yytext,
- c_ = c,
- *p_table = is_what;
- register word i = 1;
-
- ENTER("macro_suckin");
- #if VERSION && FINPUT_IO && QINPUT_IO && QMACRO
- {
- register byte huge *pt = bp->p;
- register byte *tab = _uptable;
- register lword rem = bp->remain;
-
- while( tis_ident( c_))
- {
- *p++ = c_;
- c_ = quinput( rem, pt, tab);
- i++;
- }
- if( bp)
- {
- bp->remain = rem;
- bp->p = pt;
- }
- }
- #else
- while( tis_ident(c_)) /* Suck in macro call or */
- { /* instruction */
- *p++ = c_; /* convert to upper & save */
- c_ = uinput(); /* get fresh input */
- i++;
- }
- #endif
- *p = 0;
- c = c_;
- p = (byte *) yytext; /* (*) */
- IMESS("Macro/Instr.: %s", (lword) p, 4);
-
- if( i == 4)
- {
- register struct instr huge *q;
-
- if( q = i_arr[ starters[ *p - '0']]) /* instr ? */
- {
- #if WORD_EVEN
- p++;
- c_ = p[1]; /* looks very possible al- */
- i = ((word) *p << 8) | c_; /* beit not certain */
- #else
- i = *(word *) &yytext[ 1];
- #endif
- IMESS("two chars together %4lX", (lword) i, 4);
- do
- if( i == q->d)
- {
- yylval = (lword) q->tab; /* Yup. Send index & token */
- LEAVE();
- return( T_INSTR);
- }
- while( (++q)->d);
- i = 4;
- }
- }
- yy_txt2val( i);
- state = AFTERELSE;
- LEAVE();
- return( T_IDENT); /* It's a MACRO call */
- }
-
- /* -------------------------------------------------------------------- */
- /* There are only that few people who use directives often. So here */
- /* speed isn't of that much importance. */
- /* -------------------------------------------------------------------- */
- #define AF AFTERFLOAT
- #define AI AFTERINCLUDE
- #define AO AFTEROPTION
- #undef EOA
- #define EOA { "", 0, 0 }
-
- struct direc
- {
- char *string;
- int token, state;
- };
-
- static struct direc
- da_[] =
- {
- { "AND", T_AND, 0 }, EOA
- },
- db_[] =
- {
- { "BYTE", T_BYTE, 0 }, EOA
- },
- dc_[] =
- {
- { "CALL", T_CALL, 0 }, { "CBYTE", T_CBYTE, 0 }, EOA
- },
- dd_[] =
- {
- { "DBYTE", T_DBYTE, 0 }, { "DEF", T_DEF, 0 },
- { "DS", T_DS, 0 }, EOA
- },
- de_[] =
- {
- { "ELSE", T_ELSE, 0 }, { "END", T_END, 0 },
- { "ENDIF", T_ENDIF, 0 }, { "ENDM", T_ENDM, 0 },
- { "EQU", '=', 0 }, { "ERROR", T_ERROR, 0 }, EOA
- },
- df_[] =
- {
- { "FLOAT", T_FLOAT, AF }, EOA
- },
- di_[] =
- {
- { "IF", T_IF, 0 }, { "INCLUDE",T_INCLUDE, AI }, EOA
- },
- dl_[] =
- {
- { "LOCAL", T_LOCAL, 0 }, EOA
- },
- dm_[] =
- {
- { "MACRO", T_MACRO, 0 }, EOA
- },
- dn_[] =
- {
- { "NOT", T_NOT, 0 }, EOA
- },
- do_[] =
- {
- { "OPT", T_OPT, AO}, { "OR", T_OR, 0 },
- { "ORG", T_ORG, 0 }, EOA
- },
- dp_[] =
- {
- { "PAGE", T_PAGE, 0 }, EOA
- },
- dr_[] =
- {
- { "REF", T_REF, 0 }, { "REPT", T_REPT, 0 }, EOA
- },
- ds_[] =
- {
- { "SBYTE", T_SBYTE, 0 }, { "SET", T_SET, 0 }, EOA
- },
- dt_[] =
- {
- { "TAB", T_TAB, 0 }, { "TITLE", T_TITLE, 0 }, EOA
- },
- du_[] =
- {
- { "UNDEF", T_UNDEF, 0 }, EOA
- },
- dv_[] =
- {
- { "VFL_BOCHUM", T_ZEXT, 0},EOA
- },
- dw_[] =
- {
- { "WARNING", T_WARN, 0 }, { "WORD", T_WORD, 0 }, EOA
- },
- dz_[] =
- {
- { "ZEXT", T_ZEXT, 0 }, EOA
- },
-
- *d_arr[] =
- {
- (struct direc *) 0, da_, db_, dc_, dd_, de_, df_, di_, dl_,
- dm_, dn_, do_, dp_, dr_, ds_, dt_, du_, dv_, dw_, dz_
- };
-
- /* Indexes for the Instruction_ARRay, note that i_arr[0] = 0 */
- static int
- dstarters[] =
- {
- /* 0 1 2 3 4 5 6 7 8 9 : ? @ */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- /* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
- 1,2,3,4,5,6,0,0,7,0,0,8,9,10,11,12,0,13,14,15,16,17,18,0,0,19,
- /* _ */
- 0,0,0,0,0
- };
-
- directive_suckin()
- {
- register char *p = yytext,
- c_ = c,
- *p_table = (char *) is_what;
-
- ENTER("directive_suckin");
- if( (c_ = uinput()) == '=') /* is .= ?? */
- fdreturn( T_DOTEQ);
- *p++ = '.';
- #if VERSION && FINPUT_IO && QINPUT_IO && QDIRECT
- {
- register byte huge *pt = bp->p;
- registe byte *tab = _uptable;
- register lword rem = bp->remain;
-
- do
- *p++ = c_;
- while( tis_ident( c_ = quinput( rem, pt, tab)));
- if( bp)
- {
- bp->remain = rem;
- bp->p = pt;
- }
- }
- #else
- do
- *p++ = c_; /* convert to upper & save */
- while( tis_ident(c_ = uinput()));
- #endif
- c = c_;
- *p = 0;
- p = yytext + 1;
- {
- register struct direc *q;
-
- if( q = d_arr[ dstarters[ *p - '0']]) /* get directive start */
- do
- if( ! strcmp( q->string, p))
- {
- if( q->state)
- state = q->state;
- dreturn( q->token);
- }
- while( (++q)->string);
- }
- lsyntax("unknown directive");
- }
-
-
- struct opt
- {
- char *name;
- int token;
- };
-
- static struct opt
- options[] =
- {
- { "NO", T_NO },
- { "OBJ", T_OBJ },
- { "LIST", T_LIST },
- { "MLIST", T_MLIST },
- { "CLIST", T_CLIST },
- { "EJECT", T_EJECT },
- { "ERR", T_ERR },
- { "NUM", T_NUM },
- { "XREF", T_XREF },
- { "", 0 }
- };
-
-
- option_suckin()
- {
- register struct opt huge *q = options;
- register char *p = yytext;
-
- while( is_letter(c))
- {
- *p++ = c;
- c = uinput();
- }
- *p = 0;
-
- while( q->token)
- {
- if( ! strcmp( yytext, q->name))
- return( q->token);
- q++;
- }
- lsyntax("unknown option");
- }
-
- /* (*)
- Turbo-C very cleverly (no irony this time) compiles the "-'0'" as a
- negative offset for the LEA. Therefore this isn't wasting any time
- at least on the ST. Else a 256 word array would be better
- */
-