Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,427 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "mach.h"
#ifdef VAX11
# include <c68/sys/cout.h>
#endif
#ifdef PDP11
# include <c68/sys/cout.h>
#endif
#ifdef MC68000
# include <sys/cout.h>
#endif
#ifdef DRI
# include <stdio.h>
# include <klib.h>
# include <ctype.h>
# include <cout.h>
#endif
/* 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*/
#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*/
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*/
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[];
#define LASTCHTFN tfilname[11]
/* 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();
int hifeq(), hifne(), hiflt(), hifle(), hifgt(), hifge(), hendc();
int hifnc(), hifc(), hopt();

View File

@@ -0,0 +1,235 @@
**
* 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
**
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
.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

View File

@@ -0,0 +1,10 @@
c68 -L -r -DMC68000 -c dir.c
c68 -L -r -DMC68000 -c expr.c
c68 -L -r -DMC68000 -c misc.c
c68 -L -r -DMC68000 -c pass1a.c
c68 -L -r -DMC68000 -c pass2.c
c68 -L -r -DMC68000 -c symt.c
c68 -L -r -DMC68000 -c main.c
mkver -e "assembler -"
c68 -n -L -r -DMC68000 -r dir.o expr.o misc.o pass1a.o pass2.o symt.o main.o version.c -o as68.4k -l6
setstack as68.4k 8192 8192

View File

@@ -0,0 +1,10 @@
mkver -e "assembler -"
cc -w -DPDP11 -c dir.c
cc -w -DPDP11 -c expr.c
cc -w -DPDP11 -c main.c
cc -w -DPDP11 -c misc.c
cc -w -DPDP11 -c pass1a.c
cc -w -DPDP11 -c pass2.c
cc -w -DPDP11 -c symt.c
cc -w -DPDP11 -c version.c
cc -n dir.o expr.o misc.o pass1a.o pass2.o symt.o main.o seek.o lseek.o version.o -o as68.pdp -l6 -lC

View File

@@ -0,0 +1,10 @@
mkver -e "assembler -"
cc -O -w -DVAX11 -c dir.c
cc -O -w -DVAX11 -c expr.c
cc -O -w -DVAX11 -c main.c
cc -O -w -DVAX11 -c misc.c
cc -O -w -DVAX11 -c pass1a.c
cc -O -w -DVAX11 -c pass2.c
cc -O -w -DVAX11 -c symt.c
cc -O -w -DVAX11 -c version.c
cc -n dir.o expr.o misc.o pass1a.o pass2.o symt.o main.o version.o ../binary/libV.a -o as68.vax

View File

@@ -0,0 +1,152 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *ermsg[] = {
0, /*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 tfilname[] = "/tmp/a6xxxxA"; /*temp file for it*/
#ifdef MC68000
char initfnam[] = "/lib/as68symb"; /*initialize file name*/
#else
char initfnam[] = "/usr/local/lib/as68symb";
#endif
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*/
0, /*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*/

View File

@@ -0,0 +1,939 @@
/*
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 */
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()
{
if(loctr&1) { /*have to make it even*/
dorlst(rlflg);
loctr++;
}
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.hiword = ival; /* # bytes of storage required*/
}
else
lblpt->vl1.hiword = 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->vl1.loword = (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 = &regmsk; 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;
}
loctr = ival;
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();
}
/* hpage - page directive, ignore */
hpage() /* vlh */
{
igrst();
}
/* 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);
}
if(savelc[DATA]&1) {
rlflg = DATA;
outbyte(0,DABS);
}
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) || lwritel(lfn,&stlen) == -1)
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;
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)
char *s, *t;
{
for( ; *s == *t; s++, t++ )
if( *s == '\0' )
return(0);
return( *s - *t );
}

View 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 = '?';
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->vl1.loword; /*get external #*/
rval = EXTRN;
itype = ITCN;
ival = 0;
}

View File

@@ -0,0 +1,170 @@
.he "As68"Revisions"Page %"
.de bg
.sp
.in +5
..
.de eg
.sp
.ne 8
.in -5
..
1. [vlh] 15 sep 82
.bg
Added fix to make location relative equates correct even if branch
optimization occurs.
.eg
2. [vlh] 17 sep 82
.bg
Recognizes commands in uppercase. Added recognization of upper case
directives which do not have the preceding '.'.
.eg
3. [vlh] 17 sep 82
.bg
Added recognizing of ignored directives IDNT, ORG and MASK2.
Added new directives XDEF, XREF.
.eg
4. [vlh] 20 sep 82
.bg
Added COMLINE and SECTION.
.eg
5. [vlh] 21 sep 82
.bg
Added new directive REG.
.eg
6. [vlh] 22 sep 82
.bg
Added new directives DCB and OFFSET.
.eg
7. [vlh] 22 sep 82
.bg
Recognizes branch extensions and takes the appropriate action.
.eg
8. [vlh] 23 sep 82
.bg
Added assembler directives ifeq, ifne, ifle, iflt, ifge, ifgt.
.eg
9. [vlh] 23 sep 82
.bg
Added character '$' to set of legitimate characters in a symbol.
.eg
10. [vlh] 23 sep 82
.bg
Added new ignored directive OPT.
.eg
11. [vlh] 23 sep 82
.bg
Recognizes non-opcodes starting in column 1 as labels.
.eg
12. [vlh] 27 sep 82
.bg
Added conditional assembler directives ifc, ifnc.
.eg
13. [vlh] 01 oct 82
.bg
Major reworking of expression handler.
.eg
14. [vlh] 04 oct 82
.bg
More revisions to expression stacks.
.eg
15. [vlh] 26 oct 82
.bg
Added the recognition and handling of the 'illegal' instruction.
.eg
16. [vlh] 26 oct 82
.bg
Added handling of the jmp suffixes.
.eg
17. [vlh] 27 oct 82
.bg
Fixed problem with -p flag and external variable listings.
.eg
18. [vlh] 28 oct 82
.bg
Added checking for legitimate command suffixes.
.eg
19. [vlh] 28 oct 82
.bg
Added comma as a legitimate register divisor for the REG directive.
.eg
20. [vlh] 28 oct 82
.bg
Fixed second pass error/instr len problem
.eg
21. [vlh] 01 nov 82
.bg
Added checking for invalid bit ranges.
.eg
22. [vlh] 02 nov 82
.bg
Added proper 2nd pass handling of the '*' symbol (avoid turning jsr to bra).
.eg
23. [vlh] 04 nov 82
.bg
Fixed first pass guess if operand is (rx,rx) instead of d(rx,rx).
.eg
24. [vlh] 05 nov 82
.bg
Check for appropriate range of 16-bit immediate date.
.eg
25. [vlh] 05 nov 82
.bg
Operand type check for shift/bit manipulation.
.eg
26. [vlh] 05 nov 82
.bg
Turn and/or/eor #xxx,sr/ccr into the corresponding immediate instruction.
.eg
27. [vlh] 10 nov 82
.bg
Generate an error when an illegal pc relative ea is specified.
.eg
28. [vlh] 21 dec 82
.bg
Ignore PAGE and TTL macros.
.eg
29. [vlh] 7 jan 83
.bg
Generate an error on ".bss\n.dc.b 1\n".
.eg
30. [vlh] 19 jan 83
.bg
Generate an error on "move ccr,??".
.eg
31. [bea] 09 mar 83
.bg
Fixed problem of )* in expression.
.eg
32. [vlh] 16 mar 83
.bg
\&.ds should be allowed inside .offset
.eg
33. [vlh] 18 apr 83, version 4.1
.bg
Made it portable to vaxens via the use of #define's.
.eg
34. [vlh] 19 jul 83
.bg
Added the '-a' flag, made '-L' the default.
.eg
35. [vlh] 25 jul 83
.bg
Forced local symbols to be put into the symbol table even if non-unique.
.eg
36. [vlh] 03 aug 83
.bg
Made changes to as68init required for use with the 68010. Added
the new opcodes for movec, moves and rtd, and the new control registers
sfc, dfc and vsr.
.eg
37. [vlh] 04 aug 83
.bg
Added a new routine opf13 to handle the opcodes movec and moves. Added the
new code to opf9 to handle rtd.
.eg
38. [vlh] 07 sep 83
.bg
Made rpterr increment the number of errors which had occured in order to
force endit to return a bad status.
.eg

View 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

View File

@@ -0,0 +1,801 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version = "@(#)as68 assembler 4.2 - Sep 6, 1983";
/*
* 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"
#include <signal.h>
#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;
signal(SIGINT,rubout);
pitix = itbuf;
pexti = extbl;
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*/
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*/
didorg++;
break;
case 'L': /*4.2 OBSOLETE, long addresses only*/
shortadr = 0;
break;
case 'T': /*generating code suitable for the 68010*/
m68010++;
break;
default:
usage();
}
}
if(i>=argc)
usage();
ifn=openfi(argv[i],0); /*open source file*/
setldfn(argv[i]); /*create relocatable object file name*/
lfn=openfi(ldfn,1); /*open loader file*/
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;
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()
{
rpterr("Usage: as68 [-p] [-u] [-L] [-N] sourcefile\n");
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])
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) {
rpterr("label redefined %s\n",lbt); /* non fatal err */
lblpt = 0;
return;
}
}
}
else {
mmte(); /*make label entry in main table*/
}
lblpt->flags |= SYDF; /*label is now defined*/
lblpt->flags |= (rlflg==DATA)?SYRA:(rlflg==BSS)?SYBS:SYRO;
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 /*yes, a register*/
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);
}

View File

@@ -0,0 +1,79 @@
CC = cc
C68 = nc68
SOURCES = dir.c expr.c misc.c pass1a.c pass2.c symt.c main.c
INCLUDES = as68.h cout.h order.h
VAXOBJS = vaxobj/dir.o vaxobj/expr.o vaxobj/misc.o vaxobj/pass1a.o \
vaxobj/pass2.o vaxobj/symt.o vaxobj/main.o
C68OBJS = 68obj/dir.o 68obj/expr.o 68obj/misc.o 68obj/pass1a.o \
68obj/pass2.o 68obj/symt.o 68obj/main.o
CFLAGS = -w -O -DVAX11
C68FLAGS = -L -r -DMC68000 -t0 -t1
LIB = -lV6
C68LIB = -l6
vax: ${VAXOBJS}
@mkver -e "assembler -"
${CC} ${CFLAGS} version.c ${VAXOBJS} -o as68.vax ${LIB}
as68: ${C68OBJS}
@mkver -e "assembler -"
${C68} ${C68FLAGS} ${C68OBJS} version.c -o as68.68 ${C68LIB}
@setstack as68.68 8192 8192
2k: ${C68OBJS}
@mkver -e "assembler -"
${C68} -n2 ${C68FLAGS} -r ${C68OBJS} version.c -o as68.2k ${C68LIB}
@setstack as68.2k 8192 8192
4k: ${C68OBJS}
@mkver -e "assembler -"
${C68} -n ${C68FLAGS} -r ${C68OBJS} version.c -o as68.4k ${C68LIB}
@setstack as68.4k 8192 8192
all: vax 4k
tags:
ctags ${SOURCES} ${INCLUDES}
vaxobj/dir.o: dir.c
${CC} ${CFLAGS} -c dir.c;mv -f dir.o vaxobj/dir.o
vaxobj/expr.o: expr.c
${CC} ${CFLAGS} -c expr.c;mv -f expr.o vaxobj/expr.o
vaxobj/misc.o: misc.c
${CC} ${CFLAGS} -c misc.c;mv -f misc.o vaxobj/misc.o
vaxobj/pass1a.o: pass1a.c
${CC} ${CFLAGS} -c pass1a.c;mv -f pass1a.o vaxobj/pass1a.o
vaxobj/pass2.o: pass2.c
${CC} ${CFLAGS} -c pass2.c;mv -f pass2.o vaxobj/pass2.o
vaxobj/symt.o: symt.c
${CC} ${CFLAGS} -c symt.c;mv -f symt.o vaxobj/symt.o
vaxobj/main.o: main.c
${CC} ${CFLAGS} -c main.c;mv -f main.o vaxobj/main.o
68obj/dir.o: dir.c
${C68} ${C68FLAGS} -c dir.c;mv -f dir.o 68obj/dir.o
68obj/expr.o: expr.c
${C68} ${C68FLAGS} -c expr.c;mv -f expr.o 68obj/expr.o
68obj/misc.o: misc.c
${C68} ${C68FLAGS} -c misc.c;mv -f misc.o 68obj/misc.o
68obj/pass1a.o: pass1a.c
${C68} ${C68FLAGS} -c pass1a.c;mv -f pass1a.o 68obj/pass1a.o
68obj/pass2.o: pass2.c
${C68} ${C68FLAGS} -c pass2.c;mv -f pass2.o 68obj/pass2.o
68obj/symt.o: symt.c
${C68} ${C68FLAGS} -c symt.c;mv -f symt.o 68obj/symt.o
68obj/main.o: main.c
${C68} ${C68FLAGS} -c main.c;mv -f main.o 68obj/main.o

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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*/

View File

@@ -0,0 +1,105 @@
/*
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); /*open it for reading*/
writfn = open(tfilname,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) {
i = 2; /*[vlh]was 4 for ival=2*/
if (!ival) stbuf[2].itop.ptrw2 = nopptr;
}
else
continue;
fixsyadr(i);
reduced += i;
stbuf[1].itrl -= i; /*reduced 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 2 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*/
}
}
}

View File

@@ -0,0 +1,847 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*
* 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); /*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);
}
if (!ival) { /* make it a nop */
opcpt = nopptr;
ins[0] = opcpt->vl1.loword;
pins = &ins[1];
if (modelen == LONGSIZ) {
*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)<<11) & 0x8000;
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)<<11) & 0xF000;
if (!memalt(eaop) || pcea(eaop) || ckreg(eaop))
uerr(20);
ins[0] |= eaop->ea;
doea(eaop);
}
}

View File

@@ -0,0 +1,10 @@
This is a list of the files in this directory:
main.c: Main routine and utilities
symt.c Symbol table and miscellaneous pass 1 routines
dir.c Handle all directives including conditional assembly
expr.c: Expression handling routines
pass1a.c Pass1a branch optimization
pass2.c Second pass main routines
misc.c Second pass miscellaneous routines
The Shared Text version will no longer assemble test.s on the pdp11-23

View File

@@ -0,0 +1,822 @@
/*
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*/
}
/* function to get characters from source file*/
gchr()
{
register short chr1;
if(peekc) {
chr1 = peekc;
peekc = 0;
}
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*/
if(!p2flg) /*pass 1 only*/
absln++;
}
else if(chr1=='\t') { /*convert tabs to spaces*/
chr1 = ' ';
}
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;
{
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++;
}
/*
* 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');
putchar(0); /* flush the printing*/
}
if(nerror > 0) {
putchar(0);
stdofd = STDERR;
printf("& %d errors\n",nerror);
putchar(0);
}
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
*/
openfi(pname,hflag)
char *pname;
int hflag;
{
register short fd;
fd = (hflag) ? creat(pname,0666) : open(pname,hflag);
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;
register char *p;
if(LASTCHTFN == 'A') {
j = getpid();
p = &LASTCHTFN-4;
while(p < &LASTCHTFN) {
*p++ = (j&017) + 'a';
j >>= 4;
}
}
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;
if((fd=open(initfnam,0)) < 0) {
rerr:
printf("& 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;
if((i=read(fd,bmte,SZMT*STESIZE)) <= 0)
goto rerr;
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;
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;
}
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;
{
putchar(0); /*flush buffer*/
stdofd = STDERR; /*error file*/
printf("& %d: ",absln);
printf(ptch,x1,x2,x3,x4,x5,x6);
nerror++; /* [vlh] 4.2.... */
}
/* 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';
}

View File

@@ -0,0 +1 @@
char *compiled = "@(#) assembler - Thu Sep 8 15:50 1983";