mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 17:04:19 +00:00
Upload
Digital Research
This commit is contained in:
458
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/as68.h
Normal file
458
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/as68.h
Normal file
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
#include "machine.h"
|
||||
#ifdef REGULUS /*sw*/
|
||||
# include <sys/cout.h>
|
||||
#endif
|
||||
#ifdef UNIX /*sw*/
|
||||
# include <c68/sys/cout.h>
|
||||
#endif
|
||||
#ifdef DECC
|
||||
# include "ICOUT"
|
||||
# define VAX11
|
||||
# define unlink delete
|
||||
char lsfn[40]; /* listing file name */
|
||||
int *sptr;
|
||||
#endif
|
||||
#ifdef WHITESM /*sw*/
|
||||
# include <stdio.h>
|
||||
# include <klib.h>
|
||||
# include <ctype.h>
|
||||
# include "cout.h"
|
||||
# define myfflush xfflush
|
||||
#endif
|
||||
|
||||
#ifdef CPM /*sw*/
|
||||
# include <stdio.h>
|
||||
# include <klib.h>
|
||||
# include <ctype.h>
|
||||
# include "cout.h"
|
||||
# define myfflush xfflush
|
||||
#endif
|
||||
|
||||
#include "mach.h"
|
||||
|
||||
/* flags for symbols*/
|
||||
#define SYDF 0100000 /*defined*/
|
||||
#define SYEQ 0040000 /*equated*/
|
||||
#define SYGL 0020000 /*global - entry or external*/
|
||||
#define SYER 0010000 /*equated register*/
|
||||
#define SYXR 0004000 /*external reference*/
|
||||
#define SYRA 0002000 /*DATA based relocatable*/
|
||||
#define SYRO 0001000 /*TEXT based relocatable*/
|
||||
#define SYBS 0000400 /*BSS based relocatable*/
|
||||
#define SYIN 0000200 /*internal symbol -- opcode, dir or equ*/
|
||||
#define SYPC 0000100 /*[vlh]equated using star '*' expression*/
|
||||
#define SYRM 0000040 /*[vlh]register mask equate*/
|
||||
|
||||
/*flags for opcodes and directives*/
|
||||
#define OPDR 0100000 /*0=>opcode, 1=>directive*/
|
||||
#define OPFF 037 /*type of instruction (used as mask)*/
|
||||
|
||||
/* intermediate text types*/
|
||||
#define ITBS 0 /*beginning of statement*/
|
||||
#define ITSY 1 /*pointer to symbol table*/
|
||||
#define ITCN 2 /*constant*/
|
||||
#define ITSP 3 /*special*/
|
||||
#define ITRM 4 /*[vlh]register mask!*/
|
||||
#define ITPC 5 /*[vlh]pc relative argument*/
|
||||
|
||||
/* Effective address mode bits*/
|
||||
#define DDIR 000
|
||||
#define ADIR 010
|
||||
#define INDIRECT 020
|
||||
#define INDINC 030
|
||||
#define DECIND 040
|
||||
#define INDDISP 050
|
||||
#define INDINX 060
|
||||
#define SADDR 070
|
||||
#define LADDR 071
|
||||
#define IMM 074
|
||||
|
||||
/* Register Range */
|
||||
#define AREGLO 8
|
||||
#define AREGHI 15
|
||||
|
||||
/* Relocation bit definitions:*/
|
||||
#define RBMASK 07 /*tells type of relocation*/
|
||||
#define INSABS 7 /*first word of instr -- absolute*/
|
||||
#define DABS 0 /*data word absolute*/
|
||||
#define TRELOC 2 /* TEXT relocatable*/
|
||||
#define DRELOC 1 /* DATA relocatable*/
|
||||
#define BRELOC 3 /* BSS relocatable*/
|
||||
#define EXTVAR 4 /* ref to external variable*/
|
||||
#define LUPPER 5 /* upper word of long*/
|
||||
#define EXTREL 6 /* external relative mode*/
|
||||
|
||||
/* Register values, as reflected in as68init */
|
||||
#define CCR 16
|
||||
#define SR 17
|
||||
#define USP 18
|
||||
#define WORD_ID 20 /* [vlh] 4.2 */
|
||||
#define PC 22
|
||||
#define SFC 23 /* [vlh] 4.2, control register for 68010 */
|
||||
#define DFC 24 /* [vlh] 4.2, control register for 68010 */
|
||||
#define VSR 25 /* [vlh] 4.2, control register for 68010 */
|
||||
|
||||
/* Control Register Numeric Values */
|
||||
#define SFC_CR 0
|
||||
#define DFC_CR 1
|
||||
#define USP_CR 0x800
|
||||
#define VSR_CR 0x801
|
||||
|
||||
/* Instruction Formats */
|
||||
#define ANDI 01000
|
||||
#define AND 0140000
|
||||
#define ORI 0
|
||||
#define OR 0100000
|
||||
#define EORI 05000
|
||||
#define EOR 0130000
|
||||
#define MOVE 0
|
||||
#define MOVEC 047172 /* [vlh] 4.2, 68010 */
|
||||
#define MOVES 07000 /* [vlh] 4.2, 68010 */
|
||||
#define RTD 047164 /* [vlh] 4.2, 68010 */
|
||||
#define MOVETCC 042300
|
||||
#define MOVEFCC 041300 /* [vlh] 4.2, 68010 */
|
||||
#define MOVESR 043300
|
||||
#define SRMOVE 040300
|
||||
#define MOVEUSP 047140
|
||||
#define CLRVAL 041000
|
||||
|
||||
#define CLRFOR 24
|
||||
|
||||
/*relocation values*/
|
||||
#define ABS 0 /*absolute*/
|
||||
#define DATA 1
|
||||
#define TEXT 2
|
||||
#define BSS 3
|
||||
#define EXTRN 4 /*externally defined*/
|
||||
|
||||
/* Conditional Assembly variables and constants [vlh] */
|
||||
#define LOW_CA 21 /* [vlh] */
|
||||
#define HI_CA 30 /* [vlh] */
|
||||
|
||||
/* Size attribute */
|
||||
#define BYTE 'b'
|
||||
#define WORD 'w'
|
||||
#define LONG 'l'
|
||||
#define BYTESIZ 1
|
||||
#define WORDSIZ 2
|
||||
#define LONGSIZ 4
|
||||
|
||||
/* Ascii values */
|
||||
#define EOLC '\n'/*end of line character*/
|
||||
#define EOF 0 /*end of file indicator*/
|
||||
#define NULL 0 /* [vlh] character null '\0' */
|
||||
#define SOH 1
|
||||
|
||||
/* Miscellaneous Defines */
|
||||
#define TRUE 1 /* [vlh] boolean values */
|
||||
#define FALSE 0 /* [vlh] boolean values */
|
||||
#define STDOUT 1 /* file descriptor for standard output */
|
||||
#define STDERR 2 /* file descriptor for standard error */
|
||||
#define NAMELEN 8 /* length of name in symbol table */
|
||||
#define BSIZE 512
|
||||
#define ITBSZ 256 /*size of the it buffer*/
|
||||
#define STMAX 200 /*size of intermediate text buffer*/
|
||||
#define SZIRT 128
|
||||
#define EXTSZ 512
|
||||
#define DIRECT 33 /* [vlh] 4.2, number of entries in p2direct */
|
||||
#define ORGDIR 14 /* [vlh] 4.2, org entry in p2direct */
|
||||
|
||||
/*
|
||||
* intermediate text file
|
||||
* format of the intermediate text for one statement:
|
||||
*
|
||||
* ******************************************************
|
||||
* * it type = ITBS * # it entries * 0
|
||||
* ******************************************************
|
||||
* * absolute line number (long) *
|
||||
* ******************************************************
|
||||
* * it type = ITSY * instr length * 1
|
||||
* ******************************************************
|
||||
* * symbol table pointer for stmt label (long) *
|
||||
* ******************************************************
|
||||
* * it type = ITSY * instr mode length * 2
|
||||
* ******************************************************
|
||||
* * opcode ptr (long) *
|
||||
* ******************************************************
|
||||
* * it type = ITCN * relocation base * 3
|
||||
* ******************************************************
|
||||
* * location counter (pass 1) *
|
||||
* ******************************************************
|
||||
* * it type * relocation flag * 4 - oprnds
|
||||
* ******************************************************
|
||||
* * value (long) *
|
||||
* ******************************************************
|
||||
* .
|
||||
*
|
||||
* .
|
||||
* ******************************************************
|
||||
* * it type * relocation flag * n - oprnds
|
||||
* ******************************************************
|
||||
* * value (long) *
|
||||
* ******************************************************
|
||||
*/
|
||||
|
||||
#define ITOP1 4 /*first it entry for operands*/
|
||||
|
||||
/*
|
||||
* it type meaning
|
||||
* 0 beginning of statement
|
||||
* 1 value is pointer to symbol table
|
||||
* 2 value is a constant
|
||||
* 3 value is a specal char
|
||||
*
|
||||
* relocation flag for opcode it entry is operand length:
|
||||
* 'b' => byte
|
||||
* 'w' => word
|
||||
* 'l' => long
|
||||
*/
|
||||
|
||||
struct it {
|
||||
char itty; /*it type*/
|
||||
char itrl; /*relocation flag or # it entries*/
|
||||
long itop;
|
||||
};
|
||||
|
||||
short mode; /*operand mode (byte, word, long)*/
|
||||
short modelen; /*operand length per mode*/
|
||||
|
||||
/* parameters that define the main table*/
|
||||
#ifndef DECC
|
||||
# define SZMT 300 /*initial size of the main table */
|
||||
/*must be large enough to initialize*/
|
||||
# define ICRSZMT 10 /*add to main table when run out*/
|
||||
#else
|
||||
/**
|
||||
* use sizes on vax that result in memory allocation of multiples of
|
||||
* 512 bytes. Calls to sbrk round up to the next multiple of 512 so
|
||||
* for contiguous memory allocation these numbers should be used:
|
||||
* size of symtab = 18
|
||||
* 455 * 18 + 2 = 8192 (=16*512)
|
||||
* 256 * 18 = 4608 (=9*512)
|
||||
**/
|
||||
# define SZMT 455
|
||||
# define ICRSZMT 256
|
||||
#endif
|
||||
short cszmt; /*current size of main table*/
|
||||
char *bmte; /*beginning of main table*/
|
||||
char *emte; /*end of main table*/
|
||||
|
||||
short itbuf[ITBSZ]; /*it buffer*/
|
||||
|
||||
struct it stbuf[STMAX]; /*holds it for one statement*/
|
||||
#define STBFSIZE (sizeof stbuf[0])
|
||||
|
||||
char sbuf[BSIZE]; /*holds one block of source*/
|
||||
|
||||
/* format of a symbol entry in the main table*/
|
||||
struct symtab {
|
||||
char name[NAMELEN]; /*symbol name*/
|
||||
short flags;
|
||||
long vl1; /*symbol value*/
|
||||
short vextno; /* external symbol reference # */
|
||||
char *tlnk; /*table link*/
|
||||
} *symtptr;
|
||||
/* STESIZE - byte length of symbol table entry -- should be 18 */
|
||||
/* must use a sizeof to avoid over run variables */
|
||||
#define STESIZE (sizeof *symtptr)
|
||||
char *lmte; /*last entry in main table */
|
||||
|
||||
struct irts {
|
||||
char *irle; /*ptr to last entry in chain*/
|
||||
char *irfe; /*ptr to first entry in chain*/
|
||||
};
|
||||
|
||||
long stlen; /*length of symbol table*/
|
||||
|
||||
/*initial reference table for symbols*/
|
||||
char *sirt[SZIRT];
|
||||
#define SIRTSIZE (sizeof sirt[0])
|
||||
|
||||
/*initial reference table to opcodes*/
|
||||
char *oirt[SZIRT];
|
||||
#define OIRTSIZE (sizeof oirt[0])
|
||||
|
||||
/*external symbol table*/
|
||||
char *extbl[EXTSZ];
|
||||
short extindx; /*index to external symbol table*/
|
||||
char **pexti; /*ptr to external symbol table*/
|
||||
|
||||
short absln; /*absolute line number*/
|
||||
short p2absln; /*pass 2 line number*/
|
||||
short fcflg; /*0=>passed an item. 1=>first char*/
|
||||
short fchr; /*first char in term*/
|
||||
short ifn; /*source file descriptor*/
|
||||
short *pitix; /*ptr to it buffer*/
|
||||
short itwc; /*number of words in it buffer*/
|
||||
struct it *pitw; /*ptr to it buffer next entry*/
|
||||
short itype; /*type of item*/
|
||||
long ival; /*value of item*/
|
||||
char *lblpt; /*label pointer*/
|
||||
char lbt[NAMELEN]; /*holds label name*/
|
||||
long loctr; /*location counter*/
|
||||
long savelc[4]; /*save relocation counters for 3 bases*/
|
||||
short nite; /*number of entries in stbuf*/
|
||||
struct it *pnite;
|
||||
short lfn; /*loader output file descriptor*/
|
||||
char *opcpt; /*pointer to opcode entry in main table*/
|
||||
short p2flg; /*0=>pass 1 1=>pass 2*/
|
||||
char **pirt; /*entry in initial reference table*/
|
||||
short reloc; /*reloc value returned by expr evaluator (expr)*/
|
||||
short rlflg; /*relocation value of current location counter*/
|
||||
struct hdr couthd; /* cout header structure */
|
||||
|
||||
short format;
|
||||
short sbuflen; /*number of chars in sbuf*/
|
||||
char *psbuf; /*ptr into sbuf*/
|
||||
short itfn; /*it file number*/
|
||||
char itfnc; /*last char of it file name*/
|
||||
short trbfn; /*temp for text relocation bits*/
|
||||
char trbfnc; /*last char of text rb file*/
|
||||
short dafn; /*file for data stuff*/
|
||||
char dafnc; /*last char of data file*/
|
||||
short drbfn; /*file for data relocation bits*/
|
||||
char drbfnc; /*last char*/
|
||||
short prtflg; /*print output flag*/
|
||||
short undflg; /*make undefined symbols external flag*/
|
||||
|
||||
short starmul; /* * is multiply operator*/
|
||||
|
||||
/* Symbol Table Pointers for Subset of Opcodes */
|
||||
char *endptr, *addptr;
|
||||
char *orgptr;
|
||||
char *subptr, *addiptr, *addqptr, *subiptr, *subqptr;
|
||||
char *cmpptr, *addaptr, *cmpaptr, *subaptr, *cmpmptr;
|
||||
char *equptr;
|
||||
char *andptr, *andiptr, *eorptr, *eoriptr, *orptr, *oriptr;
|
||||
char *cmpiptr;
|
||||
char *moveptr, *moveqptr;
|
||||
char *exgptr;
|
||||
char *evenptr;
|
||||
char *jsrptr, *bsrptr, *nopptr;
|
||||
|
||||
short numcon[2], numsym[2], indir[2], immed[2], numreg[2];
|
||||
short plevel; /*parenthesis level counter*/
|
||||
short opdix; /*operand index counter*/
|
||||
|
||||
/* ptrs to ins[] and rlbits[]*/
|
||||
short *pins;
|
||||
short *prlb;
|
||||
short ins[5]; /*holds instruction words*/
|
||||
|
||||
#define PRTCHLEN 128
|
||||
char prtchars[PRTCHLEN];/*line buffer for putchar*/
|
||||
char *prtchidx; /*index for putchar*/
|
||||
|
||||
short extflg, extref; /*external in expr*/
|
||||
|
||||
struct op {
|
||||
short ea; /*effective address bits*/
|
||||
short len; /*effective address length in bytes*/
|
||||
long con; /*constant or reloc part of operand*/
|
||||
short drlc; /*reloc of con*/
|
||||
short ext; /*external variable #*/
|
||||
short idx; /*index register if any*/
|
||||
short xmod; /*mode of index reg*/
|
||||
} opnd[2];
|
||||
|
||||
struct iob {
|
||||
int fd; /* file descriptor */
|
||||
int cc; /* char count */
|
||||
char *cp; /* next char pointer */
|
||||
char cbuf[BSIZE]; /* character buffer */
|
||||
} lbuf, tbuf, dabuf, drbuf;
|
||||
|
||||
char tfilname[80];
|
||||
char *sfname; /*sw -> Source filename */
|
||||
char initfnam[80]; /*sw Init file name */
|
||||
char *tfilptr; /*sw Compiler independent */
|
||||
#define LASTCHTFN (*tfilptr) /*sw*/
|
||||
|
||||
/* assembler flag variables */
|
||||
short didorg;
|
||||
short shortadr; /*short addresses if set*/
|
||||
short initflg; /*initialize flag*/
|
||||
short m68010; /*[vlh] 4.2, 68010 code*/
|
||||
|
||||
/* pass 1 global variables */
|
||||
short numops; /*number of operands*/
|
||||
short inoffset; /*[vlh]offset directive*/
|
||||
short p1inlen; /*pass 1 instr length*/
|
||||
|
||||
/* pass 2 global variables */
|
||||
short instrlen; /*pass 2 bytes in current instruction*/
|
||||
|
||||
/* General Assembler Variables */
|
||||
short stdofd;
|
||||
extern int errno;
|
||||
char peekc;
|
||||
short ca_true; /* true unless in a false CA*/
|
||||
short ca; /* depth of conditional assembly, none = 0*/
|
||||
short ca_level; /* at what CA depth did CA go false?*/
|
||||
short nerror; /*# of assembler errors*/
|
||||
short in_err; /*[vlh] don't generate instrlen err if in err state*/
|
||||
long itoffset;
|
||||
short equflg; /*doing an equate stmt*/
|
||||
short refpc; /* * referenced in expr*/
|
||||
|
||||
/* defines */
|
||||
#define tolower(c) ((c)<='Z' && (c)>='A') ? (c)|32 : (c)
|
||||
#define islower(c) ((c) <= 'z' && (c) >= 'a')
|
||||
#define isalpha(c) (islower( (c) | 32 ))
|
||||
#define isdigit(c) ((c) >= '0' && (c) <= '9')
|
||||
#define isalnum(c) (isalpha(c) || isdigit(c))
|
||||
#define igblk() while(fchr==' ') fchr=gchr()
|
||||
#define ckein() ((pitw >= pnite))
|
||||
|
||||
/* is it an alterable operand */
|
||||
#define memalt(ap) (memea(ap) && altea(ap))
|
||||
#define dataalt(ap) (dataea(ap) && altea(ap))
|
||||
#define altea(ap) ((((ap)->ea&070)!=SADDR || ((ap)->ea&6)==0))
|
||||
|
||||
/* is it the specific type of operand */
|
||||
#define memea(ap) (((ap)->ea&070) >= INDIRECT)
|
||||
#define dataea(ap) (((ap)->ea&070) != ADIR)
|
||||
#define pcea(ap) ((ap)->ea==072 || (ap)->ea==073)
|
||||
#define ckdreg(ap) ((ap)->ea>=0 && (ap)->ea<AREGLO)
|
||||
#define ckareg(ap) ((ap)->ea>=AREGLO && (ap)->ea<=AREGHI)
|
||||
#define ckreg(ap) ((ap)->ea>=0 && (ap)->ea<=AREGHI)
|
||||
|
||||
#define DBGSTRT() putchar(0); stdofd = 2
|
||||
#define DBGEND() putchar(0); stdofd = 0
|
||||
|
||||
/* Predeclared Functions which return values */
|
||||
long lseek();
|
||||
char *sbrk();
|
||||
char *lemt();
|
||||
|
||||
int endit();
|
||||
int rubout();
|
||||
|
||||
int p2gi();
|
||||
int (*p2direct[])();
|
||||
|
||||
/* Second Pass Subroutines */
|
||||
int opf1(), opf2(), opf3(), opf4(), opf5(), relbr(), opf7(), opf8();
|
||||
int opf9(), opf11(), opf12(), opf13(), opf15(), opf17(), opf20();
|
||||
int opf21(), opf22(), opf23(), opf31();
|
||||
|
||||
/* Directive Handling Subroutines */
|
||||
int hopd(), hend(), send(), horg(), sorg(), hequ(), hreg();
|
||||
int hds(), sds(), sdcb();
|
||||
int hdsect(), hpsect(), sdsect(), spsect();
|
||||
int hsection(), ssection(), hoffset();
|
||||
int hent(), hext();
|
||||
int igrst();
|
||||
int hbss(), sbss();
|
||||
int heven(), seven();
|
||||
int hdc(), sdc(), hdcb();
|
||||
int hmask2(), hcomline(), hidnt(), httl(), hpage(), spage();
|
||||
int hifeq(), hifne(), hiflt(), hifle(), hifgt(), hifge(), hendc();
|
||||
int hifnc(), hifc(), hopt();
|
||||
|
||||
238
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/as68init
Normal file
238
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/as68init
Normal file
@@ -0,0 +1,238 @@
|
||||
**
|
||||
* Copyright 1981
|
||||
* Alcyon Corporation
|
||||
* 8716 Production Ave.
|
||||
* San Diego, Ca. 92121
|
||||
*
|
||||
* 68010 added operands: movec, moves, rtd.
|
||||
* 68010 added control registers: sfc, dfc, vsr.
|
||||
* [vlh] 3 august 83
|
||||
* added vbr sw 2/5/84
|
||||
**
|
||||
R0: .equ 0,r
|
||||
R1: .equ 1,r
|
||||
R2: .equ 2,r
|
||||
R3: .equ 3,r
|
||||
R4: .equ 4,r
|
||||
R5: .equ 5,r
|
||||
R6: .equ 6,r
|
||||
R7: .equ 7,r
|
||||
R8: .equ 8,r
|
||||
R9: .equ 9,r
|
||||
R10: .equ 10,r
|
||||
R11: .equ 11,r
|
||||
R12: .equ 12,r
|
||||
R13: .equ 13,r
|
||||
R14: .equ 14,r
|
||||
R15: .equ 15,r
|
||||
D0: .equ 0,r
|
||||
D1: .equ 1,r
|
||||
D2: .equ 2,r
|
||||
D3: .equ 3,r
|
||||
D4: .equ 4,r
|
||||
D5: .equ 5,r
|
||||
D6: .equ 6,r
|
||||
D7: .equ 7,r
|
||||
A0: .equ @10,r
|
||||
A1: .equ @11,r
|
||||
A2: .equ @12,r
|
||||
A3: .equ @13,r
|
||||
A4: .equ @14,r
|
||||
A5: .equ @15,r
|
||||
A6: .equ @16,r
|
||||
A7: .equ @17,r
|
||||
SP: .equ 15,r
|
||||
CCR: .equ 16,r
|
||||
SR: .equ 17,r
|
||||
r0: .equ 0,r
|
||||
r1: .equ 1,r
|
||||
r2: .equ 2,r
|
||||
r3: .equ 3,r
|
||||
r4: .equ 4,r
|
||||
r5: .equ 5,r
|
||||
r6: .equ 6,r
|
||||
r7: .equ 7,r
|
||||
r8: .equ 8,r
|
||||
r9: .equ 9,r
|
||||
r10: .equ 10,r
|
||||
r11: .equ 11,r
|
||||
r12: .equ 12,r
|
||||
r13: .equ 13,r
|
||||
r14: .equ 14,r
|
||||
r15: .equ 15,r
|
||||
d0: .equ 0,r
|
||||
d1: .equ 1,r
|
||||
d2: .equ 2,r
|
||||
d3: .equ 3,r
|
||||
d4: .equ 4,r
|
||||
d5: .equ 5,r
|
||||
d6: .equ 6,r
|
||||
d7: .equ 7,r
|
||||
a0: .equ @10,r
|
||||
a1: .equ @11,r
|
||||
a2: .equ @12,r
|
||||
a3: .equ @13,r
|
||||
a4: .equ @14,r
|
||||
a5: .equ @15,r
|
||||
a6: .equ @16,r
|
||||
a7: .equ @17,r
|
||||
sp: .equ 15,r
|
||||
ccr: .equ 16,r
|
||||
sr: .equ 17,r
|
||||
usp: .equ 18,r
|
||||
USP: .equ 18,r
|
||||
pc: .equ 22,r
|
||||
PC: .equ 22,r
|
||||
sfc: .equ 23,r
|
||||
SFC: .equ 23,r
|
||||
dfc: .equ 24,r
|
||||
DFC: .equ 24,r
|
||||
vsr: .equ 25,r
|
||||
VSR: .equ 25,r
|
||||
vbr: .equ 25,r
|
||||
VBR: .equ 25,r
|
||||
.b: .equ 19,r
|
||||
.B: .equ 19,r
|
||||
.w: .equ 20,r
|
||||
.W: .equ 20,r
|
||||
.l: .equ 21,r
|
||||
.L: .equ 21,r
|
||||
abcd: .opd 4,@140400
|
||||
add: .opd 1,@150000
|
||||
adda: .opd 15,@150000
|
||||
addi: .opd 2,@003000
|
||||
addq: .opd 17,@050000
|
||||
inc: .opd 16,@050000
|
||||
addx: .opd 27,@150400
|
||||
and: .opd 1,@140000
|
||||
andi: .opd 2,@001000
|
||||
asl: .opd 8,@160400
|
||||
asr: .opd 8,@160000
|
||||
bcc: .opd 6,@062000
|
||||
bcs: .opd 6,@062400
|
||||
beq: .opd 6,@063400
|
||||
bze: .opd 6,@063400
|
||||
bge: .opd 6,@066000
|
||||
bgt: .opd 6,@067000
|
||||
bhi: .opd 6,@061000
|
||||
bhis: .opd 6,@062000
|
||||
bhs: .opd 6,@062000
|
||||
ble: .opd 6,@067400
|
||||
blo: .opd 6,@062400
|
||||
bls: .opd 6,@061400
|
||||
blos: .opd 6,@061400
|
||||
blt: .opd 6,@066400
|
||||
bmi: .opd 6,@065400
|
||||
bne: .opd 6,@063000
|
||||
bnz: .opd 6,@063000
|
||||
bpl: .opd 6,@065000
|
||||
bvc: .opd 6,@064000
|
||||
bvs: .opd 6,@064400
|
||||
bchg: .opd 7,@000100
|
||||
bclr: .opd 7,@000200
|
||||
bra: .opd 6,@060000
|
||||
bt: .opd 6,@060000
|
||||
bset: .opd 7,@000300
|
||||
bsr: .opd 6,@060400
|
||||
btst: .opd 7,@000000
|
||||
chk: .opd 26,@040600
|
||||
clr: .opd 24,@041000
|
||||
cmp: .opd 26,@130000
|
||||
cmpa: .opd 15,@130000
|
||||
cmpi: .opd 2,@006000
|
||||
cmpm: .opd 10,@130410
|
||||
dbcc: .opd 11,@052310
|
||||
dbcs: .opd 11,@052710
|
||||
dblo: .opd 11,@052710
|
||||
dbeq: .opd 11,@053710
|
||||
dbze: .opd 11,@053710
|
||||
dbra: .opd 11,@050710
|
||||
dbf: .opd 11,@050710
|
||||
dbge: .opd 11,@056310
|
||||
dbgt: .opd 11,@057310
|
||||
dbhi: .opd 11,@051310
|
||||
dbhs: .opd 11,@051310
|
||||
dble: .opd 11,@057710
|
||||
dbls: .opd 11,@051710
|
||||
dblt: .opd 11,@056710
|
||||
dbmi: .opd 11,@055710
|
||||
dbne: .opd 11,@053310
|
||||
dbnz: .opd 11,@053310
|
||||
dbpl: .opd 11,@055310
|
||||
dbt: .opd 11,@050310
|
||||
dbvc: .opd 11,@054310
|
||||
dbvs: .opd 11,@054710
|
||||
divs: .opd 5,@100700
|
||||
divu: .opd 5,@100300
|
||||
eor: .opd 23,@130000
|
||||
eori: .opd 2,@005000
|
||||
exg: .opd 12,@140400
|
||||
ext: .opd 13,@044000
|
||||
jmp: .opd 9,@047300
|
||||
jsr: .opd 9,@047200
|
||||
illegal: .opd 0,@045374
|
||||
lea: .opd 30,@040700
|
||||
link: .opd 19,@047120
|
||||
lsr: .opd 8,@160010
|
||||
lsl: .opd 8,@160410
|
||||
move: .opd 3,@000000
|
||||
movea: .opd 3,@000100
|
||||
movec: .opd 31,@047172
|
||||
movem: .opd 20,@044200
|
||||
movep: .opd 21,@000010
|
||||
moveq: .opd 22,@070000
|
||||
moves: .opd 31,@007000
|
||||
muls: .opd 5,@140700
|
||||
mulu: .opd 5,@140300
|
||||
nbcd: .opd 25,@044000
|
||||
neg: .opd 24,@042000
|
||||
negx: .opd 24,@040000
|
||||
nop: .opd 0,@047161
|
||||
not: .opd 24,@043000
|
||||
or: .opd 1,@100000
|
||||
ori: .opd 2,@000000
|
||||
pea: .opd 29,@044100
|
||||
reset: .opd 0,@047160
|
||||
rol: .opd 8,@160430
|
||||
ror: .opd 8,@160030
|
||||
roxl: .opd 8,@160420
|
||||
roxr: .opd 8,@160020
|
||||
rtd: .opd 14,@047164
|
||||
rte: .opd 0,@047163
|
||||
rtr: .opd 0,@047167
|
||||
rts: .opd 0,@047165
|
||||
sbcd: .opd 4,@100400
|
||||
scc: .opd 25,@052300
|
||||
shs: .opd 25,@052300
|
||||
scs: .opd 25,@052700
|
||||
slo: .opd 25,@052700
|
||||
seq: .opd 25,@053700
|
||||
sze: .opd 25,@053700
|
||||
sf: .opd 25,@050700
|
||||
sge: .opd 25,@056300
|
||||
sgt: .opd 25,@057300
|
||||
shi: .opd 25,@051300
|
||||
sle: .opd 25,@057700
|
||||
sls: .opd 25,@051700
|
||||
slt: .opd 25,@056700
|
||||
smi: .opd 25,@055700
|
||||
sne: .opd 25,@053300
|
||||
snz: .opd 25,@053300
|
||||
spl: .opd 25,@055300
|
||||
st: .opd 25,@050300
|
||||
svc: .opd 25,@054300
|
||||
svs: .opd 25,@054700
|
||||
stop: .opd 14,@047162
|
||||
sub: .opd 1,@110000
|
||||
suba: .opd 15,@110000
|
||||
subi: .opd 2,@002000
|
||||
subq: .opd 17,@050400
|
||||
dec: .opd 16,@050400
|
||||
subx: .opd 27,@110400
|
||||
swap: .opd 28,@044100
|
||||
tas: .opd 25,@045300
|
||||
trap: .opd 18,@047100
|
||||
trapv: .opd 0,@047166
|
||||
tst: .opd 24,@045000
|
||||
unlk: .opd 13,@047130
|
||||
.end
|
||||
13
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/cout.h
Normal file
13
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/cout.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#define HDSIZE (sizeof couthd) /**.o file header size*/
|
||||
struct hdr {
|
||||
short ch_magic; /*c.out magic number 060016 = $600E*/
|
||||
long ch_tsize; /*text size*/
|
||||
long ch_dsize; /*data size*/
|
||||
long ch_bsize; /*bss size*/
|
||||
long ch_ssize; /*symbol table size*/
|
||||
long ch_stksize; /*stack size*/
|
||||
long ch_entry; /*entry point*/
|
||||
short ch_rlbflg; /*relocation bits suppressed flag*/
|
||||
};
|
||||
|
||||
#define MAGIC 0x601a /* bra .+26 instruction*/
|
||||
146
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/def.h
Normal file
146
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/def.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
|
||||
char *ermsg[] = {
|
||||
"label redefined", /*1*/
|
||||
"invalid label", /*2*/
|
||||
"invalid opcode", /*3*/
|
||||
"no label for operand", /*4*/
|
||||
"opcode redefined", /*5*/
|
||||
"illegal expr", /*6*/
|
||||
"undefined symbol in equate", /*7*/
|
||||
"opcode for 68010 only", /*8*/ /* [vlh] 4.2 */
|
||||
"invalid first operand", /*9*/
|
||||
"invalid second operand", /*10*/
|
||||
"absolute value required", /*11*/
|
||||
"no code or data allowed in offset",/*12*/
|
||||
"undefined symbol", /*13*/
|
||||
"illegal index register", /*14*/
|
||||
"illegal constant", /*15*/
|
||||
"illegal extension", /*16*/ /*[vlh]*/
|
||||
"constant required", /*17*/
|
||||
"illegal format", /*18*/
|
||||
"illegal string", /*19*/
|
||||
"illegal addressing mode", /*20*/
|
||||
"assembler confusion...", /*21*/ /*[vlh] should never get this*/
|
||||
"illegal relative address", /*22*/
|
||||
"invalid bit range", /*23*/
|
||||
"illegal text delimiter", /*24*/
|
||||
"unexpected endc", /*25*/
|
||||
"endc expected", /*26*/
|
||||
"relocation error", /*27*/
|
||||
"symbol required", /*28*/
|
||||
"bad use of symbol", /*29*/
|
||||
"invalid data list", /*30*/
|
||||
"warning: cmpm generated for 68010",/*31*/ /* [vlh] 4.2 */
|
||||
"missing )", /*32*/
|
||||
"register required", /*33*/
|
||||
"illegal size", /*34*/
|
||||
"illegal 8-bit displacement", /*35*/
|
||||
"illegal external", /*36*/
|
||||
"illegal shift count", /*37*/
|
||||
"invalid instruction length", /*38*/
|
||||
"code or data not allowed in bss", /*39*/
|
||||
"backward assignment to *", /*40*/
|
||||
"illegal 16-bit displacement", /*41*/
|
||||
"illegal 16-bit immediate", /*42*/
|
||||
"illegal 8-bit immediate", /*43*/
|
||||
0
|
||||
};
|
||||
|
||||
char ldfn[40]; /*name of the relocatable object file*/
|
||||
|
||||
short brkln1 = 077777; /*pass 1 break line number for debugging*/
|
||||
short opcval; /*opcode*/
|
||||
short chmvq;
|
||||
|
||||
int (*p1direct[])() = { /* [vlh] 4.2, better have DIRECT number of entries... */
|
||||
hopd, /*0*/
|
||||
hend, /*1*/
|
||||
hdsect, /*2*/
|
||||
hpsect, /*3*/
|
||||
hequ, /*4*/
|
||||
hequ, /*5 .set same as .equ*/
|
||||
0, /*6*/
|
||||
0, /*7*/
|
||||
hdc, /*8*/
|
||||
hent, /*9*/
|
||||
hext, /*10*/
|
||||
hbss, /*11*/
|
||||
hds, /*12*/
|
||||
heven, /*13*/
|
||||
horg, /*14*/
|
||||
hmask2, /*15*/
|
||||
hreg, /*16*/
|
||||
hdcb, /*17*/
|
||||
hcomline, /*18*/
|
||||
hidnt, /*19*/
|
||||
hoffset, /*20*/
|
||||
hsection, /*21*/
|
||||
hifeq, /*22*/
|
||||
hifne, /*23*/
|
||||
hiflt, /*24*/
|
||||
hifle, /*25*/
|
||||
hifgt, /*26*/
|
||||
hifge, /*27*/
|
||||
hendc, /*28*/
|
||||
hifc, /*29*/
|
||||
hifnc, /*30*/
|
||||
hopt, /*31*/
|
||||
httl, /*32*/
|
||||
hpage, /*33*/
|
||||
0};
|
||||
|
||||
int (*p2direct[])() = { /* [vlh] 4.2, better have DIRECT number of entries... */
|
||||
0, /*0*/
|
||||
send, /*1*/
|
||||
sdsect, /*2*/
|
||||
spsect, /*3*/
|
||||
0, /*4*/
|
||||
0, /*5*/
|
||||
0, /*6*/
|
||||
0, /*7*/
|
||||
sdc, /*8*/
|
||||
0, /*9*/
|
||||
0, /*10*/
|
||||
sbss, /*11*/
|
||||
sds, /*12*/
|
||||
seven, /*13*/
|
||||
sorg, /*14*/
|
||||
0, /*15*/
|
||||
0, /*16*/
|
||||
sdcb, /*17*/
|
||||
sds, /*18 comline same as .ds.b*/
|
||||
0, /*19*/
|
||||
0, /*20*/
|
||||
ssection, /*21*/
|
||||
0, /*22*/
|
||||
0, /*23*/
|
||||
0, /*24*/
|
||||
0, /*25*/
|
||||
0, /*26*/
|
||||
0, /*27*/
|
||||
0, /*28*/
|
||||
0, /*29*/
|
||||
0, /*30*/
|
||||
0, /*31*/
|
||||
0, /*32*/
|
||||
spage, /*sw 33*/
|
||||
0};
|
||||
|
||||
short symcon;
|
||||
char endstr[] = "end";
|
||||
char equstr[] = "equ";
|
||||
char evnstr[] = "even";
|
||||
char orgstr1[] = "~.yxzorg";
|
||||
char orgstr2[] = "org";
|
||||
|
||||
short poslab;
|
||||
char tlab1[NAMELEN];
|
||||
short explmode; /*explicit mode length given*/
|
||||
|
||||
953
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/dir.c
Normal file
953
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/dir.c
Normal file
@@ -0,0 +1,953 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/* Pass 1 and pass 2 directive handling routines */
|
||||
/* code to handle conditional assembly directives */
|
||||
|
||||
#include "as68.h"
|
||||
|
||||
int p1gi();
|
||||
int p2gi();
|
||||
int igrst();
|
||||
|
||||
/*directive to define an opcode*/
|
||||
hopd()
|
||||
{
|
||||
if(!lbt[0]) {
|
||||
xerr(4); /*no label*/
|
||||
return;
|
||||
}
|
||||
setname(); /*move label into main table*/
|
||||
if((lblpt=lemt(TRUE,oirt))!=lmte) {
|
||||
xerr(5); /*opcode redefined*/
|
||||
return;
|
||||
}
|
||||
mmte(); /*make main table entry*/
|
||||
expr(&p1gi); /*get instruction format*/
|
||||
if(itype!=ITCN || ival<0 || ival>OPFF) {
|
||||
xerr(18); /*illegal format specifier*/
|
||||
return;
|
||||
}
|
||||
lblpt->flags |= ival|SYIN; /*remember format*/
|
||||
if(fchr != ',') { /*field separator*/
|
||||
xerr(10);
|
||||
return;
|
||||
}
|
||||
expr(&p1gi); /*get opcode value*/
|
||||
if(itype != ITCN) {
|
||||
xerr(17); /*not a constant*/
|
||||
return;
|
||||
}
|
||||
lblpt->vl1 = ival; /*put value in main table*/
|
||||
igrst(); /*ignore rest of statement-comment*/
|
||||
}
|
||||
|
||||
/* equate directive*/
|
||||
hequ()
|
||||
{
|
||||
if(lbt[0] == 0) {
|
||||
xerr(4); /*no label*/
|
||||
return;
|
||||
}
|
||||
setname();
|
||||
if((lblpt=lemt(FALSE,sirt))!=lmte) { /*aready there*/
|
||||
if(lbt[0] == '~') { /*local symbol*/
|
||||
lblpt = lmte;
|
||||
mmte();
|
||||
}
|
||||
}
|
||||
else
|
||||
mmte();
|
||||
if(lblpt->flags&SYXR) {
|
||||
xerr(29);
|
||||
return;
|
||||
}
|
||||
lblpt->flags |= SYDF|SYEQ; /*defined & equate*/
|
||||
equflg = 1;
|
||||
modelen = LONGSIZ;
|
||||
expr(&p1gi);
|
||||
equflg = 0;
|
||||
if(itype == ITSY && ival.ptrw2->flags&SYER) {
|
||||
lblpt->flags |= SYER; /*equated register*/
|
||||
ival = ival.ptrw2->vl1;
|
||||
}
|
||||
else if(itype != ITCN) {
|
||||
xerr(7); /*not a constant*/
|
||||
return;
|
||||
}
|
||||
if (inoffset && reloc != ABS) { /* [vlh] */
|
||||
xerr(11);
|
||||
return;
|
||||
}
|
||||
if(initflg) /*doing symbol table initialization*/
|
||||
lblpt->flags |= SYIN; /*internal symbol*/
|
||||
lblpt->vl1 = ival;
|
||||
if(reloc == DATA) /*check relocation*/
|
||||
{
|
||||
lblpt->flags |= SYRA; /*DATA relocatable*/
|
||||
}
|
||||
else if(reloc == TEXT)
|
||||
lblpt->flags |= SYRO; /*TEXT relocatable*/
|
||||
else if(reloc == BSS)
|
||||
lblpt->flags |= SYBS; /*BSS relocatable*/
|
||||
else if(fchr==',' && (fchr=gchr())=='r')
|
||||
lblpt->flags |= SYER; /*equated register*/
|
||||
if (refpc) /*[vlh] flag directive is pc relative */
|
||||
lblpt->flags |= SYPC;
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* process dsect directive*/
|
||||
hdsect()
|
||||
{
|
||||
dorlst(DATA);
|
||||
}
|
||||
|
||||
dorlst(xrtyp)
|
||||
int xrtyp;
|
||||
{
|
||||
inoffset = 0; /* [vlh] offset mode terminated my sect directive */
|
||||
chkeven(); /*sw adjust boundary if need be*/
|
||||
dlabl(); /*define label on old base if there is one*/
|
||||
savelc[rlflg] = loctr; /*save old base relocation*/
|
||||
rlflg = xrtyp;
|
||||
loctr = savelc[xrtyp]; /*set new base relocation ctr*/
|
||||
opitb();
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb();
|
||||
igrst();
|
||||
}
|
||||
|
||||
/*process psect directive*/
|
||||
hpsect()
|
||||
{
|
||||
dorlst(TEXT);
|
||||
}
|
||||
|
||||
hbss()
|
||||
{
|
||||
dorlst(BSS);
|
||||
}
|
||||
|
||||
/*make pc even*/
|
||||
heven()
|
||||
{
|
||||
modelen = 2; /*sw Set up so chkeven() won't barf ...*/
|
||||
if(loctr&1) { /*have to make it even*/
|
||||
dorlst(rlflg);
|
||||
}
|
||||
else {
|
||||
igrst();
|
||||
}
|
||||
}
|
||||
|
||||
/*process globl directive*/
|
||||
hent()
|
||||
{
|
||||
while(1) {
|
||||
gterm(TRUE); /*get entry symbol*/
|
||||
if(itype!=ITSY) { /*error if not symbol*/
|
||||
xerr(28);
|
||||
return;
|
||||
}
|
||||
if((lblpt=lemt(FALSE,sirt)) == lmte) /*look up in main table*/
|
||||
mmte(); /*not there, make new entry*/
|
||||
else
|
||||
if(lblpt->flags&SYER) /*already there*/
|
||||
uerr(29);
|
||||
lblpt->flags |= SYGL; /*symbol is an entry*/
|
||||
if(lblpt->flags&SYXR) /*been thru hext code*/
|
||||
lblpt->flags &= ~(SYXR|SYDF); /*reset for init of .comm*/
|
||||
if (inoffset && reloc != ABS) { /* [vlh] */
|
||||
xerr(11);
|
||||
return;
|
||||
}
|
||||
if(fchr == ',') /*skip ',' between entries*/
|
||||
fchr = gchr();
|
||||
else {
|
||||
igrst(); /*statement finished*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*process comm directive*/
|
||||
hext()
|
||||
{
|
||||
gterm(TRUE); /*get external symbol*/
|
||||
if(itype!=ITSY) { /*error if not symbol*/
|
||||
xerr(28);
|
||||
return;
|
||||
}
|
||||
if((lblpt=lemt(FALSE,sirt)) == lmte) /*look up in main table*/
|
||||
mmte(); /*not there, make new entry*/
|
||||
else
|
||||
if(lblpt->flags&SYDF && (lblpt->flags&SYXR)==0) /*already there*/
|
||||
uerr(29);
|
||||
lblpt->flags |= SYXR | SYDF; /*symbol is an external*/
|
||||
mkextidx(lblpt); /*put into external table*/
|
||||
if(fchr == ',') { /*skip ',' between operands*/
|
||||
fchr = gchr();
|
||||
gterm(TRUE);
|
||||
if(itype != ITCN) {
|
||||
xerr(17);
|
||||
return;
|
||||
}
|
||||
lblpt->vl1 = ival; /* # bytes of storage required*/
|
||||
}
|
||||
else
|
||||
lblpt->vl1 = 1; /* default # bytes*/
|
||||
igrst();
|
||||
}
|
||||
|
||||
mkextidx(p)
|
||||
struct symtab *p;
|
||||
{
|
||||
if(extindx >= EXTSZ) { /*check for overflow of external symbol tbl*/
|
||||
rpterr("overflow of external table\n");
|
||||
endit();
|
||||
}
|
||||
p->vextno = (int)(pexti - extbl); /* external symbol index #*/
|
||||
*pexti++ = p; /*save external in external table*/
|
||||
extindx++;
|
||||
}
|
||||
|
||||
/* end statement*/
|
||||
hend()
|
||||
{
|
||||
register short i;
|
||||
|
||||
inoffset = 0; /*[vlh] turn off inoffset mode*/
|
||||
lblpt = 0; /*no label*/
|
||||
opitb(); /*output beginning of statement*/
|
||||
igrst(); /* [vlh] ignore operands */
|
||||
stbuf[0].itrl = itwc; /*number of it entries*/
|
||||
wostb(); /*write out statement buffer*/
|
||||
if(pitix > itbuf) /*some it in buffer*/
|
||||
if(write(itfn,itbuf,ITBSZ*(sizeof i)) != ITBSZ*(sizeof i)) {
|
||||
rpterr("I/O write error on it file\n");
|
||||
endit();
|
||||
}
|
||||
if(initflg) {
|
||||
putsymtab();
|
||||
printf("68000 assembler initialized\n");
|
||||
endit();
|
||||
}
|
||||
if((fchr=gchr())!=EOF)
|
||||
rpterr("end statement not at end of source\n");
|
||||
savelc[rlflg] = loctr; /*last location on current reloc base*/
|
||||
fixunds(); /*make golbals and maybe undefineds external*/
|
||||
if(!didorg) /*did not assign to location counter*/
|
||||
pass1a(); /*resolve short branches*/
|
||||
pass2(); /*assembler pass 2*/
|
||||
}
|
||||
|
||||
/* define storage given number of bytes*/
|
||||
hds()
|
||||
{
|
||||
chkeven(); /*may need to make pc even*/
|
||||
dlabl(); /*define label maybe*/
|
||||
if (!inoffset) /* [vlh] */
|
||||
opitb(); /*output it for beginning of statement*/
|
||||
refpc = 0;
|
||||
expr(&p1gi);
|
||||
if(itype!=ITCN) {
|
||||
xerr(17); /*must be constant*/
|
||||
return;
|
||||
}
|
||||
if(reloc != ABS) {
|
||||
xerr(9); /*must be absolute*/
|
||||
return;
|
||||
}
|
||||
if (!inoffset) { /* [vlh] don't generate it if in offset */
|
||||
opitoo(); /*output one operand*/
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb(); /*write out statement buffer*/
|
||||
}
|
||||
loctr += (ival*modelen);
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* make pc even if necessary for .dc and .ds */
|
||||
chkeven()
|
||||
{
|
||||
register char *pi;
|
||||
|
||||
if (modelen>BYTESIZ && (loctr&1)) {
|
||||
pi = opcpt;
|
||||
opcpt = evenptr;
|
||||
opitb();
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb();
|
||||
opcpt = pi;
|
||||
loctr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* define byte directive*/
|
||||
hdc()
|
||||
{
|
||||
chkeven();
|
||||
hdata(modelen);
|
||||
}
|
||||
|
||||
/*
|
||||
* define bytes or words of data
|
||||
* call with:
|
||||
* 1 => defining bytes
|
||||
* 2 => defining words
|
||||
* 4 => defining long words
|
||||
*/
|
||||
hdata(mul)
|
||||
int mul;
|
||||
{
|
||||
dlabl(); /*define label*/
|
||||
opitb(); /*beginning of statement*/
|
||||
numops = 0; /*initialize count for number of operands*/
|
||||
opito(); /*output it for operands*/
|
||||
stbuf[0].itrl = itwc; /* # of it entries*/
|
||||
wostb(); /*write out statement buffer*/
|
||||
loctr += numops*mul; /* count by bytes or words*/
|
||||
}
|
||||
|
||||
/* handle org statement*/
|
||||
horg()
|
||||
{
|
||||
if(rlflg==TEXT && loctr!=0)
|
||||
didorg++; /*can't do branch optimization as separate pass now*/
|
||||
expr(&p1gi); /*value of new relocation counter*/
|
||||
if(reloc != rlflg && reloc != ABS) {
|
||||
xerr(27);
|
||||
return;
|
||||
}
|
||||
if(ival < loctr) {
|
||||
xerr(40); /*trying to go backwards*/
|
||||
return;
|
||||
}
|
||||
opcpt = orgptr; /*org directive for pass 2*/
|
||||
opitb();
|
||||
opitoo();
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb();
|
||||
loctr = ival;
|
||||
dlabl(); /*define label*/
|
||||
}
|
||||
|
||||
/* Assemble for mask2 (R9M), ignore... */
|
||||
hmask2() /* [vlh] */
|
||||
{
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* Define register list */
|
||||
hreg() /* [vlh] */
|
||||
{
|
||||
short mask;
|
||||
|
||||
if(lbt[0]==0) {
|
||||
xerr(4); /*no label*/
|
||||
return;
|
||||
}
|
||||
setname(); /*move label into main table*/
|
||||
if((lblpt=lemt(FALSE,sirt))!=lmte) {
|
||||
xerr(5); /*opcode redefined*/
|
||||
return;
|
||||
}
|
||||
if (inoffset)
|
||||
if (reloc != ABS) {
|
||||
xerr(11);
|
||||
return;
|
||||
}
|
||||
mmte(); /*make main table entry*/
|
||||
if ((mask = mkmask()) == -1) {
|
||||
xerr(6);
|
||||
return;
|
||||
}
|
||||
lblpt->flags |= SYDF|SYEQ|SYRM; /* register mask, defined & equated */
|
||||
lblpt->vl1 = mask;
|
||||
igrst();
|
||||
}
|
||||
|
||||
short regmsk[] = {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
|
||||
0100,040,020,010,4,2,1};
|
||||
/* make a register mask for the reg routine */
|
||||
mkmask() /* [vlh] */
|
||||
{
|
||||
register short *p, i, j, mask;
|
||||
|
||||
p = ®msk; mask = 0;
|
||||
while ((i = chkreg()) != -1) {
|
||||
if (fchr == '-') {
|
||||
fchr = gchr();
|
||||
if ((j = chkreg()) == -1) {
|
||||
xerr(40);
|
||||
return(-1);
|
||||
}
|
||||
while (i <= j)
|
||||
mask |= p[i++];
|
||||
}
|
||||
else mask |= p[i];
|
||||
if (fchr != '/' && fchr != ',') break; /*[vlh] Signetics fix*/
|
||||
fchr = gchr();
|
||||
}
|
||||
return(mask);
|
||||
}
|
||||
|
||||
/* get a register # from file, return -1 if none or illegal */
|
||||
chkreg() /* [vlh] */
|
||||
{
|
||||
register short i, j;
|
||||
|
||||
i = j = 0;
|
||||
if (fchr == 'a' || fchr == 'A')
|
||||
i = 8;
|
||||
else if (fchr != 'd' && fchr != 'r' && fchr != 'D' && fchr != 'R')
|
||||
return(-1);
|
||||
fchr = gchr();
|
||||
do {
|
||||
j = (j*10) + (fchr - '0');
|
||||
fchr = gchr();
|
||||
} while (isdigit(fchr));
|
||||
if (j < 0 || j > AREGHI) return(-1);
|
||||
i += j;
|
||||
if (i >= 0 && i <= AREGHI) return(i);
|
||||
else return(-1);
|
||||
}
|
||||
|
||||
/* Define constant block */
|
||||
hdcb() /* [vlh] */
|
||||
{
|
||||
chkeven(); /* on even boundary if not byte block. */
|
||||
dlabl(); /* define label... */
|
||||
opitb();
|
||||
opito();
|
||||
stbuf[0].itrl = itwc;
|
||||
numops = stbuf[ITOP1].itop;
|
||||
loctr += numops * modelen;
|
||||
wostb(); /* write out statement buffer */
|
||||
}
|
||||
|
||||
/* Command line, similar to ds.b */
|
||||
hcomline() /* [vlh] */
|
||||
{
|
||||
dlabl(); /*define label maybe*/
|
||||
modelen = BYTESIZ; /* byte store... */
|
||||
opitb(); /*output it for beginning of statement*/
|
||||
refpc = 0;
|
||||
expr(&p1gi);
|
||||
if(itype!=ITCN) {
|
||||
xerr(17); /*must be constant*/
|
||||
return;
|
||||
}
|
||||
if(reloc != ABS) {
|
||||
xerr(9); /*must be absolute*/
|
||||
return;
|
||||
}
|
||||
opitoo(); /*output one operand*/
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb(); /*write out statement buffer*/
|
||||
loctr += ival;
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* Relocateable id record, ignore */
|
||||
hidnt() /* [vlh] */
|
||||
{
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* Define offsets */
|
||||
hoffset() /* [vlh] */
|
||||
{
|
||||
inoffset = 1;
|
||||
expr(&p1gi); /* get new location counter */
|
||||
if (itype != ITCN) {
|
||||
xerr(17); /* constant required */
|
||||
return;
|
||||
}
|
||||
if (reloc != ABS) {
|
||||
xerr(9); /* must be absolute */
|
||||
return;
|
||||
}
|
||||
savelc[rlflg] = loctr; /* Save old section loctr */
|
||||
loctr = ival;
|
||||
rlflg = ABS; /* This section is absolute */
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* define sections: map to bss, text and data */
|
||||
hsection() /* [vlh] */
|
||||
{
|
||||
inoffset = 0; /* reseting section turns off offset mode */
|
||||
dlabl(); /* define label on old base if there is one */
|
||||
savelc[rlflg] = loctr; /* save old base relocation */
|
||||
opitb(); /* intermediate table... */
|
||||
expr(&p1gi); /* get section # */
|
||||
if (itype != ITCN) {
|
||||
xerr(17); /* must be a constant */
|
||||
return;
|
||||
}
|
||||
if (ival > 15 || ival < 0) {
|
||||
xerr(9); /* proper range 0..15 */
|
||||
return;
|
||||
}
|
||||
rlflg = (ival==14) ? DATA : (ival==15) ? BSS : TEXT;
|
||||
loctr = savelc[rlflg];
|
||||
stbuf[3].itop = loctr; /* pass 1 location counter */
|
||||
stbuf[3].itrl = rlflg; /* relocation base */
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb();
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* hopt -- ignore, set up assembler options */
|
||||
hopt() /* vlh */
|
||||
{
|
||||
igrst();
|
||||
}
|
||||
#ifndef CPM /*sw*/
|
||||
/* hpage - page directive, ignore */
|
||||
hpage() /* vlh */
|
||||
{
|
||||
igrst();
|
||||
}
|
||||
spage()
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* httl - title directive, ignore */
|
||||
httl() /* vlh */
|
||||
{
|
||||
igrst();
|
||||
}
|
||||
|
||||
/**** Second pass directive handling routines ****/
|
||||
|
||||
/* second pass end statement*/
|
||||
send()
|
||||
{
|
||||
register short i;
|
||||
|
||||
savelc[rlflg] = loctr;
|
||||
if(savelc[TEXT]&1) {
|
||||
rlflg = TEXT;
|
||||
outbyte(0,DABS);
|
||||
savelc[TEXT]++; /*SW need correct count here*/
|
||||
}
|
||||
if(savelc[DATA]&1) {
|
||||
rlflg = DATA;
|
||||
outbyte(0,DABS);
|
||||
savelc[DATA]++; /*SW need correct count here*/
|
||||
}
|
||||
if(savelc[BSS]&1) {
|
||||
savelc[BSS]++;
|
||||
}
|
||||
ival = 0;
|
||||
reloc = ABS;
|
||||
ckeop(9);
|
||||
print(0);
|
||||
cpdata(); /*copy data to loader file*/
|
||||
osymt(); /*output symbol table*/
|
||||
myfflush(&tbuf); /*flush text relocation bits*/
|
||||
cprlbits(); /*copy relocation bits*/
|
||||
myfflush(&lbuf);
|
||||
i = (sizeof couthd.ch_magic) + 3*(sizeof couthd.ch_tsize);
|
||||
if((lseek(lfn,(long)i,0) == -1L) || /*sw */
|
||||
write(lfn,&stlen,sizeof(stlen)) !=sizeof(stlen))
|
||||
rpterr("I/O error on loader output file\n");
|
||||
endit(); /*end*/
|
||||
}
|
||||
|
||||
/*second pass define storage - ds*/
|
||||
sds()
|
||||
{
|
||||
print(0);
|
||||
if(rlflg == TEXT || rlflg==DATA) {
|
||||
expr(&p2gi);
|
||||
if(itype != ITCN) {
|
||||
uerr(13);
|
||||
return;
|
||||
}
|
||||
ival *= modelen;
|
||||
while(ival) {
|
||||
outbyte(0,DABS);
|
||||
loctr++;
|
||||
ival--;
|
||||
}
|
||||
}
|
||||
else
|
||||
loctr += stbuf[ITOP1].itop*modelen; /*reserve storage*/
|
||||
}
|
||||
|
||||
/* second pass - define block storage, initialized */
|
||||
sdcb() /* [vlh] */
|
||||
{
|
||||
register short pfg, i, hflg, len;
|
||||
|
||||
i = pfg = hflg = 0;
|
||||
expr(&p2gi);
|
||||
if (itype != ITCN || reloc != ABS) {
|
||||
uerr(13); /* must be absolute constant */
|
||||
return;
|
||||
}
|
||||
len = ival;
|
||||
expr(&p2gi);
|
||||
if (modelen == BYTESIZ && (ival<-128 || ival>=256 || reloc != ABS)) {
|
||||
uerr(20);
|
||||
ival = 0;
|
||||
reloc = ABS;
|
||||
}
|
||||
while (len--) {
|
||||
if (modelen == BYTESIZ) {
|
||||
if (!hflg) {
|
||||
ins[i].hibyte = ival;
|
||||
outbyte((int)ival.loword,DABS);
|
||||
hflg++;
|
||||
}
|
||||
else {
|
||||
ins[i++].lobyte = ival;
|
||||
outbyte((int)ival.loword,DABS);
|
||||
hflg=0;
|
||||
}
|
||||
goto sdbl2;
|
||||
}
|
||||
else if (modelen == WORDSIZ) {
|
||||
sdbl1:
|
||||
ins[i++] = ival.loword;
|
||||
outword((int)ival.loword, reloc);
|
||||
sdbl2:
|
||||
if (i>3) {
|
||||
instrlen = i*2;
|
||||
print ((pfg++) ? 2 : 1);
|
||||
loctr += instrlen;
|
||||
i=0;
|
||||
}
|
||||
}
|
||||
else { /* long word... */
|
||||
ins[i++] = ival.hiword;
|
||||
outword((int)ival.hiword,LUPPER);
|
||||
goto sdbl1;
|
||||
}
|
||||
}
|
||||
if (i) { /* more printing */
|
||||
instrlen = i*2 - hflg;
|
||||
print ((pfg) ? 2 : 1);
|
||||
loctr += instrlen;
|
||||
}
|
||||
}
|
||||
|
||||
/*second pass data*/
|
||||
sdsect()
|
||||
{
|
||||
savelc[rlflg] = loctr;
|
||||
rlflg = DATA;
|
||||
loctr = savelc[DATA];
|
||||
print(0); /*print the new location counter*/
|
||||
}
|
||||
|
||||
/*second pass text*/
|
||||
spsect()
|
||||
{
|
||||
savelc[rlflg] = loctr;
|
||||
rlflg = TEXT;
|
||||
loctr = savelc[TEXT];
|
||||
print(0); /*print the new location counter*/
|
||||
}
|
||||
|
||||
sbss()
|
||||
{
|
||||
savelc[rlflg] = loctr;
|
||||
rlflg = BSS;
|
||||
loctr = savelc[BSS];
|
||||
print(0); /*print the new location counter*/
|
||||
}
|
||||
|
||||
/* make loctr even*/
|
||||
seven()
|
||||
{
|
||||
if(loctr&1) {
|
||||
if(rlflg==TEXT || rlflg==DATA)
|
||||
outbyte(0,DABS);
|
||||
loctr++;
|
||||
}
|
||||
print(0);
|
||||
}
|
||||
|
||||
/* second pass org*/
|
||||
sorg()
|
||||
{
|
||||
register long l;
|
||||
|
||||
if(rlflg==TEXT || rlflg==DATA) { /*must put out zeros*/
|
||||
l = stbuf[ITOP1].itop - loctr; /*# zeroes to output*/
|
||||
ins[0] = 0;
|
||||
print(1);
|
||||
while(l > 0) {
|
||||
outbyte(0,DABS);
|
||||
loctr++;
|
||||
l--;
|
||||
}
|
||||
}
|
||||
else { /*BSS*/
|
||||
loctr = stbuf[ITOP1].itop; /*new location counter*/
|
||||
print(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*second pass define data (words or bytes)
|
||||
* call with
|
||||
* 2 => defining words
|
||||
* 1 => defining bytes
|
||||
* 4 => defining long words
|
||||
*/
|
||||
sdata(dtyp)
|
||||
int dtyp;
|
||||
{
|
||||
register short pfg,i, hflg;
|
||||
|
||||
hflg = i = pfg = 0;
|
||||
while(1) {
|
||||
expr(&p2gi); /*evaluate expression*/
|
||||
if(pitw < pnite)
|
||||
pitw--; /*expr passed a token*/
|
||||
if(itype!=ITCN && reloc != EXTRN) { /*must be constant*/
|
||||
uerr(13);
|
||||
ival=0;
|
||||
reloc = ABS;
|
||||
}
|
||||
if(reloc == EXTRN)
|
||||
reloc = (extref<<3)|EXTVAR; /*gen extern reference*/
|
||||
if(dtyp==1) { /*defining a byte*/
|
||||
if(ival<-128 || ival>=256 || reloc!=ABS) { /*not a byte*/
|
||||
uerr(20);
|
||||
ival=0;
|
||||
reloc = ABS;
|
||||
}
|
||||
if(!hflg) {
|
||||
ins[i].hibyte = ival;
|
||||
outbyte((int)ival.loword,DABS);
|
||||
hflg++;
|
||||
}
|
||||
else {
|
||||
ins[i++].lobyte = ival;
|
||||
hflg = 0;
|
||||
outbyte((int)ival.loword,DABS);
|
||||
}
|
||||
goto sdal2;
|
||||
}
|
||||
else if(dtyp == 2) { /*defining a word*/
|
||||
sdal1:
|
||||
ins[i++] = ival.loword;
|
||||
outword((int)ival.loword, reloc);
|
||||
sdal2:
|
||||
if(i>3) {
|
||||
instrlen = i*2;
|
||||
print ((pfg++) ? 2 : 1);
|
||||
loctr += instrlen;
|
||||
i=0;
|
||||
}
|
||||
}
|
||||
else { /*long words*/
|
||||
ins[i++] = ival.hiword;
|
||||
outword((int)ival.hiword,LUPPER);
|
||||
goto sdal1;
|
||||
}
|
||||
if(!ckeop(15)) /*should be end of operand*/
|
||||
return;
|
||||
pitw++;
|
||||
if(ckein()) {
|
||||
if(hflg) {
|
||||
ins[i++].lobyte = 0;
|
||||
}
|
||||
if(i) { /*more printing*/
|
||||
instrlen = i*2 - hflg;
|
||||
print ((pfg) ? 2 : 1);
|
||||
loctr += instrlen;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sdc()
|
||||
{
|
||||
sdata(modelen);
|
||||
}
|
||||
|
||||
ssection() /* [vlh] */
|
||||
{
|
||||
short sect;
|
||||
|
||||
sect = stbuf[3].itrl;
|
||||
if (sect==DATA)
|
||||
sdsect();
|
||||
else if (sect==BSS)
|
||||
sbss();
|
||||
else
|
||||
spsect();
|
||||
}
|
||||
|
||||
/**** Conditional assembly directives ****/
|
||||
|
||||
hifeq() /* [vlh] */
|
||||
{
|
||||
if (!acok())
|
||||
return;
|
||||
if (ival) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifne() /* [vlh] */
|
||||
{
|
||||
if (!acok())
|
||||
return;
|
||||
if (!ival) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hiflt() /* [vlh] */
|
||||
{
|
||||
if (!acok())
|
||||
return;
|
||||
if (ival >= 0) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifle() /* [vlh] */
|
||||
{
|
||||
if (!acok())
|
||||
return;
|
||||
if (ival > 0) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifgt() /* [vlh] */
|
||||
{
|
||||
if (!acok())
|
||||
return;
|
||||
if (ival <= 0) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifge() /* [vlh] */
|
||||
{
|
||||
if (!acok())
|
||||
return;
|
||||
if (ival < 0) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifc() /* [vlh] */
|
||||
{
|
||||
if (!cmp_ops()) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifnc() /* [vlh] */
|
||||
{
|
||||
if (cmp_ops()) {
|
||||
if (ca_true)
|
||||
ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hendc() /* [vlh] */
|
||||
{
|
||||
if (!ca) {
|
||||
xerr(25); /* unexpected endc */
|
||||
return;
|
||||
}
|
||||
ca--;
|
||||
if (!ca_true)
|
||||
if (ca_level == ca) ca_true = 1;
|
||||
igrst();
|
||||
}
|
||||
|
||||
acok()
|
||||
{
|
||||
expr(&p1gi);
|
||||
if (itype != ITCN) {
|
||||
xerr(7); /* must be a constant */
|
||||
return(0);
|
||||
}
|
||||
if (reloc != ABS) {
|
||||
xerr(11); /* must be absolute, no forward references */
|
||||
return(0);
|
||||
}
|
||||
igrst();
|
||||
return(1);
|
||||
}
|
||||
|
||||
cmp_ops() /* return 1 true, 0 false */
|
||||
{
|
||||
char str1[25], str2[25];
|
||||
register short len1, len2;
|
||||
|
||||
if (fchr != '\'') {
|
||||
xerr(9);
|
||||
return(0);
|
||||
}
|
||||
len1 = len2 = 0;
|
||||
while ((fchr = gchr()) && fchr != '\'') {
|
||||
if (fchr == EOLC)
|
||||
return(0);
|
||||
str1[len1++] = fchr;
|
||||
}
|
||||
if ((fchr=gchr()) != ',') {
|
||||
xerr(9);
|
||||
return(0);
|
||||
}
|
||||
if ((fchr=gchr()) != '\'') {
|
||||
xerr(10);
|
||||
return(0);
|
||||
}
|
||||
while ((fchr = gchr()) && fchr != '\'') {
|
||||
if (fchr == EOLC)
|
||||
return(0);
|
||||
str2[len2++] = fchr;
|
||||
}
|
||||
igrst();
|
||||
if (len1 != len2)
|
||||
return(0);
|
||||
str1[len1] = str2[len2] = NULL;
|
||||
return((strcmp(str1,str2) == 0));
|
||||
}
|
||||
|
||||
strcmp(s,t)
|
||||
register char *s, *t;
|
||||
{
|
||||
for( ; *s == *t; s++, t++ )
|
||||
if( *s == '\0' )
|
||||
return(0);
|
||||
return( *s - *t );
|
||||
}
|
||||
511
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/expr.c
Normal file
511
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/expr.c
Normal file
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/* Expression evaluator */
|
||||
|
||||
# include "as68.h"
|
||||
|
||||
/*precedence of operators*/
|
||||
# define PAO 2 /*AND, OR*/
|
||||
# define PPM 2 /*+ -*/
|
||||
# define PMD 3 /** /*/
|
||||
# define PLP 1 /* (*/
|
||||
# define PRP 4 /* )*/
|
||||
# define PEE 0 /* all other special chars*/
|
||||
|
||||
#define OPSTLEN 10
|
||||
#define TREELEN 20
|
||||
|
||||
/*global short's for this package*/
|
||||
struct it exitm; /*expression item*/
|
||||
short prcnt; /*paren count*/
|
||||
short rval; /*relocation value*/
|
||||
short lpflg;
|
||||
short lastopr; /*last token was operator when set*/
|
||||
|
||||
long gval(); /*get operand value*/
|
||||
|
||||
/*
|
||||
* expression evaluator
|
||||
* call with:
|
||||
* address of function to get input
|
||||
* returns:
|
||||
* item type in itype
|
||||
* item value in ival
|
||||
* relocation flag in reloc:
|
||||
* 0 => absolute
|
||||
* 1 => data
|
||||
* 2 => text
|
||||
* 3 => bss
|
||||
* 4 => external
|
||||
*
|
||||
* The only expressions involving externals which are legal are
|
||||
* external+constant or external-constant
|
||||
*/
|
||||
|
||||
struct it *piop, *pitr;
|
||||
short iop, itr;
|
||||
|
||||
struct it opstk[OPSTLEN]; /*operator stack*/
|
||||
struct it tree[TREELEN]; /*operand stack*/
|
||||
|
||||
expr(iploc)
|
||||
int (*iploc)();
|
||||
{
|
||||
register short i, ipr;
|
||||
|
||||
extflg = starmul = iop = lpflg = 0;
|
||||
piop = &opstk[0];
|
||||
itr = -1; /*tree stack pointer*/
|
||||
pitr = &tree[0];
|
||||
pitr--;
|
||||
/* form end of expression operator*/
|
||||
opstk[0].itty = ITSP; /*special character*/
|
||||
opstk[0].itop.loword = '?'; /*sw For Whitesmith's */
|
||||
lastopr = 1;
|
||||
|
||||
/* get an input item*/
|
||||
while(1) {
|
||||
if(itr >= TREELEN-2) {
|
||||
rpterr("expr tree overflow\n");
|
||||
abort();
|
||||
}
|
||||
if(iop >= OPSTLEN-1) {
|
||||
rpterr("expr opstk overflow\n");
|
||||
abort();
|
||||
}
|
||||
(*iploc)(); /*get an input term*/
|
||||
if (itype==ITPC) return;
|
||||
starmul=0; /* * is location counter*/
|
||||
|
||||
/* special character*/
|
||||
if(itype==ITSP) {
|
||||
ipr = gprc(i=(int)ival.loword); /*get precedence of character*/
|
||||
if(ipr==PEE) /*end of expression*/
|
||||
break;
|
||||
lastopr = 1;
|
||||
if(ipr==PLP) { /*left paren*/
|
||||
lpflg++;
|
||||
prcnt++;
|
||||
iop++; /*up stack pointer*/
|
||||
piop++;
|
||||
piop->swd1=exitm.swd1; /*put operator on stack*/
|
||||
piop->itop=exitm.itop;
|
||||
continue;
|
||||
}
|
||||
if(ipr==PRP) { /*right paren*/
|
||||
if(lpflg) { exerr(); return; }
|
||||
starmul = 1; /* * is multiply*/
|
||||
prcnt--; /*down one level*/
|
||||
|
||||
while (piop->itop != '(') { /* top stk is '(' */
|
||||
itr++; /*up tree pointer*/
|
||||
pitr++;
|
||||
pitr->swd1 = piop->swd1; /*move operator*/
|
||||
pitr->itop = piop->itop;
|
||||
iop--; /*reduce operand stack*/
|
||||
piop--;
|
||||
}
|
||||
iop--; /*remove stack*/
|
||||
piop--;
|
||||
continue;
|
||||
}
|
||||
|
||||
while(ipr<=gprc(i=(int)piop->itop.loword)) { /* >= precedence */
|
||||
itr++;
|
||||
pitr++;
|
||||
pitr->swd1 = piop->swd1; /*move operator*/
|
||||
pitr->itop = piop->itop;
|
||||
iop--; /*reduce operand stack*/
|
||||
piop--;
|
||||
}
|
||||
iop++; /*up operator stack*/
|
||||
piop++;
|
||||
piop->swd1 = exitm.swd1; /*put in operator stack*/
|
||||
piop->itop = exitm.itop;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* symbol or constant*/
|
||||
else {
|
||||
lastopr = lpflg = 0; /*clear flag*/
|
||||
itr++; /*up tree pointer*/
|
||||
pitr++;
|
||||
pitr->swd1 = exitm.swd1; /*put in tree*/
|
||||
pitr->itop = exitm.itop;
|
||||
starmul = 1; /* * is multiply*/
|
||||
continue;
|
||||
}
|
||||
} /* end while(1)... */
|
||||
|
||||
/*output the rest of the operator stack to the tree*/
|
||||
for(i=iop; i>=0; i--) {
|
||||
itr++;
|
||||
pitr++;
|
||||
pitr->swd1 = piop->swd1; /*move operator*/
|
||||
pitr->itop = piop->itop;
|
||||
piop--;
|
||||
}
|
||||
|
||||
collapse();
|
||||
}
|
||||
|
||||
/* collapse the tree into one entry*/
|
||||
collapse()
|
||||
{
|
||||
register short rv1, rv2, topr, i, bos, low;
|
||||
register long tv1;
|
||||
long tv2;
|
||||
|
||||
bos = 0;
|
||||
exct1:
|
||||
if(itr>=3) {
|
||||
piop = &tree[bos];
|
||||
iop = bos;
|
||||
while (iop<=(itr-3+bos) && (piop->itty==ITSP ||
|
||||
(piop+1)->itty==ITSP || (piop+2)->itty!=ITSP)) {
|
||||
iop++;
|
||||
piop++;
|
||||
}
|
||||
if (iop<=(itr-3+bos)) {
|
||||
tv1 = gval(piop); /*get value of first operand*/
|
||||
rv1 = rval; /*relocation value*/
|
||||
tv2 = gval(piop+1);
|
||||
rv2 = rval;
|
||||
topr = (piop+2)->itop; /*operator*/
|
||||
|
||||
/* handle operators */
|
||||
if (topr == '+') {
|
||||
tv1+= tv2;
|
||||
rv1 = ckrl1(rv1,rv2); /*relocation*/
|
||||
}
|
||||
else if (topr == '-') {
|
||||
tv1 -= tv2;
|
||||
rv1 = ckrl2(rv1,rv2); /*relocation*/
|
||||
}
|
||||
else {
|
||||
switch(topr) { /*operator*/
|
||||
case '/': /* division */
|
||||
tv1 /= tv2; break;
|
||||
case '*': /* multiplication */
|
||||
tv1 *= tv2; break;
|
||||
case '&': /* logical and */
|
||||
tv1 &= tv2; break;
|
||||
case '!': /* logical or */
|
||||
tv1 |= tv2; break;
|
||||
case '<': /* left shift */
|
||||
low = tv2.loword;
|
||||
tv1 <<= low; break;
|
||||
case '>': /* right shift */
|
||||
low = tv2.loword;
|
||||
tv1 >>= low; break;
|
||||
default: /*invalid operator*/
|
||||
exerr(); return;
|
||||
}
|
||||
rv1 = ckrl3(rv1,rv2); /* relocation */
|
||||
}
|
||||
|
||||
/*put new value in tree*/
|
||||
if (iop==bos) {
|
||||
bos += 2;
|
||||
iop = bos;
|
||||
}
|
||||
piop = &tree[iop];
|
||||
piop->itty = ITCN; /*must be constant*/
|
||||
piop->itop = tv1; /*value*/
|
||||
piop->itrl = rv1; /*relocation value*/
|
||||
|
||||
if (iop != bos) { /* push up the rest of the tree... */
|
||||
i = iop + 2 - bos;
|
||||
pitr = piop+2;
|
||||
for(; i<itr; i++) {
|
||||
piop++;
|
||||
pitr++;
|
||||
piop->swd1 = pitr->swd1;
|
||||
piop->itop = pitr->itop;
|
||||
}
|
||||
}
|
||||
itr -= 2;
|
||||
goto exct1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for unary minus and unary plus*/
|
||||
if (tree[bos+1].itty!=ITSP && tree[bos].itop.loword=='?')
|
||||
{ exerr(); return; }
|
||||
if (tree[bos+1].itty!=ITSP || tree[bos].itty==ITSP) {
|
||||
reloc = ABS;
|
||||
ival = 0;
|
||||
itype = ITCN;
|
||||
return;
|
||||
}
|
||||
|
||||
if(tree[bos+1].itop.loword!='?') { /*end of statement*/
|
||||
if(tree[bos+1].itop.loword!='+') { /*ignore unary plus*/
|
||||
if(tree[bos+1].itop.loword!='-') { /* invalid operator */
|
||||
exerr();
|
||||
return;
|
||||
}
|
||||
tree[bos+1].itop = -gval(&tree[bos]);
|
||||
tree[bos+1].itty = ITCN;
|
||||
tree[bos+1].itrl = tree[bos].itrl;
|
||||
bos++;
|
||||
itr--;
|
||||
goto exct1;
|
||||
}
|
||||
}
|
||||
/* send results back to caller*/
|
||||
if ((itype = tree[bos].itty)==ITCN)
|
||||
ival = gval(&tree[bos]);
|
||||
else {
|
||||
ival = tree[bos].itop;
|
||||
if(itype==ITSY && !(ival.ptrw2->flags&SYDF)) { /*undef symbol*/
|
||||
reloc = ABS;
|
||||
ival = 0;
|
||||
itype = ITCN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
get_val(tree[bos].itrl);
|
||||
}
|
||||
|
||||
/*
|
||||
*if defined symbol get value and say constant
|
||||
* except for externals and equated registers
|
||||
*/
|
||||
get_val(reloc_val)
|
||||
int reloc_val;
|
||||
{
|
||||
if(itype==ITSY && (ival.ptrw2->flags&(SYXR|SYER))==0) {
|
||||
if(ival.ptrw2->flags&SYRA) /*get symbol relocation factor*/
|
||||
reloc = DATA;
|
||||
else if(ival.ptrw2->flags&SYRO)
|
||||
reloc = TEXT;
|
||||
else if(ival.ptrw2->flags&SYBS)
|
||||
reloc = BSS;
|
||||
else reloc = ABS;
|
||||
ival = ival.ptrw2->vl1; /*symbol vaue*/
|
||||
itype = ITCN; /*constant*/
|
||||
}
|
||||
else
|
||||
if(itype == ITSY && ival.ptrw2->flags&SYXR) { /*external symbol*/
|
||||
fixext(ival.ptrw2);
|
||||
reloc = EXTRN;
|
||||
}
|
||||
else
|
||||
reloc = reloc_val; /*relocation value of item*/
|
||||
}
|
||||
|
||||
exerr() /* [vlh] */
|
||||
{
|
||||
uerr(6);
|
||||
ival = 0;
|
||||
itype = ITCN;
|
||||
reloc = ABS;
|
||||
}
|
||||
|
||||
/*
|
||||
* get precedence of a operator
|
||||
* call with
|
||||
* operator
|
||||
* returns
|
||||
* precedence
|
||||
*/
|
||||
gprc(dprc)
|
||||
int dprc;
|
||||
{
|
||||
switch(dprc) {
|
||||
|
||||
case '+':
|
||||
case '-':
|
||||
case '&': /* and*/
|
||||
case '!': /* or*/
|
||||
case '^': /*exclusive or*/
|
||||
return(PPM);
|
||||
|
||||
case '/':
|
||||
case '*':
|
||||
case '<': /*left shift*/
|
||||
case '>': /*right shift*/
|
||||
return(PMD);
|
||||
|
||||
case '(':
|
||||
if(lastopr)
|
||||
return(PLP);
|
||||
break;
|
||||
|
||||
case ')':
|
||||
if(!prcnt) /*no left parens*/
|
||||
break;
|
||||
return(PRP);
|
||||
|
||||
}
|
||||
return(PEE); /*end of expression*/
|
||||
}
|
||||
|
||||
/*
|
||||
* get value from an it format item
|
||||
* call with
|
||||
* address of it format item
|
||||
* returns
|
||||
* the value
|
||||
* relocation value in rval
|
||||
* calls uerr if it cant get a value
|
||||
*/
|
||||
long gval(avwrd)
|
||||
struct it *avwrd;
|
||||
{
|
||||
register struct it *vwrd;
|
||||
register struct symtab *p;
|
||||
|
||||
vwrd = avwrd;
|
||||
if(vwrd->itty == ITCN) { /*constant*/
|
||||
rval = vwrd->itrl;
|
||||
return(vwrd->itop); /*value*/
|
||||
}
|
||||
if(vwrd->itty != ITSY) {
|
||||
uerr(6);
|
||||
rval = ABS;
|
||||
return(0);
|
||||
}
|
||||
p = vwrd->itop.ptrw2;
|
||||
if(p->flags&SYXR) { /*external reference*/
|
||||
fixext(p);
|
||||
return(0);
|
||||
}
|
||||
if((p->flags&SYDF) != SYDF || (p->flags&SYER)) {
|
||||
uerr(6);
|
||||
rval = ABS;
|
||||
return(0);
|
||||
}
|
||||
rval = (p->flags&SYRA) ? DATA : (p->flags&SYRO) /* reloc of item */
|
||||
? TEXT : (p->flags&SYBS) ? BSS : ABS;
|
||||
return(p->vl1);
|
||||
}
|
||||
|
||||
/*
|
||||
* get items for expression evaluator (pass one)
|
||||
* returns:
|
||||
* item type in itype
|
||||
* item value in ival
|
||||
* item in it format in exitm
|
||||
*/
|
||||
p1gi()
|
||||
{
|
||||
if(fcflg) /*used item so must pass it*/
|
||||
gterm(TRUE);
|
||||
if(!fcflg && ckspc(fchr)==1) {
|
||||
fcflg=1; /*just pass first character*/
|
||||
itype=ITSP; /*special char*/
|
||||
ival=fchr; /*value is the char*/
|
||||
}
|
||||
else { /*get a whole term*/
|
||||
fcflg = 0;
|
||||
gterm(TRUE); /*get a term*/
|
||||
if(itype==ITSY) { /* got a symbol*/
|
||||
ival.ptrw2=lemt(FALSE,sirt); /*look up in main table*/
|
||||
if(ival.ptrw2==lmte) /*not there before*/
|
||||
mmte(); /*put it in table*/
|
||||
}
|
||||
else
|
||||
if(itype == ITCN)
|
||||
exitm.itrl = reloc;
|
||||
}
|
||||
exitm.itty = itype;
|
||||
exitm.itop = ival;
|
||||
}
|
||||
|
||||
/*
|
||||
* get items for expression evaluator (pass 2)
|
||||
* returns:
|
||||
* item type in itype
|
||||
* item value in ival
|
||||
* item in it format in exitm
|
||||
*/
|
||||
p2gi()
|
||||
{
|
||||
if(pitw==pnite) { /*end of statement*/
|
||||
itype = ITSP;
|
||||
ival = ' '; /*blank*/
|
||||
exitm.itty = itype;
|
||||
exitm.itop = ival;
|
||||
return;
|
||||
}
|
||||
|
||||
if((itype = pitw->itty) == ITPC) { /*vlh*/
|
||||
pitw->itop = loctr;
|
||||
if (p2flg || format==6) itype = pitw->itty = ITCN;
|
||||
}
|
||||
ival = pitw->itop; /*value*/
|
||||
exitm.swd1 = pitw->swd1;
|
||||
exitm.itop = ival;
|
||||
pitw++;
|
||||
}
|
||||
|
||||
/*
|
||||
*check for a special character
|
||||
* call with
|
||||
* character to check
|
||||
* returns:
|
||||
* 0 => character is number or letter
|
||||
*/
|
||||
ckspc(acksc)
|
||||
int acksc;
|
||||
{
|
||||
register short cksc;
|
||||
|
||||
cksc = acksc;
|
||||
if (isalnum(cksc)) return(0);
|
||||
return((index("_~*.@$%\'",cksc) != -1) ? 0 : 1); /*[vlh] compacted*/
|
||||
}
|
||||
|
||||
/* generate new relocation for op + op*/
|
||||
ckrl1(rv1,rv2)
|
||||
int rv1, rv2;
|
||||
{
|
||||
if(rv1==rv2)
|
||||
return(rv1);
|
||||
if(rv1==ABS || rv2==ABS)
|
||||
return(rv1+rv2); /*the one that is not ABS*/
|
||||
uerr(27);
|
||||
return(ABS);
|
||||
}
|
||||
|
||||
/*generate new relocation for op - op*/
|
||||
ckrl2(rv1,rv2)
|
||||
int rv1, rv2;
|
||||
{
|
||||
if(rv2==EXTRN)
|
||||
uerr(26);
|
||||
if(rv1==rv2)
|
||||
return(ABS);
|
||||
if(rv2==ABS)
|
||||
return(rv1+rv2);
|
||||
uerr(27);
|
||||
return(ABS);
|
||||
}
|
||||
|
||||
/*generate new relocation for op /*&|<>^! op*/
|
||||
ckrl3(rv1,rv2)
|
||||
int rv1, rv2;
|
||||
{
|
||||
if(rv1!=ABS || rv2!=ABS)
|
||||
uerr(27);
|
||||
return(ABS);
|
||||
}
|
||||
|
||||
fixext(p)
|
||||
struct symtab *p;
|
||||
{
|
||||
if(extflg)
|
||||
uerr(36); /*two externals in expr*/
|
||||
extflg++;
|
||||
extref = p->vextno; /*get external #*/
|
||||
rval = EXTRN;
|
||||
itype = ITCN;
|
||||
ival = 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
$2lo68 -r -s -o as68.rel -u_nofloat -f $1 0$1s.o *.o 0$2klib 0$2clib
|
||||
era *.o
|
||||
user 10!make $1 $2
|
||||
199
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/list.c
Normal file
199
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/list.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Put all the listing stuff in here
|
||||
*/
|
||||
#include "as68.h"
|
||||
#define LPP 58 /* # Lines per listing page */
|
||||
int xline = LPP; /* Current line on page */
|
||||
int xpage = 0; /* Current page # */
|
||||
short pline; /* Current listing line # */
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* .page directive handlers (from dir.c). */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
hpage() /* Pass 1 .page routine */
|
||||
{ /************************************/
|
||||
opitb(); /* Output statement beginning */
|
||||
wostb(); /* Remaining part of statement */
|
||||
igrst(); /* Ignore optional comment */
|
||||
} /************************************/
|
||||
spage() /* Pass 2 .page routine */
|
||||
{ /************************************/
|
||||
print(0); /* Print directive line */
|
||||
xline = LPP; /* Force top of */
|
||||
page(); /* Listing page */
|
||||
} /************************************/
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* Symbol table print routine. "psyms" is called AFTER the symbol table */
|
||||
/* has been output to the loader file. We sort the symbol table, and print*/
|
||||
/* the sorted table in PDP-11ish (RT-11) fashion, with a reasonable format */
|
||||
/* for the symbols. */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
psyms() /* */
|
||||
{ /****************************/
|
||||
register long j; /* Temporary */
|
||||
register char *p; /* -> Symbol table entries */
|
||||
int symcmp(); /* Symbol comparison func. */
|
||||
/****************************/
|
||||
xline = LPP; /* Force page */
|
||||
page(); /* Eject */
|
||||
printf("S y m b o l T a b l e\n\n"); /* Print Header */
|
||||
xline++; /* Bump line counter */
|
||||
j = ((lmte-bmte)/STESIZE); /* Compute # elements */
|
||||
qsort(bmte,(int)j,STESIZE,symcmp); /* Sort'em */
|
||||
j = 0; /* Count symbols / line */
|
||||
for(p = bmte; p < lmte; p += STESIZE) /* Loop through symbol table*/
|
||||
{ /* */
|
||||
if(j > 3) /* 4 Symbols / line */
|
||||
{ /* */
|
||||
printf("\n"); /* Print newline */
|
||||
page(); /* Check for top of page */
|
||||
j = 0; /* Reset counter */
|
||||
} /****************************/
|
||||
j += psyme(p); /* Print 1 table entry */
|
||||
} /* (maybe) */
|
||||
if(j <= 3) /* Partial line? */
|
||||
printf("\n"); /* Yes, finish it */
|
||||
} /****************************/
|
||||
symcmp(a,b) /* Qsort comparison function*/
|
||||
register char *a,*b; /* -> Elts to compare */
|
||||
{ /****************************/
|
||||
return(strncmp(a,b,NAMELEN)); /* Return +1 for a > b */
|
||||
/* 0 for a = b */
|
||||
/* -1 for a < b */
|
||||
} /****************************/
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* Psyme function. This function prints a single symbol table entry on */
|
||||
/* the listing file, complete with TEXT, DATA, BSS, EXT, or UNDEF tag. */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
psyme(osypt) /* Call with -> ST entry */
|
||||
register struct symtab *osypt; /****************************/
|
||||
{ /* */
|
||||
register char *p; /* -> Name field */
|
||||
register int i; /* Count register */
|
||||
/****************************/
|
||||
if((osypt->flags & SYER) != 0 || /* Do we need to print it? */
|
||||
(osypt->flags & SYIN)) /* */
|
||||
return(0); /* No. */
|
||||
/****************************/
|
||||
p = &(osypt->name[0]); /* p -> Symbol name field */
|
||||
for(i=0;i<NAMELEN;i++) /* Print name */
|
||||
{ /* */
|
||||
if(*p) /* Non-null character? */
|
||||
putchar(*p); /* Yes, print */
|
||||
else /* No */
|
||||
putchar(' '); /* print blank */
|
||||
p++; /* Bump pointer */
|
||||
} /****************************/
|
||||
/* */
|
||||
printf(" "); /* Align descriptor */
|
||||
if(osypt->flags & SYXR) /* External Reference? */
|
||||
{ /* */
|
||||
printf("******** EXT "); /* Macro-11 style. */
|
||||
return(1); /* */
|
||||
} /****************************/
|
||||
if(osypt->flags & SYDF) /* Defined? */
|
||||
{ /* */
|
||||
puthex(osypt->vl1.hiword,4); /* Print high word */
|
||||
puthex(osypt->vl1.loword,4); /* And low word */
|
||||
if(osypt->flags & SYRA) /* DATA? */
|
||||
printf(" DATA "); /* Yes. */
|
||||
else if(osypt->flags & SYRO) /* TEXT? */
|
||||
printf(" TEXT "); /* Yes. */
|
||||
else if(osypt->flags & SYBS) /* BSS? */
|
||||
printf(" BSS "); /* Yes. */
|
||||
else printf(" ABS "); /* Then it must be absolute */
|
||||
} /****************************/
|
||||
else /* */
|
||||
{ /* */
|
||||
nerror++; /* Bump Error count */
|
||||
printf("*UNDEFINED* "); /* Identify FUBAR */
|
||||
} /* */
|
||||
return(1); /* */
|
||||
} /****************************/
|
||||
|
||||
/*
|
||||
* output source and object listing
|
||||
* call with
|
||||
* 2 => print address and binary code only
|
||||
* 1 => object in ins[] and instr type in format
|
||||
* 0 => print address only
|
||||
*/
|
||||
print(pflag)
|
||||
int pflag;
|
||||
{
|
||||
register short i, *pi;
|
||||
|
||||
if( !prtflg || fchr == EOF) /*no printing desired, or end of source file*/
|
||||
return;
|
||||
|
||||
i = instrlen; instrlen = 1; /*to print preceeding lines*/
|
||||
while(pline<p2absln) { /*need to print some lines*/
|
||||
page();
|
||||
printf("%4d ",pline); /*put source line num on listing*/
|
||||
printf(" "); /*align the source*/
|
||||
prtline(1);
|
||||
putchar('\n');
|
||||
if ((fchr=gchr()) == EOF)
|
||||
return;
|
||||
pline++;
|
||||
}
|
||||
instrlen = i;
|
||||
|
||||
/* output current address, binary, and source*/
|
||||
page();
|
||||
printf("%4d ",p2absln); /*put source line num on listing*/
|
||||
puthex((int)loctr.hiword,4);
|
||||
puthex((int)loctr.loword,4);
|
||||
putchar(' ');
|
||||
if(!pflag) /*no binary*/
|
||||
printf(" "); /*blanks instead*/
|
||||
else {
|
||||
pi = ins;
|
||||
for(i=0; i< (instrlen/2); i++) /* binary*/
|
||||
puthex(*pi++,4);
|
||||
if(instrlen&1)
|
||||
{
|
||||
i++;
|
||||
puthex(*pi,2);
|
||||
printf(" "); /*Word align*/
|
||||
}
|
||||
putchar(' ');
|
||||
for(;i<4;i++) /*four bytes max per line*/
|
||||
printf(" "); /*align the source*/
|
||||
}
|
||||
if(pline>p2absln || pflag==2)
|
||||
putchar('\n'); /*end of line*/
|
||||
else {
|
||||
prtline(0);
|
||||
if(fchr==EOF) return;
|
||||
putchar('\n');
|
||||
fchr=gchr();
|
||||
pline++;
|
||||
}
|
||||
}
|
||||
|
||||
prtline(flg)
|
||||
int flg;
|
||||
{
|
||||
while(fchr!=EOLC && fchr!=EOF)
|
||||
{
|
||||
putchar(fchr);
|
||||
fchr = gchr();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Heading Print routine
|
||||
*/
|
||||
page()
|
||||
{
|
||||
if((prtflg == 0) || (++xline < LPP)) return;
|
||||
printf("\014C P / M 6 8 0 0 0 A s s e m b l e r\t\t%s\t\tPage%4d\n",
|
||||
"Revision 04.03",++xpage);
|
||||
printf("Source File: %s\n\n",sfname);
|
||||
xline = 3;
|
||||
}
|
||||
59
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/mach.h
Normal file
59
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/mach.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#ifdef PDP11
|
||||
struct {
|
||||
char lobyte;
|
||||
char hibyte;
|
||||
};
|
||||
struct {
|
||||
char *ptrw1;
|
||||
char *ptrw2;
|
||||
};
|
||||
struct {
|
||||
short hiword; /* formally wd1 */
|
||||
short loword; /* formally wd2 */
|
||||
};
|
||||
struct {
|
||||
int swd1;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MC68000
|
||||
struct {
|
||||
char hibyte;
|
||||
char lobyte;
|
||||
};
|
||||
struct {
|
||||
char *ptrw2;
|
||||
};
|
||||
struct {
|
||||
short hiword; /* formally wd1 */
|
||||
short loword; /* formally wd2 */
|
||||
};
|
||||
struct {
|
||||
int swd1;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef VAX11
|
||||
struct {
|
||||
short loword;
|
||||
short hiword;
|
||||
};
|
||||
struct {
|
||||
short swd1;
|
||||
};
|
||||
|
||||
struct {
|
||||
char lobyte;
|
||||
char hibyte;
|
||||
};
|
||||
struct {
|
||||
char *ptrw2;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
#define MC68000 1 /* 68000 version */
|
||||
/*#define VAX 1*/ /* VAX Version */
|
||||
/*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
#define CPM 1 /* CP/M Operating System*/
|
||||
/*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
/*#define VMS 1*/ /* VMS Operating System*/
|
||||
887
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/main.c
Normal file
887
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/main.c
Normal file
@@ -0,0 +1,887 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
char *version = "@(#)main.c 1.5 12/28/83";
|
||||
|
||||
/*
|
||||
* a two pass relocatable assembler for the Motorola 68000 microprocessor
|
||||
*
|
||||
* Bill Allen
|
||||
* Modified by Vicki Hutchison
|
||||
*
|
||||
* after any of this assembler is recompiled, it must be initialized
|
||||
* before it will execute properly. To initialize, become super user
|
||||
* and execute the command:
|
||||
*
|
||||
* as68 -i as68init
|
||||
*
|
||||
* where as68 is the newly compiled version of the assembler. With-
|
||||
* out this initialization, the assembler will not run (probably bus
|
||||
* error).
|
||||
*/
|
||||
|
||||
#include "as68.h"
|
||||
#include "def.h"
|
||||
#ifndef DECC
|
||||
# include <signal.h>
|
||||
#else
|
||||
# include "Isignal"
|
||||
# define strcpy rstrcpy
|
||||
#endif
|
||||
|
||||
/*sw
|
||||
* Define Temporary and Init file names per O/S. We use code here to
|
||||
* allow re-directing temp files and the init file via command line
|
||||
* switches.
|
||||
*/
|
||||
/************************************/
|
||||
#ifdef CPM /* CPM is easy */
|
||||
char *tdname = ""; /* Temp files in same directory */
|
||||
char *idname = "0:"; /* Init file in user 0 */
|
||||
#endif /************************************/
|
||||
#ifdef WHITESM /* On whitesmith's VMS systems */
|
||||
char *tdname = ""; /* Temp files in same directory */
|
||||
char *idname = "bin:"; /* Init file in "bin:" */
|
||||
#endif /************************************/
|
||||
#ifdef UNIX /* UNIX systems are different */
|
||||
char *tdname = "/tmp/"; /* Temp files in /tmp */
|
||||
char *idname = "/lib/"; /* Init file in /lib */
|
||||
#endif /************************************/
|
||||
char tfilebase[] = {"a6AXXXXXX"}; /* Temp file basename */
|
||||
char initbase[] = {"as68symb.dat"}; /* Init file basename */
|
||||
/************************************/
|
||||
|
||||
#define INIT(op,ptr) pack(op,lmte); ptr=lemt(TRUE,oirt)
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register short i, ttmp;
|
||||
register long longtmp;
|
||||
|
||||
nerror = initflg = 0;
|
||||
prtchidx = prtchars;
|
||||
|
||||
if( signal(SIGINT,SIG_IGN) != SIG_IGN ) /*[mac] 4.2a*/
|
||||
signal(SIGINT,rubout);
|
||||
if( signal(SIGQUIT,SIG_IGN) != SIG_IGN )
|
||||
signal(SIGQUIT,rubout);
|
||||
if( signal(SIGHUP,SIG_IGN) != SIG_IGN )
|
||||
signal(SIGHUP,rubout);
|
||||
signal(SIGTERM,rubout);
|
||||
|
||||
pitix = itbuf;
|
||||
pexti = extbl;
|
||||
#ifndef DECC
|
||||
ttmp = (STESIZE*SZMT) + 2;
|
||||
bmte = sbrk(ttmp);
|
||||
longtmp = bmte; /* 11 apr 83, for vax */
|
||||
if(longtmp&1L) /* 11 apr 83, for vax */
|
||||
bmte++; /*make it even*/
|
||||
emte = bmte + ttmp - 2; /*end of main table*/
|
||||
#endif
|
||||
if(argc<=1)
|
||||
usage();
|
||||
i = 1;
|
||||
shortadr = 0; /*long addresses...*/
|
||||
while(argv[i][0] == '-') { /*may be print or initialize*/
|
||||
switch(argv[i++][1]) {
|
||||
|
||||
case 'a': /*[vlh] 4.2, short addresses only*/
|
||||
shortadr = -1;
|
||||
break;
|
||||
|
||||
case 'i': /*initialize the assembler*/
|
||||
initflg++;
|
||||
break;
|
||||
|
||||
case 'p': /*produce a listing*/
|
||||
prtflg++;
|
||||
break;
|
||||
|
||||
case 'u': /*make undefined symbols external*/
|
||||
undflg++;
|
||||
break;
|
||||
|
||||
case 'N': /*no branch optimization*/
|
||||
case 'n': /*sw */
|
||||
didorg++;
|
||||
break;
|
||||
|
||||
case 'L': /*4.2 OBSOLETE, long addresses only*/
|
||||
case 'l': /*sw */
|
||||
shortadr = 0;
|
||||
break;
|
||||
|
||||
case 'T': /*generating code suitable for the 68010*/
|
||||
case 't': /*sw Why is this a switch? */
|
||||
m68010++;
|
||||
break;
|
||||
|
||||
case 'f': /*sw Redirect temp files */
|
||||
tdname = argv[i++];
|
||||
break;
|
||||
|
||||
case 's': /*sw Change symbol table prefix */
|
||||
idname = argv[i++];
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if(i>=argc)
|
||||
usage();
|
||||
sfname = argv[i]; /* Remember source filename */
|
||||
ifn=openfi(argv[i],0,0); /*open source file*/
|
||||
setldfn(argv[i]); /*create relocatable object file name*/
|
||||
lfn=openfi(ldfn,1,1); /*open loader file*/
|
||||
|
||||
tfilname[0] = '\0'; /* Init for strcat */
|
||||
initfnam[0] = '\0'; /* */
|
||||
strcat(tfilname,tdname); /*sw Build temp file */
|
||||
strcat(tfilname,tfilebase); /* names */
|
||||
mktemp(tfilname); /* Make it unique */
|
||||
tfilptr = &tfilname[strlen(tfilname)-1] - 6; /* Points to 'A' in name */
|
||||
strcat(initfnam,idname); /* Build Symbol file */
|
||||
strcat(initfnam,initbase); /* name */
|
||||
|
||||
#ifdef DECC
|
||||
if(prtflg) { /* open file for assembler listing */
|
||||
setlsfn(argv[i]);
|
||||
stdofd = openfi(lsfn,1,0);
|
||||
sptr = fdopen(stdofd,"w");
|
||||
}
|
||||
else
|
||||
sptr = fdopen(1,"w");
|
||||
#endif
|
||||
itfn = gettempf(); /*get a temp file for it*/
|
||||
itfnc = LASTCHTFN; /*remember last char for unlink*/
|
||||
trbfn = gettempf(); /*temp for text relocation bits*/
|
||||
trbfnc = LASTCHTFN;
|
||||
dafn = gettempf(); /*temp for data binary*/
|
||||
dafnc = LASTCHTFN;
|
||||
drbfn = gettempf(); /*temp for data relocation bits*/
|
||||
drbfnc = LASTCHTFN;
|
||||
#ifndef DECC
|
||||
ttmp = (STESIZE*SZMT) + 2;
|
||||
bmte = sbrk(ttmp-1);
|
||||
longtmp = bmte; /* 11 apr 83, for vax */
|
||||
if(longtmp&1L) /* 11 apr 83, for vax */
|
||||
bmte++; /*make it even*/
|
||||
emte = bmte + ttmp - 2; /*end of main table*/
|
||||
#endif
|
||||
if(initflg) { /*initializing te main table*/
|
||||
lmte=bmte; /*beginning main table*/
|
||||
cszmt = SZMT; /*current size of main table*/
|
||||
for(i = 0; i <= SZIRT-2; i += 2) {
|
||||
sirt[i] = &sirt[i]; /*initialize the initial ref tables*/
|
||||
sirt[i+1] = 0;
|
||||
oirt[i] = &oirt[i];
|
||||
oirt[i+1] = 0;
|
||||
}
|
||||
|
||||
/*make entries in main table for directives*/
|
||||
mdemt("opd",0); /*opcode definition*/
|
||||
mdemt(endstr,1); /*end statement*/
|
||||
mdemt("data",2); /*dsect directive(code DATA based)*/
|
||||
mdemt("text",3); /*psect directive(code TEXT based)*/
|
||||
mdemt(equstr,4); /*equate*/
|
||||
mdemt("set",5); /*.set - same as .equ*/
|
||||
mdemt("dc",8); /*define byte*/
|
||||
mdemt("globl",9); /*define global (public) symbols*/
|
||||
mdemt("xdef",9); /*[vlh]define global (public) symbols*/
|
||||
mdemt("xref",9); /*[vlh]define global (public) symbols*/
|
||||
mdemt("comm",10); /*define external symbols*/
|
||||
mdemt("bss",11); /*block storage based*/
|
||||
mdemt("ds",12); /*block storage based*/
|
||||
mdemt(evnstr,13); /*round pc*/
|
||||
mdemt(orgstr1,14); /*[vlh] internal, *= */
|
||||
mdemt(orgstr2,14); /*[vlh] org location, also *= */
|
||||
mdemt("mask2",15); /*[vlh] assemble for mask2, ignore*/
|
||||
mdemt("reg",16); /*[vlh] register equate*/
|
||||
mdemt("dcb",17); /*[vlh] define block*/
|
||||
mdemt("comline",18); /*[vlh] command line*/
|
||||
mdemt("idnt",19); /*[vlh] relocateable id record, ignore*/
|
||||
mdemt("offset",20); /*[vlh] define offsets*/
|
||||
mdemt("section",21); /*[vlh] define sections*/
|
||||
mdemt("ifeq",22); /*[vlh] ca if expr = 0*/
|
||||
mdemt("ifne",23); /*[vlh] ca if expr != 0*/
|
||||
mdemt("iflt",24); /*[vlh] ca if expr < 0*/
|
||||
mdemt("ifle",25); /*[vlh] ca if expr <= 0*/
|
||||
mdemt("ifgt",26); /*[vlh] ca if expr > 0*/
|
||||
mdemt("ifge",27); /*[vlh] ca if expr >= 0*/
|
||||
mdemt("endc",28); /*[vlh] end ca*/
|
||||
mdemt("ifc",29); /*[vlh] ca if string compare*/
|
||||
mdemt("ifnc",30); /*[vlh] ca if not string compare*/
|
||||
mdemt("opt",31); /*[vlh] ignored, assemb options*/
|
||||
mdemt("ttl",32); /*[vlh] ttl define, ignore*/
|
||||
mdemt("page",33); /*[vlh] page define, ignore*/
|
||||
|
||||
}
|
||||
else /*not initializing*/
|
||||
getsymtab(); /*read initialized main table*/
|
||||
|
||||
rlflg = TEXT; /*code initially TEXT based*/
|
||||
inoffset = 0; /*[vlh]not in offset mode*/
|
||||
loctr = 0; /*no generated code*/
|
||||
ca = 0; /*[vlh]depth of conditional assembly*/
|
||||
extindx = 0; /*no external symbols yet*/
|
||||
p2flg = 0; /*pass 1*/
|
||||
ca_true = 1; /*[vlh]true unless in side false case*/
|
||||
absln = 1;
|
||||
sbuflen = -1; /*no source yet*/
|
||||
fchr = gchr(); /*get first char*/
|
||||
if(!initflg) { /*not initializing*/
|
||||
INIT(orgstr2,orgptr);
|
||||
INIT(endstr,endptr);
|
||||
INIT(equstr,equptr);
|
||||
INIT("add",addptr);
|
||||
INIT("addi",addiptr);
|
||||
INIT("addq",addqptr);
|
||||
INIT("sub",subptr);
|
||||
INIT("subi",subiptr);
|
||||
INIT("subq",subqptr);
|
||||
INIT("cmp",cmpptr);
|
||||
INIT("adda",addaptr);
|
||||
INIT("cmpa",cmpaptr);
|
||||
INIT("suba",subaptr);
|
||||
INIT("cmpm",cmpmptr);
|
||||
INIT("and",andptr);
|
||||
INIT("andi",andiptr);
|
||||
INIT("or",orptr);
|
||||
INIT("ori",oriptr);
|
||||
INIT("cmpi",cmpiptr);
|
||||
INIT("eor",eorptr);
|
||||
INIT("eori",eoriptr);
|
||||
INIT("move",moveptr);
|
||||
INIT("moveq",moveqptr);
|
||||
INIT("exg",exgptr);
|
||||
INIT("jsr",jsrptr);
|
||||
INIT("bsr",bsrptr);
|
||||
INIT("nop",nopptr);
|
||||
INIT(evnstr,evenptr);
|
||||
}
|
||||
mloop();
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
#ifndef CPM
|
||||
rpterr("Usage: as68 [-p] [-u] [-L] [-N] sourcefile\n");
|
||||
#else
|
||||
rpterr("Usage: as68 [-p] [-u] [-l] [-n] [-s d:] [-f d:] sourcefile\n");
|
||||
#endif
|
||||
endit();
|
||||
}
|
||||
|
||||
|
||||
/*main loop*/
|
||||
mloop()
|
||||
{
|
||||
register short i;
|
||||
|
||||
while(fchr!=EOF) {
|
||||
if(absln>=brkln1) /*break for debugging the assembler*/
|
||||
i=0;
|
||||
fcflg = 0; /*first time thru expr pass one*/
|
||||
cisit(); /*create it for one statement*/
|
||||
}
|
||||
opcpt = endptr;
|
||||
hend();
|
||||
}
|
||||
|
||||
#define NOCODE ((i>=0&&i<6)||i==9||i==11||i==12||i==16||(i>=20&&i<=30))
|
||||
/* cond-directives, section, ds, set, equ, reg, globl, end, offset */
|
||||
|
||||
/*create intermediate text (it) for one statement*/
|
||||
/* call with first character of statement in fchr*/
|
||||
cisit()
|
||||
{
|
||||
register short *p1,*p2;
|
||||
register short (*dirop)();
|
||||
register short i, col1; /*[vlh] col1 labels in col 1...*/
|
||||
char str[NAMELEN], *l;
|
||||
|
||||
ciss1:
|
||||
immed[0] = immed[1] = indir[0] = indir[1] = numcon[0] = 0;
|
||||
numcon[1] = numsym[0] = numsym[1] = numreg[0] = numreg[1]=0;
|
||||
plevel = numops = opdix = explmode = 0;
|
||||
cistop:
|
||||
col1 = 1;
|
||||
if(fchr==EOLC) {
|
||||
fchr = gchr();
|
||||
goto cistop;
|
||||
}
|
||||
if(fchr==' ') {
|
||||
col1 = 0;
|
||||
igblk();
|
||||
if(fchr==EOLC) /*blank line*/
|
||||
goto cistop;
|
||||
peekc = fchr;
|
||||
if (fchr != EOF)
|
||||
fchr = ' '; /* [vlh] catch eof... */
|
||||
}
|
||||
if(fchr==EOF)
|
||||
return;
|
||||
if(fchr=='*') { /*ignore comments*/
|
||||
fchr = gchr();
|
||||
if(fchr=='=') { /*relocation counter assignment*/
|
||||
fchr = gchr(); /*pass the =*/
|
||||
horg(); /*output constants if not bss*/
|
||||
}
|
||||
igrst();
|
||||
fcflg = 0; /*clear expr first time flag for next stmt*/
|
||||
goto ciss1;
|
||||
}
|
||||
|
||||
/* get the opcode and label*/
|
||||
|
||||
mode = 'w'; /*word mode*/
|
||||
igblk(); /*ignore blanks*/
|
||||
poslab = 1;
|
||||
gterm(TRUE);
|
||||
poslab = 0;
|
||||
if(fchr==':' || fchr=='=') { /*there is a label*/
|
||||
label:
|
||||
col1 = 0;
|
||||
if(itype!=ITSY) { /*not a symbol*/
|
||||
uerr(2);
|
||||
lbt[0] = (char)0; /*no label*/
|
||||
}
|
||||
else {
|
||||
p2 = &lmte->name[0];
|
||||
for(p1= &lbt[0]; p1 < &lbt[NAMELEN]; ) {
|
||||
*p1++ = *p2++;
|
||||
}
|
||||
if(fchr==':')
|
||||
fchr=gchr(); /*ignore the colons*/
|
||||
}
|
||||
labl1:
|
||||
ligblk();
|
||||
if(fchr == EOF)
|
||||
return;
|
||||
if(fchr == '*') {
|
||||
igrst(); /*comment*/
|
||||
goto labl1;
|
||||
}
|
||||
gterm(TRUE);
|
||||
if(fchr==':' || fchr=='=') { /*another label*/
|
||||
if(lbt[0]) {
|
||||
strcpy(tlab1,lmte,NAMELEN); /*save current label */
|
||||
dlabl(); /*define the last one*/
|
||||
pack(tlab1,lmte); /*restor the old lable*/
|
||||
}
|
||||
goto label;
|
||||
}
|
||||
}
|
||||
else
|
||||
lbt[0] = 0; /*no label*/
|
||||
|
||||
igblk();
|
||||
if(fchr == '=')
|
||||
goto label;
|
||||
if(itype==ITSP) {
|
||||
if(ival.loword == '=') {
|
||||
hequ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(itype!=ITSY) /*not valid opcode*/
|
||||
goto cisi3;
|
||||
if (col1) { /* [vlh] could be a label save as is... */
|
||||
l = &str;
|
||||
strcpy(l,lmte->name,NAMELEN);
|
||||
}
|
||||
if((opcpt=lemt(TRUE,oirt))==lmte) { /*not in opcode table*/
|
||||
if (col1) { /* [vlh] it's a label... */
|
||||
strcpy(lmte->name,l,NAMELEN);
|
||||
goto label;
|
||||
}
|
||||
cisi3:
|
||||
if (ca_true) /* [vlh] report error if not in CA false */
|
||||
xerr(3);
|
||||
igrst();
|
||||
return;
|
||||
}
|
||||
getmode(); /*look for .b .w or .l mode flag*/
|
||||
if(opcpt->flags&OPDR) { /* its a directive*/
|
||||
i = opcpt->vl1;
|
||||
if (!ca_true && (i < LOW_CA || i > HI_CA)) { igrst(); return; }
|
||||
if (inoffset) /* [vlh] */
|
||||
if (!(NOCODE)) { /* can't generate code in offset */
|
||||
xerr(12);
|
||||
return;
|
||||
}
|
||||
dirop = p1direct[i]; /*call routine to handle directive*/
|
||||
(*dirop)();
|
||||
return;
|
||||
}
|
||||
else if (!ca_true) { /* [vlh] */
|
||||
igrst();
|
||||
return;
|
||||
}
|
||||
else if (inoffset) { /* [vlh] */
|
||||
xerr(12);
|
||||
return;
|
||||
}
|
||||
|
||||
opcval = (opcpt->vl1); /*opcode*/
|
||||
format = (opcpt->flags&OPFF); /*format of this instr*/
|
||||
if (explmode)
|
||||
if (!modeok()) { xerr(16); return; }
|
||||
dlabl(); /*define label*/
|
||||
opitb(); /*beginning of statement*/
|
||||
if(format)
|
||||
opito(); /*may have operands*/
|
||||
else
|
||||
igrst(); /*only comments*/
|
||||
format = (opcpt->flags&OPFF); /* may have changed*/
|
||||
|
||||
|
||||
/*end of statement*/
|
||||
|
||||
i = calcilen();
|
||||
stbuf[1].itrl = i; /*assumed instruction length*/
|
||||
stbuf[0].itrl = itwc; /*number of it entries*/
|
||||
wostb(); /*write out statement buffer*/
|
||||
loctr += i;
|
||||
}
|
||||
|
||||
getmode()
|
||||
{
|
||||
if (fchr=='.') {
|
||||
fchr = gchr();
|
||||
switch (fchr) {
|
||||
case 'b':
|
||||
case 'B':
|
||||
case 's':
|
||||
case 'S':
|
||||
modelen = BYTESIZ;
|
||||
mode = BYTE;
|
||||
break;
|
||||
case 'w':
|
||||
case 'W':
|
||||
modelen = WORDSIZ;
|
||||
mode = WORD;
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
modelen = LONGSIZ;
|
||||
mode = LONG;
|
||||
break;
|
||||
default:
|
||||
peekc = fchr;
|
||||
fchr = '.';
|
||||
goto getm1;
|
||||
}
|
||||
explmode++;
|
||||
fchr = gchr();
|
||||
igblk();
|
||||
return;
|
||||
}
|
||||
getm1:
|
||||
if(opcpt == exgptr) { /*length is long*/
|
||||
modelen = LONGSIZ;
|
||||
mode = LONG;
|
||||
}
|
||||
else {
|
||||
mode = WORD; /*default is word*/
|
||||
modelen = WORDSIZ;
|
||||
}
|
||||
}
|
||||
|
||||
/* check to be sure specified mode is legal */
|
||||
modeok() /* [vlh] */
|
||||
{
|
||||
switch(format) {
|
||||
case 0 :
|
||||
case 14 :
|
||||
case 18 :
|
||||
return(FALSE);
|
||||
case 13 :
|
||||
case 15 :
|
||||
case 20 :
|
||||
case 21 :
|
||||
return(modelen==BYTESIZ?FALSE:TRUE);
|
||||
case 4 :
|
||||
case 25 :
|
||||
return(modelen==BYTESIZ?TRUE:FALSE);
|
||||
case 7 :
|
||||
case 9 :
|
||||
return(modelen==WORDSIZ?FALSE:TRUE);
|
||||
case 5 :
|
||||
case 11 :
|
||||
case 28 :
|
||||
return(modelen==WORDSIZ?TRUE:FALSE);
|
||||
case 6 :
|
||||
return(modelen==LONGSIZ?FALSE:TRUE);
|
||||
case 12 :
|
||||
case 30 :
|
||||
case 22 :
|
||||
case 29 :
|
||||
return(modelen==LONGSIZ?TRUE:FALSE);
|
||||
default :
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate the instruction length in bytes*/
|
||||
calcilen()
|
||||
{
|
||||
register short i;
|
||||
register long l;
|
||||
register char *p;
|
||||
|
||||
i = 2; /*all instrs at least 2 bytes*/
|
||||
|
||||
switch(format) {
|
||||
|
||||
case 20:
|
||||
i += 2; /*for reg mask*/
|
||||
case 1: /*two ea's -- one of which may be a reg*/
|
||||
case 15:
|
||||
case 30:
|
||||
case 26:
|
||||
case 5:
|
||||
case 3:
|
||||
case 21:
|
||||
i += lenea(1);
|
||||
case 16:
|
||||
case 24:
|
||||
case 25:
|
||||
case 29:
|
||||
i += lenea(0);
|
||||
break;
|
||||
|
||||
case 9: /* [vlh] explicit jmp length... */
|
||||
if (!explmode)
|
||||
i += lenea(0);
|
||||
else
|
||||
return(mode==LONG?6:4); /*[vlh] explicit jmp.? */
|
||||
break;
|
||||
|
||||
case 7:
|
||||
i += (immed[0]) ? 2+lenea(1) : lenea(1);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
case 11:
|
||||
case 19:
|
||||
case 31:
|
||||
i += 2; /*always 4 bytes*/
|
||||
break;
|
||||
|
||||
case 6: /*relative branches*/
|
||||
if(itwc == ITOP1+1) {
|
||||
if(stbuf[ITOP1].itty == ITCN)
|
||||
l = stbuf[ITOP1].itop;
|
||||
else if(stbuf[ITOP1].itty == ITSY) {
|
||||
p = stbuf[ITOP1].itop.ptrw2;
|
||||
if(p->flags&SYDF)
|
||||
l = p->vl1; /*symbol value*/
|
||||
else
|
||||
goto loffst;
|
||||
}
|
||||
else
|
||||
goto loffst;
|
||||
l -= (loctr+2);
|
||||
if(l<=127 && l>=-128) /*8 bit offset*/
|
||||
break;
|
||||
}
|
||||
loffst:
|
||||
if (!explmode || modelen > BYTESIZ) /*[vlh] recognize br extensions*/
|
||||
i += 2; /*long offset for branches*/
|
||||
break;
|
||||
|
||||
case 2:
|
||||
i += (mode==LONG?4:2) + lenea(1);
|
||||
break;
|
||||
|
||||
case 23:
|
||||
if(immed[0])
|
||||
i += (mode==LONG?4:2);
|
||||
case 17:
|
||||
case 22:
|
||||
i += lenea(1);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if(numops==1) /*memory shift instruction*/
|
||||
i += shiftea(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
||||
/* calc the length of an effective address*/
|
||||
lenea(lidx)
|
||||
int lidx;
|
||||
{
|
||||
if(immed[lidx])
|
||||
return(mode==LONG?LONGSIZ:WORDSIZ);
|
||||
return(shiftea(lidx));
|
||||
}
|
||||
|
||||
shiftea(lidx)
|
||||
int lidx;
|
||||
{
|
||||
if(indir[lidx] && numreg[lidx])
|
||||
return((numcon[lidx] || numsym[lidx]) ? 2 : 0);
|
||||
if(numsym[lidx] || numcon[lidx])
|
||||
return((!shortadr || numcon[lidx]==2) ? 4 : 2);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
*define a label if there is one to define
|
||||
* call with:
|
||||
* label name in lbt if it exists
|
||||
* else lbt[0] == 0
|
||||
*/
|
||||
dlabl()
|
||||
{
|
||||
if(lbt[0]) { /*got a label*/
|
||||
pack(lbt,lmte); /*put label in main table*/
|
||||
lblpt=lemt(FALSE,sirt); /*look up label*/
|
||||
if(lblpt != lmte) { /*symbol entered previously*/
|
||||
if(lbt[0] == '~') { /*local symbol -- may be duplicate*/
|
||||
lblpt = lmte;
|
||||
mmte();
|
||||
}
|
||||
else {
|
||||
if(lblpt->flags&SYXR) {
|
||||
uerr(29);
|
||||
lblpt = 0;
|
||||
return;
|
||||
}
|
||||
if((lblpt->flags)&SYDF) {
|
||||
uerr(1);
|
||||
lblpt = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mmte(); /*make label entry in main table*/
|
||||
}
|
||||
lblpt->flags |= SYDF; /*label is now defined*/
|
||||
if(rlflg == TEXT)
|
||||
lblpt->flags |= SYRO;
|
||||
else if(rlflg == DATA)
|
||||
lblpt->flags |= SYRA;
|
||||
else if(rlflg == BSS)
|
||||
lblpt->flags |= SYBS;
|
||||
/* No flags to set if absolute */
|
||||
lblpt->vl1 = loctr; /*label value*/
|
||||
}
|
||||
else
|
||||
lblpt = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* output it for operands
|
||||
* gets intput from gterm
|
||||
* puts output in stbuf using itwc as an index
|
||||
* itwc should point at the next entry to be made in stbuf
|
||||
*/
|
||||
opito()
|
||||
{
|
||||
register short lopcomma;
|
||||
|
||||
lopcomma = symcon = chmvq = 0;
|
||||
numops++; /*count first operand*/
|
||||
while(1) {
|
||||
starmul = symcon; /*star is multiply op if flag is set*/
|
||||
if(fchr=='\'' || fchr=='"')
|
||||
lopcomma = 0;
|
||||
gterm(FALSE); /*get a term*/
|
||||
if(itwc==ITOP1 && format==CLRFOR && opcval==CLRVAL)
|
||||
chgclr();
|
||||
opitoo(); /*output it for one operand*/
|
||||
if(itype==ITSP && ival.loword==',') {
|
||||
if (plevel==1 && !numcon[opdix]) /* [vlh] */
|
||||
numcon[opdix] = 1;
|
||||
if(lopcomma)
|
||||
uerr(30);
|
||||
lopcomma++;
|
||||
igblk(); /*ignore blanks for 68000 C compiler*/
|
||||
}
|
||||
else
|
||||
lopcomma=0;
|
||||
if(ival==EOLC && itype==ITSP) /*end of operands*/
|
||||
break;
|
||||
if(fchr==EOLC) {
|
||||
fchr=gchr();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(chmvq) /*changed move to moveq*/
|
||||
if(numops!=2 || immed[1] || indir[1] || numcon[1] || numsym[1] ||
|
||||
numreg[1]>=AREGLO) {
|
||||
stbuf[2].itop.ptrw2 = moveptr; /*change it back*/
|
||||
opcpt = moveptr;
|
||||
}
|
||||
|
||||
if (stbuf[2].itop.ptrw2==cmpptr) /* [vlh] cmp -> cmpm ?? */
|
||||
if (numreg[0] && numreg[1] && indir[0] && indir[1]) {
|
||||
stbuf[2].itop.ptrw2 = cmpmptr;
|
||||
opcpt = cmpmptr;
|
||||
}
|
||||
|
||||
if(lopcomma)
|
||||
uerr(30);
|
||||
}
|
||||
|
||||
/* change clr.l An to suba.l An,An*/
|
||||
chgclr()
|
||||
{
|
||||
register char *p;
|
||||
|
||||
if(itype==ITSY) { /*first op is symbol*/
|
||||
p = lemt(FALSE,sirt);
|
||||
if(p==lmte)
|
||||
return;
|
||||
if(!(p->flags&SYER) || p->vl1<AREGLO) /*not A reg*/
|
||||
return;
|
||||
opcpt = subaptr; /*make it a suba instr*/
|
||||
opitb();
|
||||
opitoo(); /*output first operand -- An*/
|
||||
itype = ITSP;
|
||||
ival = ',';
|
||||
opitoo(); /*output a comma*/
|
||||
itype = ITSY; /*now the A reg again*/
|
||||
}
|
||||
}
|
||||
|
||||
/*output it for one operand*/
|
||||
opitoo()
|
||||
{
|
||||
register char *sp;
|
||||
|
||||
symcon = 0;
|
||||
if(itype==ITSP) { /*special symbol*/
|
||||
if(ival.loword==',' && !plevel) { /* another operand */
|
||||
numops++;
|
||||
if(!opdix)
|
||||
opdix++;
|
||||
}
|
||||
if(ival.loword==')')
|
||||
symcon = 1; /* star is multiply */
|
||||
if(ival.loword==' ') { /*end of operands*/
|
||||
while(fchr!=EOLC) /*ignore rest of statement*/
|
||||
fchr=gchr();
|
||||
return;
|
||||
}
|
||||
if(ival.loword==EOLC)
|
||||
return;
|
||||
}
|
||||
else /*symbol or constant*/
|
||||
symcon = 1;
|
||||
|
||||
if(itwc >= STMAX) { /*it overflow*/
|
||||
rpterr("i.t. overflow\n");
|
||||
abort();
|
||||
}
|
||||
pitw->itty = itype; /*type of it entry*/
|
||||
|
||||
/*put symbol in it buffer*/
|
||||
if(itype==ITSY) {
|
||||
sp=lemt(FALSE,sirt); /*look up it main table*/
|
||||
pitw->itop.ptrw2 = sp; /*ptr to symbol entry*/
|
||||
if(sp==lmte) /*first occurrance*/
|
||||
mmte();
|
||||
itwc++; /*count entries in it buffer*/
|
||||
pitw++;
|
||||
if(!(sp->flags&SYER)) /*is it a register?*/
|
||||
numsym[opdix]++;
|
||||
else if(sp->vl1) /*yes, a register & not D0 */
|
||||
numreg[opdix] = sp->vl1;
|
||||
return;
|
||||
}
|
||||
else if(itype == ITCN ) {
|
||||
if(ival.hiword && ival.hiword != -1)
|
||||
numcon[opdix] = 2;
|
||||
else if(!numcon[opdix])
|
||||
numcon[opdix] = 1;
|
||||
if(numops == 1)
|
||||
tryquick();
|
||||
}
|
||||
|
||||
/* special characters and constants*/
|
||||
pitw->itop = ival;
|
||||
pitw->itrl = reloc;
|
||||
itwc++;
|
||||
pitw++;
|
||||
}
|
||||
|
||||
/* change add into addq and sub into subq if possible*/
|
||||
tryquick()
|
||||
{
|
||||
register char *p;
|
||||
register long l;
|
||||
|
||||
if(fchr!=',' || !immed[0])
|
||||
return;
|
||||
l = ival;
|
||||
if(itwc != ITOP1+1) {
|
||||
if(itwc!=ITOP1+2 || stbuf[ITOP1+1].itty!=ITSP ||
|
||||
stbuf[ITOP1+1].itop.loword != '-')
|
||||
return;
|
||||
l = -l;
|
||||
}
|
||||
p = stbuf[2].itop.ptrw2;
|
||||
if(p==moveptr) {
|
||||
if(explmode && modelen != LONGSIZ) /*dont change .w or .b*/
|
||||
return;
|
||||
if(l>=-128 && l<=127) {
|
||||
stbuf[2].itop.ptrw2 = moveqptr;
|
||||
opcpt = moveqptr;
|
||||
chmvq++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(l<=0 || l>8) {
|
||||
return;
|
||||
}
|
||||
if(p==addptr || p==addiptr) {
|
||||
stbuf[2].itop.ptrw2 = opcpt = addqptr;
|
||||
}
|
||||
else if(p==subptr || p==subiptr) {
|
||||
stbuf[2].itop.ptrw2 = opcpt = subqptr;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(astr1, astr2, alen)
|
||||
char *astr1, *astr2;
|
||||
register int alen;
|
||||
{
|
||||
register char *str1, *str2;
|
||||
|
||||
str1 = astr1;
|
||||
str2 = astr2;
|
||||
while (--alen != -1)
|
||||
*str1++ = *str2++;
|
||||
}
|
||||
|
||||
/* index - find the index of a character in a string*/
|
||||
/* This is identical to Software Tools index.*/
|
||||
index(str,chr) /* returns index of c in str or -1*/
|
||||
char *str; /* pointer to string to search*/
|
||||
char chr; /* character to search for*/
|
||||
{
|
||||
register char *s;
|
||||
register short i;
|
||||
|
||||
for( s = str, i = 0; *s != '\0'; i++ )
|
||||
if( *s++ == chr )
|
||||
return(i);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
$2pip machine.h=machine.68k
|
||||
|
||||
$2cp68 -i 0$1 dir.c $1x.i
|
||||
$2c068 $1x.i $1x.1 $1x.2 $1x.3 -f
|
||||
era $1x.i
|
||||
$2c168 $1x.1 $1x.2 dir.s
|
||||
era $1x.1
|
||||
era $1x.2
|
||||
$2as68 -l -u -f $1 -s 0$1 dir.s
|
||||
era dir.s
|
||||
|
||||
|
||||
$2cp68 -i 0$1 expr.c $1x.i
|
||||
$2c068 $1x.i $1x.1 $1x.2 $1x.3 -f
|
||||
era $1x.i
|
||||
$2c168 $1x.1 $1x.2 expr.s
|
||||
era $1x.1
|
||||
era $1x.2
|
||||
$2as68 -l -u -f $1 -s 0$1 expr.s
|
||||
era expr.s
|
||||
|
||||
$2cp68 -i 0$1 list.c $1x.i
|
||||
$2c068 $1x.i $1x.1 $1x.2 $1x.3 -f
|
||||
era $1x.i
|
||||
$2c168 $1x.1 $1x.2 list.s
|
||||
era $1x.1
|
||||
era $1x.2
|
||||
$2as68 -l -u -f $1 -s 0$1 list.s
|
||||
era list.s
|
||||
|
||||
$2cp68 -i 0$1 main.c $1x.i
|
||||
$2c068 $1x.i $1x.1 $1x.2 $1x.3 -f
|
||||
era $1x.i
|
||||
$2c168 $1x.1 $1x.2 main.s
|
||||
era $1x.1
|
||||
era $1x.2
|
||||
$2as68 -l -u -f $1 -s 0$1 main.s
|
||||
era main.s
|
||||
|
||||
$2cp68 -i 0$1 misc.c $1x.i
|
||||
$2c068 $1x.i $1x.1 $1x.2 $1x.3 -f
|
||||
era $1x.i
|
||||
$2c168 $1x.1 $1x.2 misc.s
|
||||
era $1x.1
|
||||
era $1x.2
|
||||
$2as68 -l -u -f $1 -s 0$1 misc.s
|
||||
era misc.s
|
||||
|
||||
$2cp68 -i 0$1 pass1a.c $1x.i
|
||||
$2c068 $1x.i $1x.1 $1x.2 $1x.3 -f
|
||||
era $1x.i
|
||||
$2c168 $1x.1 $1x.2 pass1a.s
|
||||
era $1x.1
|
||||
era $1x.2
|
||||
$2as68 -l -u -f $1 -s 0$1 pass1a.s
|
||||
era pass1a.s
|
||||
|
||||
$2cp68 -i 0$1 pass2.c $1x.i
|
||||
$2c068 $1x.i $1x.1 $1x.2 $1x.3 -f
|
||||
era $1x.i
|
||||
$2c168 $1x.1 $1x.2 pass2.s
|
||||
era $1x.1
|
||||
era $1x.2
|
||||
$2as68 -l -u -f $1 -s 0$1 pass2.s
|
||||
era pass2.s
|
||||
|
||||
$2cp68 -i 0$1 symt.c $1x.i
|
||||
$2c068 $1x.i $1x.1 $1x.2 $1x.3 -f
|
||||
era $1x.i
|
||||
$2c168 $1x.1 $1x.2 symt.s
|
||||
era $1x.1
|
||||
era $1x.2
|
||||
$2as68 -l -u -f $1 -s 0$1 symt.s
|
||||
era symt.s
|
||||
|
||||
link $1 $2
|
||||
1025
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/misc.c
Normal file
1025
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/misc.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, CA 92121
|
||||
*/
|
||||
|
||||
#ifdef VAX11
|
||||
struct { char b4; char b3; char b2; char b1; };
|
||||
struct { char wb2; char wb1; };
|
||||
#endif
|
||||
|
||||
#ifdef PDP11
|
||||
struct { char b2; char b1; char b4; char b3; };
|
||||
struct { char wb2; char wb1; };
|
||||
#endif
|
||||
|
||||
#ifdef MC68000
|
||||
struct { char b1; char b2; char b3; char b4; };
|
||||
struct { char wb1; char wb2; };
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#define MOVEA 0100
|
||||
|
||||
|
||||
extern char tfilname[]; /*name of it file*/
|
||||
extern char initfnam[]; /*name of the initilization file*/
|
||||
|
||||
int (*opfary[])() = {
|
||||
0, /*0*/
|
||||
opf1, /*1*/
|
||||
opf2, /*2*/
|
||||
opf3, /*3*/
|
||||
opf4, /*4*/
|
||||
opf5, /*5*/
|
||||
relbr, /*6*/
|
||||
opf7, /*7*/
|
||||
opf8, /*8*/
|
||||
opf9, /*9*/
|
||||
opf4, /*10*/
|
||||
opf11, /*11*/
|
||||
opf12, /*12*/
|
||||
opf13, /*13*/
|
||||
opf9, /*14*/
|
||||
opf15, /*15*/
|
||||
opf17, /*16*/
|
||||
opf17, /*17*/
|
||||
opf13, /*18*/
|
||||
opf11, /*19*/
|
||||
opf20, /*20*/
|
||||
opf21, /*21*/
|
||||
opf22, /*22*/
|
||||
opf23, /*23*/
|
||||
opf9, /*24*/
|
||||
opf9, /*25*/
|
||||
opf5, /*26*/ /* [vlh] cmp, chk, extention verification */
|
||||
opf4, /*27*/ /* [vlh] addx, subx, extension verification */
|
||||
opf13, /*28*/ /* [vlh] swap, extension verification */
|
||||
opf9, /*29*/ /* [vlh] pea, extention verification */
|
||||
opf15, /*30*/ /* [vlh] lea, extension verification */
|
||||
opf31 /*31*/ /* [vlh] 4.2, movec & moves 68010 */
|
||||
};
|
||||
|
||||
#define LSTFRMT 31
|
||||
|
||||
short f1mode[] = {0,0,0100,0,0200};
|
||||
short f2mode[] = {0,0,0100,0,0200};
|
||||
short f3mode[] = {0,010000,030000,0,020000};
|
||||
short f15mode[] = {0,0,0300,0,0700};
|
||||
short f5mode[] = {0,0,0100,0,0200};
|
||||
short f5amode[] = {0,0,0300,0,0700};
|
||||
short f13mode[] = {0,0,0200,0,0300};
|
||||
short f23mode[] = {0,0400,0500,0,0600};
|
||||
short rlbits[5]; /*holds relocation bits for instr*/
|
||||
short pline; /*number of last printed line*/
|
||||
short brkln2 = 077777; /*pass 2 break line number for debugging*/
|
||||
short prsp; /*special print alignment flag*/
|
||||
107
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/pass1a.c
Normal file
107
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/pass1a.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/* reduce long relative branches to short if possible*/
|
||||
|
||||
#include "as68.h"
|
||||
|
||||
|
||||
pass1a()
|
||||
{
|
||||
register long reduced;
|
||||
register short writfn, i, wsize;
|
||||
|
||||
pitix = &itbuf[ITBSZ];
|
||||
reduced = itoffset = 0L; stbuf[0].itrl = 0;
|
||||
wsize = 3*STBFSIZE; /* [vlh] don't calculate many times */
|
||||
close(itfn);
|
||||
LASTCHTFN = itfnc;
|
||||
itfn = openfi(tfilname,0,1); /*open it for reading*/
|
||||
writfn = open(tfilname,1,1); /*may need to rewrite some of it*/
|
||||
if(writfn<0)
|
||||
abort();
|
||||
while(1) {
|
||||
ristb(); /*read it for one statement*/
|
||||
opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
|
||||
if(!(opcpt->flags&OPDR)) { /*not a directive*/
|
||||
format = (opcpt->flags)&OPFF;
|
||||
p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
|
||||
if(((format==6 && p1inlen==4) || opcpt==jsrptr) &&
|
||||
(rlflg=stbuf[3].itrl)==TEXT) {
|
||||
nite = stbuf[0].itrl & 0377;/* # of it entries */
|
||||
pnite = &stbuf[nite].itty; /*ptr to end of stmt*/
|
||||
modelen = stbuf[2].itrl; /*instr mode length*/
|
||||
opdix = ITOP1; /*first operand*/
|
||||
pitw = &stbuf[ITOP1].itty; /*ptr to first operand*/
|
||||
loctr = stbuf[3].itop - reduced;
|
||||
expr(&p2gi);
|
||||
ival -= loctr+2L;
|
||||
if(itype==ITCN && !extflg && reloc!=ABS) {
|
||||
if(format==9) { /*jsr*/
|
||||
i = (ival>= -128 && ival<=127) ? p1inlen-2 :
|
||||
(ival>= -32768 && ival<=32767) ? p1inlen-4 : 0;
|
||||
if (!i)
|
||||
continue;
|
||||
stbuf[2].itop.ptrw2 = bsrptr; /*chng to bsr*/
|
||||
}
|
||||
else if(ival>= -128 && ival<=127) {
|
||||
if (ival==2) /* branch to next instr - delete */
|
||||
i = 4;
|
||||
else /* reduce long branch to short */
|
||||
i = 2;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
fixsyadr(i);
|
||||
reduced += i;
|
||||
stbuf[1].itrl -= i; /*reduced instr lenght somewhat*/
|
||||
if(!stbuf[1].itrl)
|
||||
stbuf[1].itrl = -1; /*ignore flag*/
|
||||
if(lseek(writfn,itoffset,0) == -1L) {
|
||||
rpterr("seek error on intermediate file\n");
|
||||
abort();
|
||||
}
|
||||
if(write(writfn,&stbuf[0],wsize) != wsize) {
|
||||
rpterr("write error on it file\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(opcpt == endptr) {
|
||||
savelc[TEXT] -= reduced;
|
||||
close(writfn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fix all symbol addresses that are text based and greater than loctr*/
|
||||
/* fix means subtract al from them*/
|
||||
fixsyadr(al)
|
||||
{
|
||||
register char **sx1, **sx2;
|
||||
register short l;
|
||||
|
||||
l = al;
|
||||
/* loop thru symbol initial reference table*/
|
||||
for(sx1 = sirt; sx1 < &sirt[SZIRT-1]; sx1 += 2) {
|
||||
if(*(sx2 = sx1+1)==0) /* this chain is empty*/
|
||||
continue;
|
||||
|
||||
/* symbols on one chain*/
|
||||
sx2 = *sx2; /*first entry on this chain*/
|
||||
while(1) {
|
||||
if((sx2->flags&SYDF || sx2->flags&SYPC) && sx2->flags&SYRO &&
|
||||
sx2->vl1 > loctr) /* [vlh] */
|
||||
sx2->vl1 -= l;
|
||||
if(sx2 == *sx1) /*end of chain*/
|
||||
break;
|
||||
sx2 = sx2->tlnk; /*next entry in chain*/
|
||||
}
|
||||
}
|
||||
}
|
||||
850
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/pass2.c
Normal file
850
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/pass2.c
Normal file
@@ -0,0 +1,850 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
|
||||
@(#)pass2.c 1.5 12/16/83
|
||||
*/
|
||||
|
||||
/*
|
||||
* pass two for the 68000 assembler
|
||||
* Bill Allen
|
||||
* March 1980
|
||||
*/
|
||||
|
||||
#include "as68.h"
|
||||
#include "p2def.h"
|
||||
|
||||
/*pass two driver*/
|
||||
pass2()
|
||||
{
|
||||
register short i;
|
||||
register int (*dirop)();
|
||||
|
||||
pitix = &itbuf[ITBSZ]; /*it buffer is empty*/
|
||||
lbuf.cc = tbuf.cc = dabuf.cc = drbuf.cc = BSIZE;
|
||||
lbuf.fd = lfn; /*set buffered io for binary file*/
|
||||
lbuf.cp = &lbuf.cbuf[0];
|
||||
tbuf.fd = trbfn; /*set buffered io for text reloc bits file*/
|
||||
tbuf.cp = &tbuf.cbuf[0];
|
||||
dabuf.fd = dafn; /*set buffered io for data bytes*/
|
||||
dabuf.cp = &dabuf.cbuf[0];
|
||||
drbuf.fd = drbfn; /*set buffered io for data reloc bits*/
|
||||
drbuf.cp = &drbuf.cbuf[0];
|
||||
couthd.ch_magic = MAGIC;/*c.out magic number*/
|
||||
if(savelc[TEXT]&1)
|
||||
savelc[TEXT]++; /*make it even*/
|
||||
couthd.ch_tsize = savelc[TEXT]; /*text size*/
|
||||
if(savelc[DATA]&1)
|
||||
savelc[DATA]++; /*make it even*/
|
||||
couthd.ch_dsize = savelc[DATA]; /*data size*/
|
||||
couthd.ch_bsize = savelc[BSS]; /*bss size*/
|
||||
/**
|
||||
* symbol table size is not known now -- it is set at end of pass 2
|
||||
* entry point and stack size are zero for now
|
||||
**/
|
||||
putchd(&lbuf,&couthd); /* [vlh] 4.1, replaces write_header */
|
||||
savelc[0] = 0; savelc[1] = 0; savelc[2] = 0; savelc[3] = 0;
|
||||
loctr = 0; /*location counter*/
|
||||
rlflg = TEXT; /*TEXT relocatable*/
|
||||
p2flg = 1; /*pass two*/
|
||||
if (lseek(ifn,0L,0) == -1L) { /*beginning of source*/
|
||||
rpterr("seek error on source file\n");
|
||||
abort();
|
||||
}
|
||||
close(itfn);
|
||||
LASTCHTFN = itfnc;
|
||||
itfn = openfi(tfilname,0,1); /*open it for reading*/
|
||||
pline = 1; /*no lines printed*/
|
||||
fchr=gchr(); /*get first char*/
|
||||
while(1) { /*pass 2 main loop*/
|
||||
ristb(); /*read it for one statement*/
|
||||
p2absln = stbuf[0].itop; /*line number*/
|
||||
if(p2absln>=brkln2) /*for debugging the assembler*/
|
||||
i=0;
|
||||
opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
|
||||
nite = stbuf[0].itrl & 0377; /*number of it entries*/
|
||||
pnite = &stbuf[nite].itty; /*ptr to end of stmt*/
|
||||
modelen = stbuf[2].itrl; /*instr mode length*/
|
||||
p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
|
||||
opdix = ITOP1; /*first operand*/
|
||||
pitw = &stbuf[ITOP1].itty; /*ptr to first operand*/
|
||||
prsp = 0; /*special print flag off*/
|
||||
instrlen = 2; /*default for print*/
|
||||
if(opcpt->flags&OPDR) { /*opcode is a directive*/
|
||||
i = opcpt->vl1; /*directive number*/
|
||||
if (i<=DIRECT) {
|
||||
dirop = p2direct[i];
|
||||
(*dirop)(); /*handle directive*/
|
||||
}
|
||||
else
|
||||
uerr(21);
|
||||
}
|
||||
else
|
||||
gcist(); /*generate code for one statement*/
|
||||
}
|
||||
}
|
||||
|
||||
/* generate code for an instruction*/
|
||||
/* call with*/
|
||||
/* intermediate text for instruction in stbuf*/
|
||||
gcist()
|
||||
{
|
||||
if(stbuf[0].itty != ITBS) /*beginning of statement*/
|
||||
abort();
|
||||
format = (opcpt->flags)&OPFF;
|
||||
in_err = 0; /*[vlh] no error this instruction, yet*/
|
||||
ival = 0; /*initial value for possible operand*/
|
||||
reloc = ABS;
|
||||
instrlen = 2; /*at least 2 bytes*/
|
||||
ins[0] = opcpt->vl1.loword; /*opcode value, 4.2 ==> loword*/
|
||||
rlbits[0] = INSABS; /*instruction absolute*/
|
||||
pins = &ins[1];
|
||||
prlb = &rlbits[1];
|
||||
if(nite>ITOP1) { /*operands*/
|
||||
if(!format)
|
||||
uerr(9);
|
||||
else if(format>LSTFRMT) /* [vlh] was a magic number... */
|
||||
abort();
|
||||
else {
|
||||
(*opfary[format])();
|
||||
}
|
||||
}
|
||||
if (!ckein() && !in_err) /* at end of statement ?? */
|
||||
uerr(6);
|
||||
print(1); /*print source*/
|
||||
|
||||
loctr += p1inlen;
|
||||
if (!in_err && p1inlen != instrlen) /* [vlh] 2nd pass error recovery */
|
||||
uerr(38);
|
||||
outinstr(); /*write out instr binary*/
|
||||
}
|
||||
|
||||
/* relative branches*/
|
||||
relbr()
|
||||
{
|
||||
expr(&p2gi);
|
||||
if(extflg) { /*external reference*/
|
||||
instrlen += 2; /*long relative*/
|
||||
*pins++ = ival; /*pass constant part*/
|
||||
*prlb++ = (extref<<3)|EXTREL; /*ext ref*/
|
||||
return;
|
||||
}
|
||||
ival -= (loctr+2); /*calc relative offset*/
|
||||
if(itype!=ITCN || reloc != rlflg) {
|
||||
uerr(22); /*invalid relative branch*/
|
||||
ival = 0;
|
||||
}
|
||||
reloc = ABS;
|
||||
if(p1inlen==4) { /*long displacement*/
|
||||
if(ival>32767 || ival<-32768)
|
||||
uerr(22);
|
||||
instrlen += 2;
|
||||
*pins++ = ival;
|
||||
*prlb++ = DABS; /*data absolute*/
|
||||
}
|
||||
else { /*short displacement*/
|
||||
if(ival>127 || ival<-128)
|
||||
uerr(22);
|
||||
ins[0] |= (ival.loword&0377);
|
||||
}
|
||||
/* [vlh] 4.2 0==>2 make it a nop if -N specified */
|
||||
if ((ival==0) || (ival==2 && didorg)) {
|
||||
opcpt = nopptr;
|
||||
ins[0] = opcpt->vl1.loword;
|
||||
if(instrlen==4) { /* long branch */
|
||||
pins = &ins[1];
|
||||
*pins++ = opcpt->vl1.loword;
|
||||
rlbits[1] = INSABS;
|
||||
}
|
||||
}
|
||||
in_err++; /* ignore extra eg. bra *+$d04(pc) vs. bra *+d04 */
|
||||
}
|
||||
|
||||
#define US (unsigned short)
|
||||
/* format one -- add, sub, and, or, cmp, etc.*/
|
||||
/* one operand must be a D reg (or A reg dest for add, sub, or cmp)*/
|
||||
opf1()
|
||||
{
|
||||
register short *p;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if (ins[0]==(US AND) || ins[0]==(US OR))
|
||||
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
if (ins[0]==(US AND))
|
||||
opcpt = andiptr;
|
||||
else
|
||||
opcpt = oriptr;
|
||||
ins[0] = opcpt->vl1.loword;
|
||||
format = (opcpt->flags)&OPFF;
|
||||
ccr_or_sr();
|
||||
return;
|
||||
}
|
||||
p = f1mode;
|
||||
if(ckdreg(&opnd[1])) { /*destn is D reg*/
|
||||
if((opcpt==andptr||opcpt==orptr)&&ckareg(&opnd[0])) /*A source*/
|
||||
uerr(20);
|
||||
makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
||||
return;
|
||||
}
|
||||
else if(ckdreg(&opnd[0]) && memalt(&opnd[1])) { /*source is D reg*/
|
||||
if (pcea(&opnd[1])) uerr(10);
|
||||
makef1(opnd[0].ea,p[modelen]+0400,&opnd[1]);
|
||||
return;
|
||||
}
|
||||
else if(ckareg(&opnd[1])) { /*A reg is dstn*/
|
||||
if(opcpt==addptr)
|
||||
opcpt = addaptr;
|
||||
else if(opcpt==cmpptr)
|
||||
opcpt = cmpaptr;
|
||||
else if(opcpt==subptr)
|
||||
opcpt = subaptr;
|
||||
else {
|
||||
uerr(20);
|
||||
return;
|
||||
}
|
||||
format = (opcpt->flags)&OPFF;
|
||||
opnd[1].ea &= 07;
|
||||
p = f15mode;
|
||||
makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
||||
return;
|
||||
}
|
||||
else if(!makeimm()) /*make an immediate instr*/
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/* format 2 -- addi, andi, subi, etc*/
|
||||
opf2()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(ins[0]==ANDI || ins[0]==ORI || ins[0]==EORI) {
|
||||
if(cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
ccr_or_sr();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(opnd[0].ea != IMM) {
|
||||
uerr(9);
|
||||
return;
|
||||
}
|
||||
if(!dataalt(&opnd[1]) || pcea(&opnd[1])) {
|
||||
uerr(20);
|
||||
return;
|
||||
}
|
||||
genimm();
|
||||
}
|
||||
|
||||
/*format #3 -- move and movea*/
|
||||
opf3()
|
||||
{
|
||||
register short k;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(cksprg(&opnd[0],CCR)) { /* [vlh] 03-aug-83 */
|
||||
ins[0] = MOVEFCC;
|
||||
if(anysprg(&opnd[1]))
|
||||
uerr(20);
|
||||
if (modelen == BYTESIZ || modelen == LONGSIZ)
|
||||
uerr(34);
|
||||
if (!m68010)
|
||||
uerr(8);
|
||||
ins[0] |= opnd[1].ea;
|
||||
if(!dataea(&opnd[1]))
|
||||
uerr(9);
|
||||
doea(&opnd[1]);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[1],CCR)) {
|
||||
ins[0] = MOVETCC;
|
||||
opf3l1:
|
||||
if(anysprg(&opnd[0]))
|
||||
uerr(20);
|
||||
if (modelen == BYTESIZ || modelen == LONGSIZ)
|
||||
uerr(34);
|
||||
ins[0] |= opnd[0].ea;
|
||||
if(!dataea(&opnd[0]))
|
||||
uerr(9);
|
||||
doea(&opnd[0]);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[1],SR)) {
|
||||
ins[0] = MOVESR;
|
||||
goto opf3l1;
|
||||
}
|
||||
if(cksprg(&opnd[0],SR)) {
|
||||
if (modelen == BYTESIZ || modelen == LONGSIZ)
|
||||
uerr(34);
|
||||
if(anysprg(&opnd[1]))
|
||||
uerr(20);
|
||||
ins[0] = SRMOVE | opnd[1].ea;
|
||||
if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
||||
uerr(10);
|
||||
doea(&opnd[1]);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[0],USP)) {
|
||||
if (modelen == BYTESIZ)
|
||||
uerr(34); /* default is word, can't test */
|
||||
if (!ckareg(&opnd[1]))
|
||||
uerr(33);
|
||||
ins[0] = MOVEUSP|8|(opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[1],USP)) {
|
||||
if (modelen == BYTESIZ)
|
||||
uerr(34); /* default is word, can't test */
|
||||
if (!ckareg(&opnd[0]))
|
||||
uerr(33);
|
||||
ins[0] = MOVEUSP|(opnd[0].ea&7);
|
||||
return;
|
||||
}
|
||||
k = ins[0];
|
||||
ins[0] |= f3mode[modelen];
|
||||
ckbytea();
|
||||
ins[0] |= opnd[0].ea; /*source ea*/
|
||||
doea(&opnd[0]);
|
||||
ins[0] |= (opnd[1].ea&7)<<9; /*dest register*/
|
||||
ins[0] |= (opnd[1].ea&070)<<3; /*dest mode*/
|
||||
doea(&opnd[1]);
|
||||
if(k==MOVEA) {
|
||||
if(dataea(&opnd[1]))
|
||||
uerr(20);
|
||||
}
|
||||
else if((pcea(&opnd[1]) && dataea(&opnd[1])) || opnd[1].ea==IMM)
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/* format 4 -- abcd, sbcd */
|
||||
/* format 10 -- cmpm*/
|
||||
/* format 27 -- addx, subx */
|
||||
opf4()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if (format==27) { /*addx,subx add in size bits*/
|
||||
ins[0] |= f1mode[modelen];
|
||||
}
|
||||
else if(format==10) { /*cmpm*/
|
||||
if((opnd[0].ea&070)!=INDINC || (opnd[1].ea&070)!=INDINC)
|
||||
uerr(20);
|
||||
ins[0] |= f1mode[modelen] | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
if (m68010) { /* [vlh] 4.2 */
|
||||
uerr(31);
|
||||
nerror--; /* just a warning */
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(ckdreg(&opnd[0]) && ckdreg(&opnd[1])) {
|
||||
ins[0] |= ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
return;
|
||||
}
|
||||
if((opnd[0].ea&070)==DECIND && (opnd[1].ea&070)==DECIND) {
|
||||
ins[0] |= 010 | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
return;
|
||||
}
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/*format 5 -- div, mul*/
|
||||
/*format 26 -- cmp, chk */
|
||||
opf5()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(!ckdreg(&opnd[1])) {
|
||||
if(opcpt==cmpptr) {
|
||||
if(!dataea(&opnd[1])) /* [vlh] made define */
|
||||
ins[0] |= f5amode[modelen]; /* was pumode */
|
||||
else if(makeimm())
|
||||
return;
|
||||
else
|
||||
uerr(20);
|
||||
}
|
||||
else
|
||||
uerr(20);
|
||||
}
|
||||
if(opcpt==cmpptr) {
|
||||
ins[0] |= f5mode[modelen]; /* was pumode */
|
||||
ckbytea();
|
||||
}
|
||||
else if(!dataea(&opnd[0]))
|
||||
uerr(20);
|
||||
ins[0] |= (opnd[1].ea&7)<<9 | opnd[0].ea;
|
||||
doea(&opnd[0]);
|
||||
}
|
||||
|
||||
#define BTST 0000
|
||||
/* format 7 -- bit instrs -- btst, bclr, bset, etc*/
|
||||
opf7()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(opnd[1].ea==IMM||(ins[0]!=BTST&&pcea(&opnd[1]))||ckareg(&opnd[1]))
|
||||
uerr(20);
|
||||
if(ckdreg(&opnd[0])) {
|
||||
ins[0] |= (opnd[0].ea<<9)|0400;
|
||||
}
|
||||
else { /*static bit #*/
|
||||
if(opnd[0].con<0L || opnd[0].con>31 ||
|
||||
(opnd[1].ea&INDIRECT&&opnd[0].con>7)) /* [vlh] */
|
||||
uerr(23);
|
||||
if(opnd[0].ea != IMM)
|
||||
uerr(17);
|
||||
ins[0] |= 04000;
|
||||
dodisp(&opnd[0]);
|
||||
}
|
||||
if (modelen==1 && !(memea(&opnd[1]))) /*[vlh]*/
|
||||
uerr(20);
|
||||
else if (!(ckdreg(&opnd[1])) && modelen==4)
|
||||
uerr(20);
|
||||
ins[0] |= opnd[1].ea;
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 8 -- shifts and rotates*/
|
||||
opf8()
|
||||
{
|
||||
register short i;
|
||||
|
||||
getea(0); /*get first operand*/
|
||||
if(pitw >= pnite) { /*end of all ops*/
|
||||
if(ckdreg(&opnd[0])) { /*shift dreg one bit*/
|
||||
cpop01(); /*copy opnd 0 to 1*/
|
||||
opnd[0].ea = IMM;
|
||||
opnd[0].con = 1L;
|
||||
if (!ckdreg(&opnd[1])) uerr(20);
|
||||
opf8l1:
|
||||
if(opnd[0].con<1 || opnd[0].con>8) /*[vlh legal range 1..8*/
|
||||
uerr(37);
|
||||
ins[0] |= ((opnd[0].con.loword&7)<<9)|f1mode[modelen]|opnd[1].ea;
|
||||
return;
|
||||
}
|
||||
i = (ins[0]&077)<<6;
|
||||
ins[0] &= 0177700;
|
||||
ins[0] |= 0300|i|opnd[0].ea;
|
||||
if(!memalt(&opnd[0]) || pcea(&opnd[0]) || modelen != 2)
|
||||
uerr(20);
|
||||
doea(&opnd[0]);
|
||||
return;
|
||||
}
|
||||
if(!ckcomma()) {
|
||||
uerr(10);
|
||||
return;
|
||||
}
|
||||
getea(1); /*get second operand*/
|
||||
if(!ckdreg(&opnd[1])) /* [vlh] second operand must be dreg */
|
||||
uerr(20);
|
||||
if(ckdreg(&opnd[0])) { /*first op is D reg*/
|
||||
ins[0] |= (opnd[0].ea<<9)|040; /*reg # and reg bit*/
|
||||
}
|
||||
else {
|
||||
if(opnd[0].ea != IMM)
|
||||
uerr(20);
|
||||
goto opf8l1;
|
||||
}
|
||||
ins[0] |= f1mode[modelen] | opnd[1].ea; /*put in size and reg #*/
|
||||
}
|
||||
|
||||
/* format 9 -- jmp, jsr */
|
||||
/* format 14 -- stop */
|
||||
/* format 14 -- rtd (68010) */
|
||||
/* format 24 -- clr, neg, negx, not */
|
||||
/* format 25 -- s?? */
|
||||
/* format 29 -- pea */
|
||||
/* one operand instructions -- jmp, clr, neg, not, sge, etc.*/
|
||||
opf9()
|
||||
{
|
||||
getea(0);
|
||||
if(format==24) { /*clr, not, etc*/
|
||||
ins[0] |= f1mode[modelen]; /*add size bits*/
|
||||
if(!dataalt(&opnd[0]) || pcea(&opnd[0]))
|
||||
uerr(20);
|
||||
}
|
||||
else if(format==25) { /*tas,scc, etc*/
|
||||
if(ckareg(&opnd[0]) || pcea(&opnd[0]) || opnd[0].ea==IMM)
|
||||
uerr(20);
|
||||
}
|
||||
else if(format==14) { /*stop*/
|
||||
if (ins[0] == RTD && !m68010) /* [vlh] 4.2 */
|
||||
uerr(8);
|
||||
if(modelen!=2 || opnd[0].ea!=IMM)
|
||||
uerr(20);
|
||||
doea(&opnd[0]);
|
||||
return;
|
||||
}
|
||||
else if(!controlea(&opnd[0])) /*jmp, jsr, etc*/
|
||||
uerr(20);
|
||||
ins[0] |= opnd[0].ea;
|
||||
doea(&opnd[0]);
|
||||
}
|
||||
|
||||
/* format 11 -- dbcc*/
|
||||
/* format 19 -- link*/
|
||||
opf11()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(format==19) { /*link*/
|
||||
if(!ckareg(&opnd[0]))
|
||||
uerr(33);
|
||||
if(opnd[1].ea != IMM)
|
||||
uerr(17);
|
||||
}
|
||||
else {
|
||||
if(!ckdreg(&opnd[0]))
|
||||
uerr(33);
|
||||
if(opnd[1].drlc!=rlflg) /*[vlh]don't chk opnd[1].ea!=LADDR||SADDR*/
|
||||
uerr(22);
|
||||
opnd[1].con -= (loctr+2L);
|
||||
cksize(&opnd[1]);
|
||||
opnd[1].drlc = ABS; /*not relocatable*/
|
||||
}
|
||||
ins[0] |= opnd[0].ea&7; /*put in reg #*/
|
||||
dodisp(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 12 -- exg*/
|
||||
opf12()
|
||||
{
|
||||
register short i;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(ckdreg(&opnd[0])) {
|
||||
if(ckdreg(&opnd[1])) { /*exchange D regs*/
|
||||
ins[0] |= 0100 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
if(ckareg(&opnd[1])) { /*ins[0] <- A and D flag*/
|
||||
ins[0] |= 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(ckareg(&opnd[0])) {
|
||||
if(ckareg(&opnd[1])) { /*both a regs*/
|
||||
ins[0] |= 0110 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
if(ckdreg(&opnd[1])) { /*A and D regs*/
|
||||
i = opnd[0].ea; /*exchg ea's*/
|
||||
opnd[0].ea = opnd[1].ea;
|
||||
opnd[1].ea = i;
|
||||
ins[0] |= 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
}
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/* format 13 -- ext, unlk*/
|
||||
/* format 18 -- trap*/
|
||||
/* format 28 -- swap */
|
||||
#define UNLK 047130
|
||||
|
||||
opf13()
|
||||
{
|
||||
getea(0);
|
||||
if(format==18) { /*trap*/
|
||||
if(opnd[0].con<0 || opnd[0].con>15)
|
||||
uerr(15);
|
||||
ins[0] |= opnd[0].con.loword;
|
||||
return;
|
||||
}
|
||||
if(ins[0]==UNLK) { /*unlk instr*/
|
||||
if(!ckareg(&opnd[0]))
|
||||
uerr(20);
|
||||
}
|
||||
else {
|
||||
if(!ckdreg(&opnd[0]))
|
||||
uerr(20);
|
||||
if (format==13) /* ext */
|
||||
ins[0] |= f13mode[modelen];
|
||||
}
|
||||
ins[0] |= opnd[0].ea&7;
|
||||
}
|
||||
|
||||
/* format 15 -- adda, cmpa, suba*/
|
||||
/* format 30 -- lea */
|
||||
opf15()
|
||||
{
|
||||
register short i;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(!ckareg(&opnd[1]))
|
||||
uerr(33);
|
||||
if(format==30) {
|
||||
i = 0700;
|
||||
if(!controlea(&opnd[0]))
|
||||
uerr(20);
|
||||
}
|
||||
else
|
||||
i = f15mode[modelen];
|
||||
makef1(opnd[1].ea&7,i,&opnd[0]);
|
||||
if (format==15 && opnd[0].ea != 071) cksize(&opnd[0]);
|
||||
}
|
||||
|
||||
/*formats 16 and 17 -- addq, inc, subq, dec*/
|
||||
opf17()
|
||||
{
|
||||
if(format==16) { /*inc or dec*/
|
||||
clrea(&opnd[0]);
|
||||
opnd[0].ea = IMM;
|
||||
opnd[0].con = 1L;
|
||||
opnd[0].drlc = ABS;
|
||||
getea(1);
|
||||
}
|
||||
else {
|
||||
if(get2ops())
|
||||
return;
|
||||
}
|
||||
if(opnd[0].ea != IMM || !altea(&opnd[1]) || pcea(&opnd[1]))
|
||||
uerr(20);
|
||||
if(opnd[0].con<=0 || opnd[0].con>8)
|
||||
uerr(15);
|
||||
if(modelen==1 && !dataea(&opnd[1]))
|
||||
uerr(34);
|
||||
ins[0] |= f1mode[modelen]|((opnd[0].con.loword&7)<<9)|opnd[1].ea;
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 20 -- movem */
|
||||
short regmsk0[] = {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
|
||||
0100,040,020,010,4,2,1};
|
||||
short regmsk1[] = {1,2,4,010,020,040,0100,0200,0400,01000,02000,04000,010000,
|
||||
020000,040000,0100000};
|
||||
opf20()
|
||||
{
|
||||
register short dr, i, j;
|
||||
|
||||
dr = 0;
|
||||
if(getreg() != -1 || pitw->itty == ITRM) { /*regs to memory*/
|
||||
if (pitw->itty != ITRM) { /* [vlh] */
|
||||
pitw--;
|
||||
j = getrlist(regmsk0);
|
||||
}
|
||||
else {
|
||||
j = pitw->itop;
|
||||
pitw++;
|
||||
}
|
||||
if(!ckcomma())
|
||||
uerr(10);
|
||||
}
|
||||
else
|
||||
dr = 02000;
|
||||
getea(0);
|
||||
if(dr) {
|
||||
if(!ckcomma())
|
||||
uerr(10);
|
||||
if (pitw->itty != ITRM) /* [vlh] */
|
||||
j = getrlist(regmsk1); /*mem to regs*/
|
||||
else {
|
||||
j = pitw->itop;
|
||||
j = fixmask(j);
|
||||
pitw++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(controlea(&opnd[0]))
|
||||
j = fixmask(j);
|
||||
}
|
||||
i = opnd[0].ea&070;
|
||||
if(!controlea(&opnd[0]) && i!=INDINC && i!=DECIND)
|
||||
uerr(20);
|
||||
if(modelen==4) /*long*/
|
||||
ins[0] |= 0100;
|
||||
ins[0] |= opnd[0].ea|dr;
|
||||
*pins++ = j; /*reg mask*/
|
||||
*prlb++ = DABS;
|
||||
instrlen += 2;
|
||||
doea(&opnd[0]);
|
||||
if (!dr) { /* 1st argument (2nd is reg list) */
|
||||
if (pcea(&opnd[0]) || (opnd[0].ea&070)==INDINC)
|
||||
uerr(20); /* xx(pc), xx(pc,dx), -(ax) */
|
||||
}
|
||||
else /* 2nd argument (1st is reg list) */
|
||||
if ((opnd[0].ea&070)==DECIND)
|
||||
uerr(20); /* (ax)+ */
|
||||
}
|
||||
|
||||
/*
|
||||
* get a list of registers for the movem instr
|
||||
* call with:
|
||||
* ptr to reg-to-mem or mem-to-reg array of bits
|
||||
*/
|
||||
getrlist(ap)
|
||||
short *ap;
|
||||
{
|
||||
register short *p, i, j, mask;
|
||||
|
||||
p = ap;
|
||||
mask = 0;
|
||||
while((i=getreg()) != -1) {
|
||||
if(ckitc(pitw,'-')) {
|
||||
pitw++;
|
||||
if((j=getreg()) == -1) {
|
||||
uerr(40);
|
||||
break;
|
||||
}
|
||||
while(i<=j)
|
||||
mask |= p[i++];
|
||||
}
|
||||
else
|
||||
mask |= p[i];
|
||||
if(ckitc(pitw,'/'))
|
||||
pitw++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if(!mask)
|
||||
uerr(40);
|
||||
return(mask);
|
||||
}
|
||||
|
||||
/*reverse a movem register mask for control ea to memory*/
|
||||
fixmask(msk)
|
||||
int msk;
|
||||
{
|
||||
register short i, j, k;
|
||||
|
||||
k = (msk&1) ? 0100000 : 0;
|
||||
i = 2;
|
||||
j = 040000;
|
||||
while(i) {
|
||||
if(msk&i)
|
||||
k |= j;
|
||||
i <<= 1;
|
||||
j >>= 1;
|
||||
}
|
||||
return(k);
|
||||
}
|
||||
|
||||
/* format 21 -- movep*/
|
||||
opf21()
|
||||
{
|
||||
register short m,d;
|
||||
register char *p;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(ckdreg(&opnd[0])) { /*d reg source*/
|
||||
m = 0600;
|
||||
d = opnd[0].ea;
|
||||
p = &opnd[1];
|
||||
}
|
||||
else if(ckdreg(&opnd[1])) { /*d reg dest*/
|
||||
m = 0400;
|
||||
d = opnd[1].ea;
|
||||
p = &opnd[0];
|
||||
}
|
||||
else {
|
||||
uerr(20);
|
||||
}
|
||||
if((p->ea&070) != INDDISP)
|
||||
uerr(20);
|
||||
if(modelen == 4)
|
||||
m |= 0100;
|
||||
ins[0] |= (d<<9)|m|(p->ea&7);
|
||||
*pins++ = p->con.loword;
|
||||
*prlb++ = p->drlc;
|
||||
instrlen += 2;
|
||||
}
|
||||
|
||||
/* format 22 -- moveq*/
|
||||
opf22()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(opnd[0].ea != IMM)
|
||||
uerr(17);
|
||||
if(opnd[0].con>255L || opnd[0].con<-256L)
|
||||
uerr(15);
|
||||
if(!ckdreg(&opnd[1]))
|
||||
uerr(33);
|
||||
ins[0] |= (opnd[1].ea<<9) | (opnd[0].con.loword&0377);
|
||||
}
|
||||
|
||||
/* format 23 -- eor*/
|
||||
opf23()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
opcpt = eoriptr;
|
||||
ins[0] = opcpt->vl1.loword;
|
||||
format = (opcpt->flags)&OPFF;
|
||||
ccr_or_sr();
|
||||
return;
|
||||
}
|
||||
if(!ckdreg(&opnd[0])) {
|
||||
if(makeimm()) /*must be immediate*/
|
||||
return;
|
||||
uerr(20); /*or error*/
|
||||
}
|
||||
if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
||||
uerr(20);
|
||||
ins[0] |= (opnd[0].ea<<9)|f23mode[modelen]|opnd[1].ea;
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 31 -- movec and moves (68010 only) [vlh] 4.2 */
|
||||
opf31()
|
||||
{
|
||||
register struct op *cntrl, *genrl, *eaop;
|
||||
|
||||
instrlen += 2;
|
||||
if (!m68010)
|
||||
uerr(8);
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if (ins[0] == MOVEC) {
|
||||
if (modelen == BYTESIZ)
|
||||
uerr(34);
|
||||
if ( cksprg(&opnd[0],USP) || cksprg(&opnd[0],SFC) ||
|
||||
cksprg(&opnd[0],DFC) || cksprg(&opnd[0],VSR)) {
|
||||
cntrl = &opnd[0];
|
||||
genrl = &opnd[1];
|
||||
}
|
||||
else {
|
||||
if ( !cksprg(&opnd[1],USP) && !cksprg(&opnd[1],SFC) &&
|
||||
!cksprg(&opnd[1],DFC) && !cksprg(&opnd[1],VSR))
|
||||
uerr(18);
|
||||
ins[0] |= 1; /* direction Rn --> Rc */
|
||||
cntrl = &opnd[1];
|
||||
genrl = &opnd[0];
|
||||
}
|
||||
if (!ckreg(genrl))
|
||||
uerr(18);
|
||||
*pins = ((genrl->ea)<<12) & 0xF000; /* [vlh] 4.3 11==12,8==F */
|
||||
if (cksprg(cntrl,DFC))
|
||||
*pins |= DFC_CR;
|
||||
else if (cksprg(cntrl,USP))
|
||||
*pins |= USP_CR;
|
||||
else if (cksprg(cntrl,VSR))
|
||||
*pins |= VSR_CR;
|
||||
/* else... *pins |= SFC_CR; (SFC_CR == 0)*/
|
||||
}
|
||||
else { /* MOVES */
|
||||
ins[0] |= f1mode[modelen];
|
||||
if (ckreg(&opnd[0])) {
|
||||
genrl = &opnd[0];
|
||||
eaop = &opnd[1];
|
||||
*pins = 0x800; /* from general register to <ea> */
|
||||
}
|
||||
else {
|
||||
genrl = &opnd[1];
|
||||
eaop = &opnd[0];
|
||||
*pins = 0;
|
||||
}
|
||||
*pins |= ((genrl->ea)<<12) & 0xF000; /* [vlh] 4.3 11==>12 */
|
||||
if (!memalt(eaop) || pcea(eaop) || ckreg(eaop))
|
||||
uerr(20);
|
||||
ins[0] |= eaop->ea;
|
||||
doea(eaop);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
$1vsend as68.rel
|
||||
$1vsend dir.c
|
||||
$1vsend expr.c
|
||||
$1vsend main.c
|
||||
$1vsend misc.c
|
||||
$1vsend pass1a.c
|
||||
$1vsend pass2.c
|
||||
$1vsend symt.c
|
||||
$1vsend version.c
|
||||
$1vsend as68.h
|
||||
$1vsend def.h
|
||||
$1vsend mach.h
|
||||
$1vsend order.h
|
||||
$1vsend p2def.h
|
||||
$1vsend as68init.
|
||||
$1vsend cout.h
|
||||
$1vsend send.sub
|
||||
$1vsend link.sub
|
||||
$1vsend list.c
|
||||
$1vsend machine.h
|
||||
$1vsend machine.68k
|
||||
$1vsend make.sub
|
||||
892
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/symt.c
Normal file
892
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/symt.c
Normal file
@@ -0,0 +1,892 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "as68.h"
|
||||
|
||||
char *ermsg[];
|
||||
char initfnam[];
|
||||
char ldfn[];
|
||||
char tlab1[];
|
||||
short ftudp;
|
||||
short poslab;
|
||||
|
||||
/*output it for beginning of statement*/
|
||||
opitb()
|
||||
{
|
||||
stbuf[0].itty = ITBS; /*beginning of statement*/
|
||||
stbuf[0].itop = (fchr!=EOLC) ? absln : absln-1;
|
||||
stbuf[1].itty = ITSY; /*label entry*/
|
||||
stbuf[1].itop.ptrw2 = lblpt; /*pointer to symbol or 0*/
|
||||
|
||||
/*put opcode in it buffer*/
|
||||
stbuf[2].itty = ITSY;
|
||||
stbuf[2].itrl = modelen; /*mode of instr(byte, word, long)*/
|
||||
stbuf[2].itop.ptrw2 = opcpt; /*pointer to opcode in main table*/
|
||||
stbuf[3].itty = ITCN;
|
||||
stbuf[3].itrl = rlflg; /*relocation base*/
|
||||
stbuf[3].itop = loctr; /*pass1 location counter*/
|
||||
itwc = ITOP1; /*next available slot-currently 4*/
|
||||
pitw = &stbuf[ITOP1].itty; /*init the pointer*/
|
||||
}
|
||||
|
||||
/*
|
||||
* get an input term (symbol, constant, or special character)
|
||||
* call with:
|
||||
* the first character in fchr
|
||||
* returns:
|
||||
* item type in itype
|
||||
* item value in ival if item is a constant or special character
|
||||
* if it is a symbol it is placed at the end of the main table
|
||||
*
|
||||
* meaning of state table:
|
||||
*
|
||||
* currently getting: symbol(0) constant(1) beginning(2)
|
||||
*
|
||||
* next char:
|
||||
* digit(0) 0 1 1
|
||||
*
|
||||
* letter(3) 0 3 0
|
||||
*
|
||||
* special char(6) 3 3 3
|
||||
*
|
||||
* contents of the state table is the next state. processing stops when
|
||||
* state 3 is encountered. state 2 is the beginning state.
|
||||
*/
|
||||
int sttbl[] = {0,1,1,0,3,0,3,3,3}; /*state table for parser*/
|
||||
|
||||
gterm(constpc)
|
||||
int constpc;
|
||||
{
|
||||
register short smode, i;
|
||||
register char *p;
|
||||
register short tmode;
|
||||
register char *j;
|
||||
long num;
|
||||
char istr[80];
|
||||
|
||||
if(fchr == '\'' || fchr == '"')
|
||||
if(astring()) /*maybe ascii string*/
|
||||
return;
|
||||
smode = 2; /*beginning state*/
|
||||
i = 0;
|
||||
p = istr;
|
||||
|
||||
/*loop to put item on istr*/
|
||||
while(fchr>=' ') { /*until a control char*/
|
||||
if(smode==2 && fchr=='.')
|
||||
tmode = 3;
|
||||
else if(isalpha(fchr) || fchr=='~' || fchr=='_' || (fchr=='$'&&i))
|
||||
tmode=3;
|
||||
else if(isdigit(fchr))
|
||||
tmode=0;
|
||||
else
|
||||
tmode = 6;
|
||||
tmode = sttbl[tmode+smode]; /*new state*/
|
||||
if(tmode==3) break; /*end of item*/
|
||||
smode = tmode;
|
||||
*p++ = fchr; /*save character*/
|
||||
i++;
|
||||
fchr=gchr();
|
||||
}
|
||||
|
||||
/* end of item*/
|
||||
switch(smode) {
|
||||
|
||||
case 0: /*symbol*/
|
||||
*p = '\0'; /*end of symbol*/
|
||||
itype = ITSY; /*symbol*/
|
||||
pack(istr,lmte); /*put symbol at end of main table*/
|
||||
j = lemt(FALSE,sirt);
|
||||
if(istr[0]!='~' && !poslab && (j->flags&(SYEQ|SYER))==SYEQ) {
|
||||
itype = (j->flags&SYRM) ? ITRM : ITCN; /* [vlh] */
|
||||
ival = j->vl1;
|
||||
reloc = ((j->flags)&SYRO) ? TEXT : ((j->flags)&SYRA) ? DATA :
|
||||
((j->flags)&SYBS) ? BSS : ABS;
|
||||
}
|
||||
return;
|
||||
|
||||
case 1: /*constant*/
|
||||
if(!constant(&num,istr,i)) {
|
||||
uerr(17); /*illegal constant*/
|
||||
num = 0;
|
||||
}
|
||||
ival = num;
|
||||
itype = ITCN;
|
||||
reloc = ABS;
|
||||
return;
|
||||
|
||||
case 2: /*just a special char*/
|
||||
switch(fchr) {
|
||||
|
||||
case '*': /*location counter*/
|
||||
if(starmul) { /*multiply*/
|
||||
starmul = 0;
|
||||
goto specsy;
|
||||
}
|
||||
refpc++; /*referenced pgm ctr*/
|
||||
reloc = rlflg; /*relocation of location counter*/
|
||||
ival = loctr;
|
||||
itype = (constpc) ? ITCN : ITPC;
|
||||
break;
|
||||
|
||||
|
||||
case '$': /*hex constant*/
|
||||
oconst(16);
|
||||
return;
|
||||
|
||||
case '@': /*octal const*/
|
||||
oconst(8);
|
||||
return;
|
||||
|
||||
case '%': /*binary const*/
|
||||
oconst(2);
|
||||
return;
|
||||
|
||||
case '#':
|
||||
immed[opdix]++;
|
||||
goto specsy;
|
||||
|
||||
case '(':
|
||||
indir[opdix]++;
|
||||
plevel++;
|
||||
goto specsy;
|
||||
|
||||
case ')':
|
||||
plevel--;
|
||||
goto specsy;
|
||||
|
||||
default:
|
||||
specsy:
|
||||
itype = ITSP; /*return special char*/
|
||||
ival = fchr;
|
||||
}
|
||||
if(fchr != EOLC)
|
||||
fchr=gchr(); /*get next char*/
|
||||
if((ival=='>' && fchr=='>') || (ival=='<' && fchr=='<'))
|
||||
fchr=gchr(); /*shift op, ignore second char*/
|
||||
return;
|
||||
|
||||
default:
|
||||
abort(); /*not possible*/
|
||||
}
|
||||
}
|
||||
|
||||
/*astring - check for an ascii string enclosed in single quotes*/
|
||||
astring()
|
||||
{
|
||||
register char delim;
|
||||
|
||||
if(fchr != '\'' && fchr != '"') /*valid delimiter*/
|
||||
return(0);
|
||||
delim = fchr;
|
||||
if(equflg || (itype==ITSP && ival.loword=='#')) { /*immediate operand*/
|
||||
if(astr1(delim)) {
|
||||
fchr = gchr();
|
||||
if(fchr!=delim)
|
||||
xerr(19);
|
||||
fchr=gchr();
|
||||
}
|
||||
return((equflg) ? 1 : 0);
|
||||
}
|
||||
while(astr1(delim)) {
|
||||
itype = ITSP;
|
||||
ival = ','; /*separate by commas*/
|
||||
reloc = ABS;
|
||||
opitoo();
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
astr1(adelim)
|
||||
int adelim;
|
||||
{
|
||||
register short delim,i,retv;
|
||||
register long l;
|
||||
|
||||
delim = adelim;
|
||||
i = 0; l = 0;
|
||||
retv = 1;
|
||||
while((fchr=gchr()) != EOF) {
|
||||
if(fchr==delim) {
|
||||
fchr = gchr();
|
||||
if(fchr != delim) {
|
||||
retv = 0; /*end of string*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(fchr == EOLC) {
|
||||
xerr(19);
|
||||
retv = 0; /*end of string*/
|
||||
break;
|
||||
}
|
||||
l = (l<<8) | fchr;
|
||||
if(++i >= modelen) {
|
||||
if((fchr=gchr()) == delim) {
|
||||
fchr = gchr();
|
||||
retv = 0; /*end of string*/
|
||||
}
|
||||
else
|
||||
peekc = fchr; /*next char in string*/
|
||||
break; /*filled one bucket*/
|
||||
}
|
||||
}
|
||||
while(i < modelen) {
|
||||
l <<= 8;
|
||||
i++;
|
||||
}
|
||||
itype = ITCN;
|
||||
ival = l;
|
||||
reloc = ABS;
|
||||
if(!equflg)
|
||||
opitoo(); /*output one operand*/
|
||||
return(retv);
|
||||
}
|
||||
|
||||
/*get constant given radix*/
|
||||
oconst(ardx)
|
||||
int ardx;
|
||||
{
|
||||
register short trdx,j;
|
||||
register long i;
|
||||
|
||||
switch (ardx) { /* radix as power of 2 */
|
||||
case 16 : trdx = 4; break;
|
||||
case 8 : trdx = 3; break;
|
||||
case 2 : trdx = 1; break;
|
||||
default :
|
||||
rpterr("invalid radix in oconst");
|
||||
abort();
|
||||
}
|
||||
i=0;
|
||||
while(1) {
|
||||
fchr=gchr();
|
||||
j=fchr;
|
||||
if(isdigit(j))
|
||||
j -= '0';
|
||||
else if((j=tolower(j))>='a' && j<='f')
|
||||
j = j-'a'+10;
|
||||
else
|
||||
break; /*not valid numeric char*/
|
||||
if(j>=0 && j<ardx)
|
||||
i = (i<<trdx)+j;
|
||||
else
|
||||
break;
|
||||
}
|
||||
ival = i;
|
||||
itype = ITCN;
|
||||
reloc = ABS;
|
||||
}
|
||||
|
||||
|
||||
/*convert ascii constant to binary*/
|
||||
constant(pnum,pstr,idx)
|
||||
long *pnum;
|
||||
register char *pstr;
|
||||
int idx;
|
||||
{
|
||||
register short i,j;
|
||||
register long l;
|
||||
|
||||
l = 0;
|
||||
for(i=0; i<idx; i++) {
|
||||
j = *pstr++;
|
||||
if(isdigit(j))
|
||||
j -= '0';
|
||||
if(j<0 || j>=10)
|
||||
return(0);
|
||||
l = (l<<3) + (l<<1) + j; /* l = l*10 + j*/
|
||||
}
|
||||
*pnum = l;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* method for looking up entries in the main table
|
||||
*
|
||||
* Note: The entry to be looked up must be placed at the end
|
||||
* of the main table. The global cell 'lmte'(last main
|
||||
* entry) points to the next available entry in the main
|
||||
* table. The address of an initial reference table must
|
||||
* also be provided.
|
||||
*
|
||||
* 1) Compute the hash code for the symbol and add it to the base address
|
||||
* of the initial reference table given as input. Thus, two words are
|
||||
* accessed which define the chain on which the symbol must be if it
|
||||
* is in the table at all.
|
||||
*
|
||||
* 2) Alter the table link of the last symbol in the chain so that it
|
||||
* points to the symbol being looked up. Note that the symbol to be
|
||||
* looked up is always placed at the end of the main table before
|
||||
* calling the lookup routine. This essentially adds one more element
|
||||
* to the end of the chain, namely the symbol to be looked up.
|
||||
*
|
||||
* 3) Now start at the first symbol in the chain and follow the chain
|
||||
* looking for a symbol equal to the symbol being looked up. It is
|
||||
* guaranteed that such a symbol will be found because it is always
|
||||
* the last symbol on the chain.
|
||||
*
|
||||
* 4) When the symbol is found, check to see if it is the last symbol
|
||||
* on the chain. If not, the symbol being looked for is in the table
|
||||
* and has been found. If it is the last symbol, the symbol being
|
||||
* looked up is not in the table.
|
||||
*
|
||||
* 5) In the case the looked up symbol is not found, it is usually added
|
||||
* to the end of the table. This is done simply b changing the
|
||||
* initial reference table entry which points to the previous
|
||||
* last symbol on the chain so that is now points to the symbol at the
|
||||
* end of the main table. In case the symbol just looked up is not to
|
||||
* be added to the main table then no action is needed . This means
|
||||
* that the table link of the last symbol on a chain may point any-
|
||||
* where.
|
||||
*
|
||||
* look up entry in the main table
|
||||
* call with:
|
||||
* address of initial reference table
|
||||
* entry to be looked up at the end of the main table
|
||||
* returns:
|
||||
* a pointer to the entry. if this pointer is equal to
|
||||
* lmte then the symbol was not previously in the table.
|
||||
**/
|
||||
char *
|
||||
lemt(oplook,airt)
|
||||
char **airt;
|
||||
int oplook; /* if true then looking in opcode table */
|
||||
{
|
||||
register char *mtpt;
|
||||
register short *p1, *p2, i, j;
|
||||
|
||||
if (oplook) { /* [vlh] get rid of preceding '.', to lowercase */
|
||||
if (lmte->name[0]=='.') {
|
||||
lmte->name[NAMELEN-1] = NULL; /* in case of '.' */
|
||||
j = 1;
|
||||
}
|
||||
else
|
||||
j = 0;
|
||||
for (i=0; j<NAMELEN; i++, j++)
|
||||
lmte->name[i] = tolower(lmte->name[j]);
|
||||
}
|
||||
pirt = airt + hash(); /*hashed ptr to irt*/
|
||||
mtpt = pirt->irfe; /*pointer to first entry in chain*/
|
||||
if(!mtpt) /*empty chain*/
|
||||
mtpt = lmte; /*start at end of main table*/
|
||||
else
|
||||
(pirt->irle)->tlnk = lmte; /*last entry in chain is new symbol*/
|
||||
if((lmte->name[0]=='~') && (lmte->name[1]!='~') && (lmte->name[1]!='.'))
|
||||
return(lmte); /*[vlh] 4.2, force local symbols */
|
||||
|
||||
/*loop to locate entry in main table*/
|
||||
lemtl:
|
||||
p1 = &mtpt->name[0];
|
||||
p2 = &lmte->name[0];
|
||||
i = NAMELEN/(sizeof i);
|
||||
while(i) {
|
||||
if(*p1++ != *p2++) {
|
||||
mtpt = mtpt->tlnk; /*go to next entry in chain*/
|
||||
goto lemtl;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
return(mtpt);
|
||||
}
|
||||
|
||||
/* compute a hash code for the last entry in the main table*/
|
||||
/* returns the hash code*/
|
||||
hash()
|
||||
{
|
||||
register short i, ht1;
|
||||
register char *p;
|
||||
|
||||
ht1 = 0;
|
||||
p = &lmte->name[0];
|
||||
for(i=0; i<NAMELEN; i++)
|
||||
ht1 += *p++;
|
||||
return(ht1&(SZIRT-2)); /*make hash code even and between 0 & SZIRT-2*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Make an entry in the main table
|
||||
* assumes :
|
||||
* entry to be made is pointed at by lmte
|
||||
* pirt points to the correct initial reference table entry.
|
||||
*/
|
||||
mmte()
|
||||
{
|
||||
pirt->irle = lmte; /*pointer to last entry in chain*/
|
||||
if(pirt->irfe == 0) /*first entry in chain*/
|
||||
pirt->irfe = lmte;
|
||||
lmte += STESIZE; /*bump last main table entry pointer*/
|
||||
if(lmte>=emte) { /*main table overflow*/
|
||||
if(sbrk(STESIZE*ICRSZMT) == -1){ /*get more memory*/
|
||||
rpterr("symbol table overflow\n");
|
||||
endit();
|
||||
}
|
||||
else {
|
||||
emte += STESIZE*ICRSZMT; /*move end of main table*/
|
||||
cszmt += ICRSZMT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* make an entry in the main table for a directive
|
||||
* call with:
|
||||
* pointer to string containing directive name
|
||||
* address of routine to handle directive in pass one
|
||||
* address of routine to handle directive in pass two
|
||||
*/
|
||||
mdemt(mdstr,dirnum)
|
||||
char *mdstr;
|
||||
int dirnum;
|
||||
{
|
||||
register char *mdept;
|
||||
|
||||
pack(mdstr,lmte); /*pack name at end of main table*/
|
||||
mdept=lemt(TRUE,oirt); /*look up in opcode table*/
|
||||
if(mdept != lmte) { /*best not be there already*/
|
||||
uerr(5);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
mmte(); /*make main table entry*/
|
||||
mdept->flags |= OPDR|SYIN; /*directive*/
|
||||
mdept->vl1 = dirnum; /*directive #*/
|
||||
}
|
||||
|
||||
/*
|
||||
* pack a string into an entry in the main table
|
||||
* call with:
|
||||
* pointer to the string
|
||||
* pointer to desired entry in the main table
|
||||
*/
|
||||
pack(apkstr,apkptr)
|
||||
char *apkstr, *apkptr;
|
||||
{
|
||||
register short i;
|
||||
register char *pkstr, *pkptr;
|
||||
|
||||
pkstr = apkstr;
|
||||
pkptr = apkptr;
|
||||
i = NAMELEN;
|
||||
while(*pkstr && i) {
|
||||
*pkptr++ = *pkstr++;
|
||||
i--;
|
||||
}
|
||||
while(i--)
|
||||
*pkptr++ = '\0'; /*pad with nulls*/
|
||||
}
|
||||
|
||||
#ifdef CPM
|
||||
int xcol = 0; /* Column number */
|
||||
int spcnt = 0; /* Fill counter */
|
||||
#endif
|
||||
/* function to get characters from source file*/
|
||||
gchr()
|
||||
{
|
||||
register short chr1;
|
||||
|
||||
if(peekc) {
|
||||
chr1 = peekc;
|
||||
peekc = 0;
|
||||
#ifdef CPM
|
||||
if(chr1 != SOH)
|
||||
xcol--;
|
||||
#endif
|
||||
}
|
||||
#ifdef CPM
|
||||
else if(spcnt)
|
||||
{
|
||||
spcnt--;
|
||||
return(' ');
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
gchr1:
|
||||
if(sbuflen<=0){ /*nothing on input buffer*/
|
||||
sbuflen=read(ifn,sbuf,BSIZE); /*read in source*/
|
||||
if(sbuflen<=0)
|
||||
return(EOF); /*end of file*/
|
||||
psbuf = sbuf;
|
||||
}
|
||||
chr1 = *psbuf++;
|
||||
sbuflen--;
|
||||
}
|
||||
if (chr1 == SOH) /*preprocessor flag*/
|
||||
goto gchr1; /*ignore it*/
|
||||
if(chr1 == EOLC) { /*end of line*/
|
||||
#ifdef CPM
|
||||
xcol = -1; /* Init column counter */
|
||||
#endif
|
||||
if(!p2flg) /*pass 1 only*/
|
||||
absln++;
|
||||
}
|
||||
else if(chr1=='\t') { /*convert tabs to spaces*/
|
||||
#ifdef CPM
|
||||
spcnt += 7 - (xcol&7); /* Set fill count */
|
||||
xcol += spcnt; /* Adjust column number */
|
||||
#endif
|
||||
chr1 = ' ';
|
||||
}
|
||||
#ifdef CPM
|
||||
xcol++; /* Bump column number */
|
||||
#endif
|
||||
return(chr1);
|
||||
}
|
||||
|
||||
/*
|
||||
* write out intermediate text for one statement
|
||||
* call with
|
||||
* the it for the statement in stbuf
|
||||
*/
|
||||
wostb()
|
||||
{
|
||||
register short woix, *itwo, i;
|
||||
|
||||
if(stbuf[0].itty != ITBS)
|
||||
abort(); /*not beginning of stmt*/
|
||||
itwo = &stbuf;
|
||||
woix = stbuf[0].itrl & 0377; /*unsigned byte*/
|
||||
while(woix--) {
|
||||
for(i=0; i<STBFSIZE/(sizeof *itwo); i++) {
|
||||
if(pitix > &itbuf[ITBSZ-1]) /*no room in buffer*/
|
||||
doitwr();
|
||||
*pitix++ = *itwo++; /*first word*/
|
||||
}
|
||||
}
|
||||
/* debug(); //call debug package*/
|
||||
}
|
||||
|
||||
doitwr()
|
||||
{
|
||||
register short i;
|
||||
|
||||
if(write(itfn,itbuf,ITBSZ*(sizeof i)) != ITBSZ*(sizeof i)) {
|
||||
rpterr("it write error errno=%o\n",errno);
|
||||
endit();
|
||||
}
|
||||
pitix = itbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* user source error
|
||||
* call with:
|
||||
* number to indicate reason for error
|
||||
* types the error number and the line number on which
|
||||
* the error occured.
|
||||
*/
|
||||
uerr(errn)
|
||||
int errn;
|
||||
{
|
||||
#ifndef CPM
|
||||
putchar(0); /* clear the buffer */
|
||||
stdofd = STDERR; /* output file descriptor <== STDERR */
|
||||
if(p2flg) { /*pass 2 gets two ampersands*/
|
||||
in_err++; /* [vlh] instrlen <- pass1 estimation */
|
||||
printf("&& %d: %s\n",p2absln,ermsg[errn-1]);
|
||||
}
|
||||
else
|
||||
printf("& %d: %s\n",(fchr==EOLC)?absln-1:absln,
|
||||
ermsg[errn-1]);
|
||||
putchar(0);
|
||||
stdofd = STDOUT;
|
||||
nerror++;
|
||||
#else
|
||||
if(p2flg) { /*pass 2 gets two ampersands*/
|
||||
in_err++; /* [vlh] instrlen <- pass1 estimation */
|
||||
fprintf(stderr,"&& %d: %s\n",p2absln,ermsg[errn-1]);
|
||||
}
|
||||
else
|
||||
fprintf(stderr,"& %d: %s\n",(fchr==EOLC)?absln-1:absln,
|
||||
ermsg[errn-1]);
|
||||
nerror++;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* user error that causes the statement to be abandoned
|
||||
* call with:
|
||||
* error number
|
||||
*/
|
||||
xerr(xern)
|
||||
int xern;
|
||||
{
|
||||
uerr(xern); /*type error message*/
|
||||
if(!p2flg) /*pass one*/
|
||||
igrst(); /*pass rest of source*/
|
||||
}
|
||||
|
||||
/* abort the assembly*/
|
||||
abort()
|
||||
{
|
||||
rpterr("as68 abort\n");
|
||||
endit();
|
||||
}
|
||||
|
||||
/*ignore rest of statement*/
|
||||
igrst()
|
||||
{
|
||||
while(fchr!=EOLC && fchr!=EOF) /*until end of line*/
|
||||
fchr=gchr();
|
||||
while((fchr=gchr())==EOLC) ; /*ignore null lines*/
|
||||
}
|
||||
|
||||
/*ignore blanks after a label*/
|
||||
ligblk()
|
||||
{
|
||||
if(fchr == EOF) return;
|
||||
igblk();
|
||||
if(fchr==EOLC) {
|
||||
fchr=gchr();
|
||||
ligblk();
|
||||
}
|
||||
}
|
||||
|
||||
rubout()
|
||||
{
|
||||
nerror = -1;
|
||||
endit();
|
||||
}
|
||||
|
||||
/* exit from the assembler*/
|
||||
endit()
|
||||
{
|
||||
LASTCHTFN = itfnc;
|
||||
unlink(tfilname); /*delete temporary files*/
|
||||
LASTCHTFN = trbfnc;
|
||||
unlink(tfilname);
|
||||
LASTCHTFN = dafnc;
|
||||
unlink(tfilname);
|
||||
LASTCHTFN = drbfnc;
|
||||
unlink(tfilname);
|
||||
if(nerror != -1) { /*not rubout*/
|
||||
if(ftudp)
|
||||
putchar('\n');
|
||||
#ifndef CPM
|
||||
putchar(0); /* flush the printing*/
|
||||
#endif
|
||||
}
|
||||
if(nerror > 0) {
|
||||
#ifndef CPM
|
||||
putchar(0);
|
||||
stdofd = STDERR;
|
||||
printf("& %d errors\n",nerror);
|
||||
putchar(0);
|
||||
#else
|
||||
fprintf(stderr,"& %d errors\n",nerror);
|
||||
#endif
|
||||
}
|
||||
if (initflg)
|
||||
unlink(ldfn); /* [vlh] get rid of empty .o file */
|
||||
exit(nerror!=0);
|
||||
}
|
||||
|
||||
/*
|
||||
* open files
|
||||
* call with:
|
||||
* pointer to name of file to open
|
||||
* flag for how to open
|
||||
* 0 => read
|
||||
* 1 => write
|
||||
* Flag for file type
|
||||
* 0 => ASCII
|
||||
* 1 => Binary
|
||||
*/
|
||||
openfi(pname,hflag,file)
|
||||
char *pname;
|
||||
int hflag;
|
||||
int file;
|
||||
{
|
||||
register short fd;
|
||||
|
||||
fd = (hflag) ? creat(pname,0666,file) : open(pname,hflag,file);
|
||||
if(fd < 0) { /*open failed*/
|
||||
rpterr("can't open %s errno=%o\n",pname,errno);
|
||||
endit();
|
||||
}
|
||||
return(fd);
|
||||
}
|
||||
|
||||
/* get a temp file for the intermediate text*/
|
||||
gettempf()
|
||||
{
|
||||
register short j;
|
||||
#ifndef CPM
|
||||
register char *p;
|
||||
|
||||
if(LASTCHTFN == 'A') {
|
||||
j = getpid();
|
||||
p = &LASTCHTFN-4;
|
||||
while(p < &LASTCHTFN) {
|
||||
*p++ = (j&017) + 'a';
|
||||
j >>= 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while(LASTCHTFN < 'z') {
|
||||
LASTCHTFN++;
|
||||
if((j=creat(tfilname,0600))>=0)
|
||||
return(j);
|
||||
}
|
||||
rpterr("temp file create error: %s errno=%o\n",tfilname,errno);
|
||||
endit();
|
||||
}
|
||||
|
||||
/* move label name from lbt to main table entry pointed to by lmte*/
|
||||
setname()
|
||||
{
|
||||
register short *p1, *p2;
|
||||
|
||||
p1 = &lmte->name[0];
|
||||
for(p2 = &lbt[0]; p2 < &lbt[NAMELEN]; ) {
|
||||
*p1++ = *p2;
|
||||
*p2++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the initialized main table and initial reference tables from*/
|
||||
/* the initialize file*/
|
||||
getsymtab()
|
||||
{
|
||||
register char **p;
|
||||
register struct symtab *p1;
|
||||
register char *p2;
|
||||
register short fd,i;
|
||||
#ifdef CPM
|
||||
int j;
|
||||
#endif
|
||||
if((fd=open(initfnam,0)) < 0) {
|
||||
rerr:
|
||||
rpterr("& Unable to read init file: %s\n", initfnam);
|
||||
endit();
|
||||
}
|
||||
if(read(fd,sirt,SZIRT*SIRTSIZE) != SZIRT*SIRTSIZE) {
|
||||
goto rerr;
|
||||
}
|
||||
|
||||
if(read(fd,oirt,SZIRT*SIRTSIZE) != SZIRT*SIRTSIZE)
|
||||
goto rerr;
|
||||
|
||||
#ifdef CPM /* NO byte level EOF */
|
||||
if(read(fd,&j,sizeof(j)) != sizeof(j))
|
||||
goto rerr;
|
||||
if((i=read(fd,bmte,j)) != j)
|
||||
goto rerr;
|
||||
#else
|
||||
if((i=read(fd,bmte,SZMT*STESIZE)) <= 0)
|
||||
goto rerr;
|
||||
#endif
|
||||
|
||||
if((i%STESIZE) != 0)
|
||||
goto rerr;
|
||||
|
||||
lmte = bmte + i;
|
||||
p2 = bmte-1;
|
||||
for(p=sirt; p<&sirt[SZIRT]; p++) {
|
||||
if(*p)
|
||||
*p += (long)p2; /* 11 apr 83, for vax */
|
||||
}
|
||||
for(p=oirt; p<&oirt[SZIRT]; p++) {
|
||||
if(*p)
|
||||
*p += (long)p2; /* 11 apr 83, for vax */
|
||||
}
|
||||
for(p1=bmte; p1<lmte; p1++) {
|
||||
if(p1->tlnk)
|
||||
p1->tlnk += (long)p2; /* 11 apr 83, for vax */
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* write the initialization file*/
|
||||
putsymtab()
|
||||
{
|
||||
register char **p;
|
||||
register struct symtab *p1;
|
||||
register char *p2;
|
||||
register short fd,i;
|
||||
#ifdef CPM
|
||||
int j; /* Temp */
|
||||
#endif
|
||||
if((fd=creat(initfnam,0644))<0) {
|
||||
werr:
|
||||
printf("& Write error on init file: %s\n", initfnam);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* change all pointers so that they are relative to the beginning
|
||||
* of the symbol table
|
||||
*/
|
||||
p2 = bmte-1;
|
||||
for(p=sirt; p<&sirt[SZIRT]; p++) {
|
||||
if(*p)
|
||||
*p = *p - p2; /* 11 apr 83, for vax */
|
||||
}
|
||||
for(p=oirt; p<&oirt[SZIRT]; p++) {
|
||||
if(*p)
|
||||
*p = *p - p2; /* 11 apr 83, for vax */
|
||||
}
|
||||
for(p1=bmte; p1<lmte; p1++) {
|
||||
if(p1->tlnk)
|
||||
p1->tlnk = p1->tlnk - p2; /* 11 apr 83, for vax */
|
||||
}
|
||||
|
||||
if(write(fd,sirt,SZIRT*SIRTSIZE) != SZIRT*SIRTSIZE) {
|
||||
goto werr;
|
||||
}
|
||||
|
||||
if(write(fd,oirt,SZIRT*OIRTSIZE) != SZIRT*OIRTSIZE)
|
||||
goto werr;
|
||||
|
||||
i = (char *)lmte - bmte; /*length of current main table*/
|
||||
if((i % STESIZE) != 0) {
|
||||
goto werr;
|
||||
}
|
||||
#ifdef CPM /* NO byte level EOF */
|
||||
j = i; /* Put in memory */
|
||||
if(write(fd,&j,sizeof(j)) != sizeof(j))
|
||||
goto werr;
|
||||
#endif
|
||||
if(write(fd,bmte,i) != i)
|
||||
goto werr;
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* print an error on file descriptor 2*/
|
||||
/* used for errors with disasterous consequences*/
|
||||
rpterr(ptch,x1,x2,x3,x4,x5,x6)
|
||||
char *ptch;
|
||||
{
|
||||
#ifndef CPM
|
||||
putchar(0); /*flush buffer*/
|
||||
stdofd = STDERR; /*error file*/
|
||||
printf("& %d: ",absln);
|
||||
printf(ptch,x1,x2,x3,x4,x5,x6);
|
||||
nerror++; /* [vlh] 4.2.... */
|
||||
#else
|
||||
fprintf(stderr,"& %d: ",absln);
|
||||
fprintf(stderr,ptch,x1,x2,x3,x4,x5,x6);
|
||||
nerror++; /* [vlh] 4.2.... */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* set the file name for the relocatable object file (sourcefile.o)*/
|
||||
setldfn(ap)
|
||||
char *ap;
|
||||
{
|
||||
register char *p1,*p2;
|
||||
|
||||
p1 = ap;
|
||||
p2 = ldfn;
|
||||
while(*p1) {
|
||||
*p2++ = *p1++;
|
||||
}
|
||||
if(*(p2-2) != '.') { /*not name.?*/
|
||||
*p2++ = '.';
|
||||
*p2++ = 'o';
|
||||
}
|
||||
else { /* is name.? */
|
||||
*(p2-1) = 'o';
|
||||
}
|
||||
*p2 = '\0';
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
char *compiled = "@(#) assembler 4.3 - Fri Dec 30 09:38 1983";
|
||||
Reference in New Issue
Block a user