home *** CD-ROM | disk | FTP | other *** search
- #include <setjmp.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <ctype.h>
-
- #include "mselect.h" /*external selection of microprocessor symbol table*/
- #include "proto.h"
- #include "as.h"
- #include "structs.h"
- #include "riscos.h"
- #include "extvars.h"
-
- #define FATAL 2
- #define SERIOUS 1
- #define WARNING 0
- #define MAXERR 100
-
- /* Throwback routines Copyright © 1992 Niklas Röjemo */
-
- extern struct oper table[];
-
- int pedantic = 1;
-
- static int ThrowbackStarted;
- static char *Filename;
-
- static char errbuf[1024];
-
-
-
- /*
- * void errorInit(int throwback,char *np) { if(throwback) Filename =
- * CanonicalisePath(np); else Filename = 0; }
- */
-
- void
- errorInit(int throwback, char *np)
- {
- if (throwback)
- Filename = np;
- else
- Filename = 0;
- #ifdef DEBUG
- printf("filename = %s\n", np);
- #endif
- }
-
- void
- errorFinish(void)
- {
- if (ThrowbackStarted > 0) {
- ThrowbackStarted = 0;
- ThrowbackEnd();
- }
- }
-
- static void
- TB(int level, int lineno, char *error)
- {
- os_error *err;
- if (!Filename)
- return;
- if (!ThrowbackStarted) {
- err = ThrowbackStart();
- if (err) {
- fprintf(stderr, "ThrowbackStart %s\n", err->errmess);
- exit(-1);
- }
- err = ThrowbackSendStart(Filename);
- if (err) {
- if (pedantic)
- fprintf(stderr, "ThrowbackSendStart %s", err->errmess);
- ThrowbackStarted = -1;
- } else
- ThrowbackStarted = 1;
- }
- if (ThrowbackStarted > 0)
- ThrowbackSendError(level, lineno, error);
- }
-
- /*
- * fatal --- fatal error handler
- */
- void
- fatal(char *str)
- {
- pouterror(FATAL, str); /* added ver TER_2.0 4 Jul 89 */
- TB(FATAL, Local_Line_num, str);
-
- #ifdef IBM /* changed ver TER_2.0 */
- exit(-1);
- #else
- exit(10); /* Amiga & UNIX prefer positive numbers for
- * error minimal error is 10 (no system prob) */
- #endif
- return; /* never executed */
- }
-
- /*
- * error --- error in a line print line number and error
- */
- void
- error(char *str)
- {
-
- /*
- * if(N_files > 1) commented out test for N_files in rel TER_2.0
- * because a single command line source file (which is what N_file
- * counts) can have multiple include source files.
- */
-
- pouterror(SERIOUS, str);
- TB(SERIOUS, Local_Line_num, str);
- }
-
- /*
- * warn --- trivial error in a line print line number and error
- */
- void
- warn(char *str)
- {
- /*
- * if(N_files > 1) commented out in rel TER_2.0 same reason as
- * above
- */
- pouterror(WARNING, str);
- TB(WARNING, Local_Line_num, str);
- }
-
-
- /*
- * delim --- check if character is a delimiter
- */
- int
- delim(char c)
- {
- if (any(c, " \t\n"))
- return (YES);
- return (NO);
- }
-
- /*
- * skip_white --- move pointer to next non-whitespace char
- */
- char *
- skip_white(char *ptr)
- {
- while (*ptr == BLANK || *ptr == TAB)
- ptr++;
- return (ptr);
- }
-
- /*
- * eword --- emit a word to code file
- */
- void
- eword(int wd)
- {
- emit(hibyte(wd));
- emit(lobyte(wd));
- }
-
- /*
- * emit --- emit a byte to code file
- */
- int
- emit(unsigned char byte)
- {
- #ifdef DEBUG
- printf("%2x @ %4x\n", byte, Pc);
- #endif
- if (Pass == 1) {
- Pc++;
- return (YES);
- }
- if (P_total < P_LIMIT)
- P_bytes[P_total++] = byte;
- E_bytes[E_total++] = byte;
- Pc++;
- if (E_total == E_LIMIT)
- f_record();
- return;
- }
-
- /*
- * f_record --- flush record out in `S1' format
- */
- void
- f_record(void)
- { /* made void for ANSI C compat ver TER_2.0
- * 6/18/89 */
- int i;
- int chksum;
-
- if (Pass == 1)
- return;
- if (E_total == 0) {
- E_pc = Pc;
- return;
- }
- F_total += E_total; /* total bytes in file ver (TER)2.01 19 Jun
- * 89 */
- chksum = E_total + 3; /* total bytes in this record */
- chksum += lobyte(E_pc);
- chksum += E_pc >> 8;
- fprintf(Objfil, "S1"); /* record header preamble */
- hexout(E_total + 3); /* byte count +3 */
- hexout(E_pc >> 8); /* high byte of PC */
- hexout(lobyte(E_pc)); /* low byte of PC */
- for (i = 0; i < E_total; i++) {
- chksum += lobyte(E_bytes[i]);
- hexout(lobyte(E_bytes[i])); /* data byte */
- }
- chksum = ~chksum; /* one's complement */
- hexout(lobyte(chksum)); /* checksum */
- if (CRflag == 1) /* test for CRflag added ver TER_1.1 */
- fprintf(Objfil, "%c\n", CR); /* print in IBM format for
- * some PROM boxes */
- else
- fprintf(Objfil, "\n"); /* this is original statement */
- E_pc = Pc;
- E_total = 0;
- }
-
- char *hexstr = "0123456789ABCDEF";
-
- void
- hexout(int byte)
- {
-
- byte = lobyte(byte);
- fprintf(Objfil, "%c%c", hexstr[byte >> 4], hexstr[byte & 017]);
- return;
- }
-
- /*
- * print_line --- pretty print input line
- */
- void
- print_line(void)
- {
- int i;
- register char *ptr;
-
- fprintf(Listfil, "%04d ", Line_num);
- if (P_total || P_force)
- {fprintf(Listfil,"%04x", Old_pc);}
- else
- {fprintf(Listfil," ");}
-
- for (i = 0; i < P_total && i < 6; i++)
- {fprintf(Listfil, " %02x", lobyte(P_bytes[i]));}
- for (; i < 6; i++)
- {fprintf(Listfil," ");}
- fprintf(Listfil," ");
-
- if (Cflag) {
- if (Cycles)
- {fprintf(Listfil, "[%2d ] ", Cycles);}
- else
- {fprintf(Listfil," ");}
- }
- ptr = Line;
- while (*ptr != '\n') /* just echo the line back out */
- {fputc(*ptr++,Listfil);}
- for (; i < P_total; i++) {
- if (i % 6 == 0)
- {fprintf(Listfil,"\n ");};
- fprintf(Listfil, " %02x", lobyte(P_bytes[i]));
- }
- if (Pflag50 && (++Page_lines >= PageLen)) /* form feed if flag set */
- NewPage(); /* ver (TER) 2.02 19 Jun 89 */
- fprintf(Listfil,"\n");
- }
-
- /*
- * any --- does str contain c?
- */
- int
- any(char c, char *str)
- {
- while (*str != EOS)
- if (*str++ == c)
- return (YES);
- return (NO);
- }
-
- /*
- * mapdn --- convert A-Z to a-z
- */
- char
- mapdn(char c)
- {
- if (c >= 'A' && c <= 'Z')
- return ((char) (c + 040)); /* cast value to char for
- * ANSI C, ver TER_2.0 */
- return (c);
- }
-
- /*
- * lobyte --- return low byte of an int
- */
- unsigned char
- lobyte(int i)
- {
- return (i & 0xFF);
- }
-
-
- /*
- * hibyte --- return high byte of an int
- */
- unsigned char
- hibyte(int i)
- {
- return ((i >> 8) & 0xFF);
- }
-
- /*
- * head --- is str2 the head of str1?
- */
- int
- head(char *str1, char *str2)
- {
- while (*str1 != EOS && *str2 != EOS) {
- if (*str1 != *str2)
- break;
- str1++;
- str2++;
- }
- if (*str1 == *str2)
- return (YES);
- if (*str2 == EOS)
- if (any(*str1, " \t\n,+-];*"))
- return (YES);
- return (NO);
- }
-
- /*
- * alpha --- is character a legal letter
- */
- int
- alpha(char c)
- {
- if (c <= 'z' && c >= 'a')
- return (YES);
- if (c <= 'Z' && c >= 'A')
- return (YES);
- if (c == '_')
- return (YES);
- if (c == '.')
- return (YES);
- return (NO);
- }
-
-
- /*
- * alphan --- is character a legal letter or digit
- */
- int
- alphan(char c)
- {
- if (alpha(c))
- return (YES);
- if (c <= '9' && c >= '0')
- return (YES);
- if (c == '$')
- return (YES); /* allow imbedded $ */
- if (c == '@')
- return (YES); /* allow imbedded @, added ver TER_2.0 added
- * to permit redefinable variables */
- return (NO);
- }
-
- /*
- * white --- is character whitespace?
- */
- int
- white(char c)
- {
- if (c == TAB || c == BLANK || c == '\n')
- return (YES);
- return (NO);
- }
-
- /*
- * alloc --- allocate memory
- */
- char *
- alloc(int nbytes)
- {
-
- return (malloc(nbytes));
- }
-
- /*
- * FNameGet --- Find a file name <file> or "file" in the Operand string added
- * ver TER_2.0 6/17/89 note: this routine will return a file name with white
- * space if between delimeters. This is permitted in AmigaDOS. Other DOS
- * may hiccup or just use name up to white space
- */
-
- int
- FNameGet(char *NameString)
- /* char *NameString; pointer to output string */
- {
- char *frompoint; /* pointers to input string, don't
- * bash Operand */
- char *topoint;/* pointer to output string, don't bash
- * NameString */
-
- frompoint = Operand; /* include file name is in parsed string
- * Operand */
- topoint = NameString; /* copy of pointer to increment in copying */
- if (*frompoint != '<' && *frompoint != '"')
- return (0); /* bad syntax */
- frompoint++; /* skip < or " */
-
- while (*frompoint != '>' && *frompoint != '"') { /* look for delimeter */
- if (*frompoint == EOS)
- return (0); /* missing delimeter */
- *topoint++ = *frompoint++; /* copy path & file name for
- * DOS */
- }
-
- *topoint = EOS; /* terminate file name */
- #ifdef DEBUG2
- printf("FNameGet: file name=%s\n", NameString);
- #endif
- return (1); /* proper syntax anyway */
- }
-
- /*
- * --- strsave() find a place to save a string & return pointer to it added
- * ver TER_2.0 6/18/89 function taken from Kernighan & Ritchie 78
- */
- char *
- strsave(char *s)
- {
- char *p;
-
- if ((p = alloc(strlen(s) + 1)) != NULL)
- strcpy(p, s);
- return (p);
- }
-
- /*
- * pouterror() ---- print out standard error header added rel TER_2.0 6/18/89
- */
-
- void
- pouterror(int err_type, char *str)
- {
- fprintf(stderr, "%s, line no. ", Argv[Cfn]); /* current file name */
- fprintf(stderr, "%d: ", Local_Line_num); /* current line number */
- fprintf(stderr, "%s\n", str);
- /*
- * NOTE: THERE IS NO \n ! Calling procedure supplies suffixing error
- * message and \n. viz. file pseudo.c procedure do_pseudo in case
- * INCLUDE. Note also that error count is incremented.
- */
- Page_lines++; /* increment lines per page */
- if (err_type != WARNING) {
- Err_count++;
- }
- }
-
- /*
- * New Page() --- form feed a new page, print heading & inc page number Moved
- * here from do_pseudo (pseudo.c) in ver (TER) 2.02 19 Jun 89 so that can
- * call from print_line() as well for p50 option.
- */
-
- void
- NewPage(void)
- {
- Page_lines = 0; /* ver TER_2.08 so that OPT PAGE works */
- fprintf(Listfil, "\n\f");
- fprintf(Listfil, "%-10s", Argv[Cfn]);
- fprintf(Listfil, " ");
- fprintf(Listfil, "page %3d\n", Page_num++);
- }
-
-
- /*
- * LastChar() ----- return a pointer to the last character in a string
- * Exception: will return garbage if NULL string
- */
-
- char *
- LastChar(char *strpt)
- /* strpt; pointer to string to be examined */
- {
- char *c;
-
- c = strpt; /* don't zap original */
- while (*c != EOS) /* search for end */
- c++;
- return (--c); /* back up one to last character */
- }
-
-
- #define OS_FSControl 0x29
- #define DDEUtils_ThrowbackRegister 0x42585
- #define DDEUtils_ThrowbackUnRegister 0x42586
- #define DDEUtils_ThrowbackStart 0x42587
- #define DDEUtils_ThrowbackSend 0x42588
- #define DDEUtils_ThrowbackEnd 0x42580
- #define Throwback_ReasonProcessing 0
- #define Throwback_ReasonErrorDetails 1
- #define Throwback_ReasonInfoDetails 2
-
-
-
- os_error *
- ThrowbackStart(void)
- {
- return os_swi0(os_X | DDEUtils_ThrowbackStart);
- }
-
- static char *ErrorFile;
-
- os_error *
- ThrowbackSendStart(char *filename)
- {
- ErrorFile = filename;
- return os_swi3(os_X | DDEUtils_ThrowbackSend,
- Throwback_ReasonProcessing, 0, (int) filename);
- }
-
- os_error *
- ThrowbackSendError(int level, int lineno, char *error)
- {
- if (level == ThrowbackInfo)
- return os_swi6(os_X | DDEUtils_ThrowbackSend,
- Throwback_ReasonInfoDetails, 0, (int) ErrorFile,
- lineno, 0, (int) error);
- else
- return os_swi6(os_X | DDEUtils_ThrowbackSend,
- Throwback_ReasonErrorDetails, 0, (int) ErrorFile,
- lineno, level, (int) error);
- }
-
- os_error *
- ThrowbackEnd(void)
- {
- return os_swi0(os_X | DDEUtils_ThrowbackEnd);
- }
-