summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-08-11 22:34:54 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2012-08-11 22:34:54 (GMT)
commit4bff55d3ba6bd40d402469bc1d476c20f8e6181b (patch)
treeb8dc24f8b6fa31c0b44c91aba03578ab46d3588b
parent29d30fbd4fe4c172042c38c2eac798c9432f2fd9 (diff)
downloadabc80sim-4bff55d3ba6bd40d402469bc1d476c20f8e6181b.zip
abc80sim-4bff55d3ba6bd40d402469bc1d476c20f8e6181b.tar.gz
abc80sim-4bff55d3ba6bd40d402469bc1d476c20f8e6181b.tar.bz2
abc80sim-4bff55d3ba6bd40d402469bc1d476c20f8e6181b.tar.xz
Add Z80 assembler used for abcdev for nowabc80sim-2.0
-rw-r--r--z80asm/Makefile34
-rw-r--r--z80asm/mio.c130
-rw-r--r--z80asm/zdis.120
-rw-r--r--z80asm/zdis.c1526
-rw-r--r--z80asm/zmac.167
-rw-r--r--z80asm/zmac.y2957
6 files changed, 4734 insertions, 0 deletions
diff --git a/z80asm/Makefile b/z80asm/Makefile
new file mode 100644
index 0000000..1b21908
--- /dev/null
+++ b/z80asm/Makefile
@@ -0,0 +1,34 @@
+# Makefile to make z80 macro assembler.
+
+CC=gcc -traditional
+CFLAGS = -O2
+
+all: zmac zdis
+
+zmac: y.tab.o mio.o
+ $(CC) $(CFLAGS) -o zmac y.tab.o mio.o
+
+y.tab.c: zmac.y
+ yacc zmac.y
+
+zdis: zdis.o
+ $(CC) $(CFLAGS) -o zdis zdis.o
+
+install:
+ install -s zmac /usr/local/bin
+ install -s zdis /usr/local/bin
+
+install_man:
+ cp zmac.1 /usr/man/manl/zmac.l
+ cp zdis.1 /usr/man/manl/zdis.l
+
+clean:
+ rm -f zdis.o zmac.o mio.o y.tab.c y.tab.o a.out core
+
+shar: zmac.shar.1 zmac.shar.2
+
+zmac.shar.1: Makefile zmac.y mio.c zmac.1 zdis.1
+ shar -vc Makefile zmac.y mio.c zmac.1 zdis.1 > zmac.shar.1
+
+zmac.shar.2: zdis.c serial.z serial.hex
+ shar -vc zdis.c serial.z serial.hex > zmac.shar.2
diff --git a/z80asm/mio.c b/z80asm/mio.c
new file mode 100644
index 0000000..195ba3c
--- /dev/null
+++ b/z80asm/mio.c
@@ -0,0 +1,130 @@
+/*
+ * mio.c - Colin Kelley 1-18-87
+ * routines to emulate temporary file handling with memory instead
+ *
+ */
+
+#include <stdio.h>
+#define MALLOC_SIZE 10000
+
+unsigned char *malloc(), *realloc();
+
+static unsigned char *mhead; /* pointer to start of malloc()d area */
+static unsigned char *mend; /* pointer to current (just beyond) EOF*/
+static unsigned char *mptr; /* pointer to current position */
+static unsigned int msize; /* size of chunk mhead points to */
+
+FILE *
+mfopen(filename,mode)
+char *filename,*mode;
+{
+ if ((mhead = malloc(MALLOC_SIZE)) == 0) {
+ msize = 0;
+ return (0);
+ }
+ msize = MALLOC_SIZE;
+ mend = mptr = mhead;
+ return ((FILE *)1); /* not used */
+}
+
+mfclose(f)
+FILE *f;
+{
+ if (mhead) {
+ free(mhead);
+ return (0);
+ }
+ else
+ return (-1);
+}
+
+unsigned int
+mfputc(c,f)
+unsigned int c;
+FILE *f;
+{
+register unsigned char *p;
+ while (mptr >= mhead + msize) {
+ if ((p = realloc(mhead,msize+MALLOC_SIZE)) == (unsigned char *)-1) {
+ fputs("mio: out of memory\n",stderr);
+ return (-1);
+ }
+ else {
+ msize += MALLOC_SIZE;
+ mptr = (unsigned char *) (p + (unsigned int)(mptr - mhead));
+ mhead = p;
+ }
+ }
+ *mptr = c & 255;
+ mend = ++mptr;
+ return c;
+}
+
+unsigned int
+mfgetc(f)
+FILE *f;
+{
+ if (mptr >= mend) /* no characters left */
+ return (-1);
+ else
+ return (*mptr++);
+}
+
+mfseek(f,loc,origin)
+FILE *f;
+long loc;
+int origin;
+{
+ if (origin != 0) {
+ fputs("mseek() only implemented with 0 origin",stderr);
+ return (-1);
+ }
+ mptr = mhead + loc;
+ return (0);
+}
+
+mfread(ptr, size, nitems,f)
+char *ptr;
+unsigned int size, nitems;
+FILE *f;
+{
+register unsigned int i = 0;
+ while (i < nitems) {
+ if ((mptr + size) > mend)
+ break;
+ bcopy(mptr,ptr,size);
+ ptr += size;
+ mptr += size;
+ i++;
+ }
+ return (i);
+}
+
+mfwrite(ptr, size, nitems, f)
+char *ptr;
+int size, nitems;
+FILE *f;
+{
+register unsigned int i = 0;
+register unsigned char *p;
+ while (i < nitems) {
+ while (mptr + size >= mhead + msize) {
+ if ((p = realloc(mhead,msize+MALLOC_SIZE)) == (unsigned char *)-1){
+ fputs("mio: out of memory\n",stderr);
+ return (-1);
+ }
+ else {
+ msize += MALLOC_SIZE;
+ mptr = (unsigned char *) (p + (unsigned int)(mptr - mhead));
+ mhead = p;
+ }
+ }
+ if ((mptr + size) > mhead + msize)
+ break;
+ bcopy(ptr,mend,size);
+ ptr += size;
+ mend += size;
+ mptr = mend;
+ }
+ return (i);
+}
diff --git a/z80asm/zdis.1 b/z80asm/zdis.1
new file mode 100644
index 0000000..8b10975
--- /dev/null
+++ b/z80asm/zdis.1
@@ -0,0 +1,20 @@
+.TH ZDIS l
+.SH NAME
+zdis \- disassembler for Z80 cross-assembler
+.SH SYNOPSIS
+zdis < infile.hex
+.SH DESCRIPTION
+.I Zdis
+reads a hex file created by
+.I zmac
+and produces a disassembly on stdout.
+.SH SEE ALSO
+zmac(l)
+.SH FILES
+Source is in /usr/local/src/zmac directory.
+.SH BUGS
+Zdis ignores the program counter field in the hex file. Instead it assumes
+that the hex file has an ORG of 0.
+.sp
+The man page is incomplete. If anyone discovers more information about
+using zdis, please consider helping to update the man page.
diff --git a/z80asm/zdis.c b/z80asm/zdis.c
new file mode 100644
index 0000000..d8ed373
--- /dev/null
+++ b/z80asm/zdis.c
@@ -0,0 +1,1526 @@
+#include <stdio.h>
+
+char undefined[] = "undefined";
+
+struct opcode {
+ char *name;
+ int args;
+};
+
+struct opcode major[256] = {
+ "nop", 0, /* 00 */
+ "ld bc,%02x%02xh", 2, /* 01 */
+ "ld bc,a", 0, /* 02 */
+ "inc bc", 0, /* 03 */
+ "inc b", 0, /* 04 */
+ "dec b", 0, /* 05 */
+ "ld b,%02xh", 1, /* 06 */
+ "rlc a", 0, /* 07 */
+
+ "ex af,af'", 0, /* 08 */
+ "add hl,bc", 0, /* 09 */
+ "ld a,(bc)", 0, /* 0a */
+ "dec bc", 0, /* 0b */
+ "inc c", 0, /* 0c */
+ "dec c", 0, /* 0d */
+ "ld c,%02xh", 1, /* 0e */
+ "rrc a", 0, /* 0f */
+
+ "djnz %02xh", 1, /* 10 */
+ "ld de,%02x%02xh", 2, /* 11 */
+ "ld (de),a", 0, /* 12 */
+ "inc de", 0, /* 13 */
+ "inc d", 0, /* 14 */
+ "dec d", 0, /* 15 */
+ "ld d,%02xh", 1, /* 16 */
+ "rla", 0, /* 17 */
+
+ "jr %02xh", 1, /* 18 */
+ "add hl,de", 0, /* 19 */
+ "ld a,(de)", 0, /* 1a */
+ "dec de", 0, /* 1b */
+ "inc e", 0, /* 1c */
+ "dec e", 0, /* 1d */
+ "ld e,%02xh", 1, /* 1e */
+ "rra", 0, /* 1f */
+
+ "jr nz,%02xh", 1, /* 20 */
+ "ld hl,%02x%02xh", 2, /* 21 */
+ "ld (%02x%02xh),hl",2, /* 22 */
+ "inc hl", 0, /* 23 */
+ "inc h", 0, /* 24 */
+ "dec h", 0, /* 25 */
+ "ld h,%02xh", 1, /* 26 */
+ "daa", 0, /* 27 */
+
+ "jr z,%02xh", 1, /* 28 */
+ "add hl,hl", 0, /* 29 */
+ "ld hl,(%02x%02xh)",2, /* 2a */
+ "dec hl", 0, /* 2b */
+ "inc l", 0, /* 2c */
+ "dec l", 0, /* 2d */
+ "ld l,%02xh", 1, /* 2e */
+ "cpl", 0, /* 2f */
+
+ "jr nc,%02xh", 1, /* 30 */
+ "ld sp,%02x%02xh", 2, /* 31 */
+ "ld (%02x%02xh),a", 2, /* 32 */
+ "inc sp", 0, /* 33 */
+ "inc (hl)", 0, /* 34 */
+ "dec (hl)", 0, /* 35 */
+ "ld (hl),%02xh", 1, /* 36 */
+ "scf", 0, /* 37 */
+
+ "jr c,%02xh", 1, /* 38 */
+ "add hl,sp", 0, /* 39 */
+ "ld a,(%02x%02xh)", 2, /* 3a */
+ "dec sp", 0, /* 3b */
+ "inc a", 0, /* 3c */
+ "dec a", 0, /* 3d */
+ "ld a,%02xh", 1, /* 3e */
+ "ccf", 0, /* 3f */
+
+ "ld b,b", 0, /* 40 */
+ "ld b,c", 0, /* 41 */
+ "ld b,d", 0, /* 42 */
+ "ld b,e", 0, /* 43 */
+ "ld b,h", 0, /* 44 */
+ "ld b,l", 0, /* 45 */
+ "ld b,(hl)", 0, /* 46 */
+ "ld b,a", 0, /* 47 */
+
+ "ld c,b", 0, /* 48 */
+ "ld c,c", 0, /* 49 */
+ "ld c,d", 0, /* 4a */
+ "ld c,e", 0, /* 4b */
+ "ld c,h", 0, /* 4c */
+ "ld c,l", 0, /* 4d */
+ "ld c,(hl)", 0, /* 4e */
+ "ld c,a", 0, /* 4f */
+
+ "ld d,b", 0, /* 50 */
+ "ld d,c", 0, /* 51 */
+ "ld d,d", 0, /* 52 */
+ "ld d,e", 0, /* 53 */
+ "ld d,h", 0, /* 54 */
+ "ld d,l", 0, /* 55 */
+ "ld d,(hl)", 0, /* 56 */
+ "ld d,a", 0, /* 57 */
+
+ "ld e,b", 0, /* 58 */
+ "ld e,c", 0, /* 59 */
+ "ld e,d", 0, /* 5a */
+ "ld e,e", 0, /* 5b */
+ "ld e,h", 0, /* 5c */
+ "ld e,l", 0, /* 5d */
+ "ld e,(hl)", 0, /* 5e */
+ "ld e,a", 0, /* 5f */
+
+ "ld h,b", 0, /* 60 */
+ "ld h,c", 0, /* 61 */
+ "ld h,d", 0, /* 62 */
+ "ld h,e", 0, /* 63 */
+ "ld h,h", 0, /* 64 */
+ "ld h,l", 0, /* 65 */
+ "ld h,(hl)", 0, /* 66 */
+ "ld h,a", 0, /* 67 */
+
+ "ld l,b", 0, /* 68 */
+ "ld l,c", 0, /* 69 */
+ "ld l,d", 0, /* 6a */
+ "ld l,e", 0, /* 6b */
+ "ld l,h", 0, /* 6c */
+ "ld l,l", 0, /* 6d */
+ "ld l,(hl)", 0, /* 6e */
+ "ld l,a", 0, /* 6f */
+
+ "ld (hl),b", 0, /* 70 */
+ "ld (hl),c", 0, /* 71 */
+ "ld (hl),d", 0, /* 72 */
+ "ld (hl),e", 0, /* 73 */
+ "ld (hl),h", 0, /* 74 */
+ "ld (hl),l", 0, /* 75 */
+ "halt", 0, /* 76 */
+ "ld (hl),a", 0, /* 77 */
+
+ "ld a,b", 0, /* 78 */
+ "ld a,c", 0, /* 79 */
+ "ld a,d", 0, /* 7a */
+ "ld a,e", 0, /* 7b */
+ "ld a,h", 0, /* 7c */
+ "ld a,l", 0, /* 7d */
+ "ld a,(hl)", 0, /* 7e */
+ "ld a,a", 0, /* 7f */
+
+ "add a,b", 0, /* 80 */
+ "add a,c", 0, /* 81 */
+ "add a,d", 0, /* 82 */
+ "add a,e", 0, /* 83 */
+ "add a,h", 0, /* 84 */
+ "add a,l", 0, /* 85 */
+ "add a,(hl)", 0, /* 86 */
+ "add a,a", 0, /* 87 */
+
+ "adc a,b", 0, /* 88 */
+ "adc a,c", 0, /* 89 */
+ "adc a,d", 0, /* 8a */
+ "adc a,e", 0, /* 8b */
+ "adc a,h", 0, /* 8c */
+ "adc a,l", 0, /* 8d */
+ "adc a,(hl)", 0, /* 8e */
+ "adc a,a", 0, /* 8f */
+
+ "sub b", 0, /* 90 */
+ "sub c", 0, /* 91 */
+ "sub d", 0, /* 92 */
+ "sub e", 0, /* 93 */
+ "sub h", 0, /* 94 */
+ "sub l", 0, /* 95 */
+ "sub (hl)", 0, /* 96 */
+ "sub a", 0, /* 97 */
+
+ "sbc a,b", 0, /* 98 */
+ "sbc a,c", 0, /* 99 */
+ "sbc a,d", 0, /* 9a */
+ "sbc a,e", 0, /* 9b */
+ "sbc a,h", 0, /* 9c */
+ "sbc a,l", 0, /* 9d */
+ "sbc a,(hl)", 0, /* 9e */
+ "sbc a,a", 0, /* 9f */
+
+ "and b", 0, /* a0 */
+ "and c", 0, /* a1 */
+ "and d", 0, /* a2 */
+ "and e", 0, /* a3 */
+ "and h", 0, /* a4 */
+ "and l", 0, /* a5 */
+ "and (hl)", 0, /* a6 */
+ "and a", 0, /* a7 */
+
+ "xor b", 0, /* a8 */
+ "xor c", 0, /* a9 */
+ "xor d", 0, /* aa */
+ "xor e", 0, /* ab */
+ "xor h", 0, /* ac */
+ "xor l", 0, /* ad */
+ "xor (hl)", 0, /* ae */
+ "xor a", 0, /* af */
+
+ "or b", 0, /* b0 */
+ "or c", 0, /* b1 */
+ "or d", 0, /* b2 */
+ "or e", 0, /* b3 */
+ "or h", 0, /* b4 */
+ "or l", 0, /* b5 */
+ "or (hl)", 0, /* b6 */
+ "or a", 0, /* b7 */
+
+ "cp b", 0, /* b8 */
+ "cp c", 0, /* b9 */
+ "cp d", 0, /* ba */
+ "cp e", 0, /* bb */
+ "cp h", 0, /* bc */
+ "cp l", 0, /* bd */
+ "cp (hl)", 0, /* be */
+ "cp a", 0, /* bf */
+
+ "ret nz", 0, /* c0 */
+ "pop bc", 0, /* c1 */
+ "jp nz,%02x%02xh", 2, /* c2 */
+ "jp %02x%02xh", 2, /* c3 */
+ "call nz,%02x%02xh", 2, /* c4 */
+ "push bc", 0, /* c5 */
+ "add a,%02xh", 1, /* c6 */
+ "rst 0", 0, /* c7 */
+
+ "ret z", 0, /* c8 */
+ "ret", 0, /* c9 */
+ "jp z,%02x%02xh", 2, /* ca */
+ 0, 0, /* cb */
+ "call z,%02x%02xh", 2, /* cc */
+ "call %02x%02xh", 2, /* cd */
+ "adc a,%02xh", 1, /* ce */
+ "rst 8", 0, /* cf */
+
+ "ret nc", 0, /* d0 */
+ "pop de", 0, /* d1 */
+ "jp nc,%02x%02xh", 2, /* d2 */
+ "out (%02xh),a", 1, /* d3 */
+ "call nc,%02x%02xh", 2, /* d4 */
+ "push de", 0, /* d5 */
+ "sub %02xh", 1, /* d6 */
+ "rst 10h", 0, /* d7 */
+
+ "ret c", 0, /* d8 */
+ "exx", 0, /* d9 */
+ "jp c,%02x%02xh", 2, /* da */
+ "in a,(%02xh)", 1, /* db */
+ "call c,%02x%02xh", 2, /* dc */
+ 0, 1, /* dd */
+ "sbc a,%02xh", 1, /* de */
+ "rst 18h", 0, /* df */
+
+ "ret po", 0, /* e0 */
+ "pop hl", 0, /* e1 */
+ "jp po,%02x%02xh", 2, /* e2 */
+ "ex (sp),hl", 0, /* e3 */
+ "call po,%02x%02xh", 2, /* e4 */
+ "push hl", 0, /* e5 */
+ "and %02xh", 1, /* e6 */
+ "rst 20h", 0, /* e7 */
+ "ret pe", 0, /* e8 */
+
+ "jp (hl)", 0, /* e9 */
+ "jp pe,%02x%02xh", 2, /* ea */
+ "ex de,hl", 0, /* eb */
+ "call pe,%02x%02xh", 2, /* ec */
+ 0, 2, /* ed */
+ "xor %02xh", 1, /* ee */
+ "rst 28h", 0, /* ef */
+
+ "ret p", 0, /* f0 */
+ "pop af", 0, /* f1 */
+ "jp p,%02x%02xh", 2, /* f2 */
+ "di", 0, /* f3 */
+ "call p,%02x%02xh", 2, /* f4 */
+ "push af", 0, /* f5 */
+ "or %02xh", 1, /* f6 */
+ "rst 30h", 0, /* f7 */
+
+ "ret m", 0, /* f8 */
+ "ld sp,hl", 0, /* f9 */
+ "jp m,%02x%02xh", 2, /* fa */
+ "ei", 0, /* fb */
+ "call m,%02x%02xh", 2, /* fc */
+ 0, 3, /* fd */
+ "cp %02xh", 1, /* fe */
+ "rst 38h", 0, /* ff */
+};
+
+struct opcode minor[4][256] = {
+ /* cb */
+ "rlc b", 0, /* cb00 */
+ "rlc c", 0, /* cb01 */
+ "rlc d", 0, /* cb02 */
+ "rlc e", 0, /* cb03 */
+ "rlc h", 0, /* cb04 */
+ "rlc l", 0, /* cb05 */
+ "rlc (hl)", 0, /* cb06 */
+ "rlc a", 0, /* cb07 */
+
+ "rrc b", 0, /* cb08 */
+ "rrc c", 0, /* cb09 */
+ "rrc d", 0, /* cb0a */
+ "rrc e", 0, /* cb0b */
+ "rrc h", 0, /* cb0c */
+ "rrc l", 0, /* cb0d */
+ "rrc (hl)", 0, /* cb0e */
+ "rrc a", 0, /* cb0f */
+
+ "rl b", 0, /* cb10 */
+ "rl c", 0, /* cb11 */
+ "rl d", 0, /* cb12 */
+ "rl e", 0, /* cb13 */
+ "rl h", 0, /* cb14 */
+ "rl l", 0, /* cb15 */
+ "rl (hl)", 0, /* cb16 */
+ "rl a", 0, /* cb17 */
+
+ "rr b", 0, /* cb18 */
+ "rr c", 0, /* cb19 */
+ "rr d", 0, /* cb1a */
+ "rr e", 0, /* cb1b */
+ "rr h", 0, /* cb1c */
+ "rr l", 0, /* cb1d */
+ "rr (hl)", 0, /* cb1e */
+ "rr a", 0, /* cb1f */
+
+ "sla b", 0, /* cb20 */
+ "sla c", 0, /* cb21 */
+ "sla d", 0, /* cb22 */
+ "sla e", 0, /* cb23 */
+ "sla h", 0, /* cb24 */
+ "sla l", 0, /* cb25 */
+ "sla (hl)", 0, /* cb26 */
+ "sla a", 0, /* cb27 */
+
+ "sra b", 0, /* cb28 */
+ "sra c", 0, /* cb29 */
+ "sra d", 0, /* cb2a */
+ "sra e", 0, /* cb2b */
+ "sra h", 0, /* cb2c */
+ "sra l", 0, /* cb2d */
+ "sra (hl)", 0, /* cb2e */
+ "sra a", 0, /* cb2f */
+
+ undefined, 0, /* cb30 */
+ undefined, 0, /* cb31 */
+ undefined, 0, /* cb32 */
+ undefined, 0, /* cb33 */
+ undefined, 0, /* cb34 */
+ undefined, 0, /* cb35 */
+ undefined, 0, /* cb36 */
+ undefined, 0, /* cb37 */
+
+ "srl b", 0, /* cb38 */
+ "srl c", 0, /* cb39 */
+ "srl d", 0, /* cb3a */
+ "srl e", 0, /* cb3b */
+ "srl h", 0, /* cb3c */
+ "srl l", 0, /* cb3d */
+ "srl (hl)", 0, /* cb3e */
+ "srl a", 0, /* cb3f */
+
+ "bit 0,b", 0, /* cb40 */
+ "bit 0,c", 0, /* cb41 */
+ "bit 0,d", 0, /* cb42 */
+ "bit 0,e", 0, /* cb43 */
+ "bit 0,h", 0, /* cb44 */
+ "bit 0,l", 0, /* cb45 */
+ "bit 0,(hl)", 0, /* cb46 */
+ "bit 0,a", 0, /* cb47 */
+
+ "bit 1,b", 0, /* cb48 */
+ "bit 1,c", 0, /* cb49 */
+ "bit 1,d", 0, /* cb4a */
+ "bit 1,e", 0, /* cb4b */
+ "bit 1,h", 0, /* cb4c */
+ "bit 1,l", 0, /* cb4d */
+ "bit 1,(hl)", 0, /* cb4e */
+ "bit 1,a", 0, /* cb4f */
+
+ "bit 2,b", 0, /* cb50 */
+ "bit 2,c", 0, /* cb51 */
+ "bit 2,d", 0, /* cb52 */
+ "bit 2,e", 0, /* cb53 */
+ "bit 2,h", 0, /* cb54 */
+ "bit 2,l", 0, /* cb55 */
+ "bit 2,(hl)", 0, /* cb56 */
+ "bit 2,a", 0, /* cb57 */
+
+ "bit 3,b", 0, /* cb58 */
+ "bit 3,c", 0, /* cb59 */
+ "bit 3,d", 0, /* cb5a */
+ "bit 3,e", 0, /* cb5b */
+ "bit 3,h", 0, /* cb5c */
+ "bit 3,l", 0, /* cb5d */
+ "bit 3,(hl)", 0, /* cb5e */
+ "bit 3,a", 0, /* cb5f */
+
+ "bit 4,b", 0, /* cb60 */
+ "bit 4,c", 0, /* cb61 */
+ "bit 4,d", 0, /* cb62 */
+ "bit 4,e", 0, /* cb63 */
+ "bit 4,h", 0, /* cb64 */
+ "bit 4,l", 0, /* cb65 */
+ "bit 4,(hl)", 0, /* cb66 */
+ "bit 4,a", 0, /* cb67 */
+
+ "bit 5,b", 0, /* cb68 */
+ "bit 5,c", 0, /* cb69 */
+ "bit 5,d", 0, /* cb6a */
+ "bit 5,e", 0, /* cb6b */
+ "bit 5,h", 0, /* cb6c */
+ "bit 5,l", 0, /* cb6d */
+ "bit 5,(hl)", 0, /* cb6e */
+ "bit 5,a", 0, /* cb6f */
+
+ "bit 6,b", 0, /* cb70 */
+ "bit 6,c", 0, /* cb71 */
+ "bit 6,d", 0, /* cb72 */
+ "bit 6,e", 0, /* cb73 */
+ "bit 6,h", 0, /* cb74 */
+ "bit 6,l", 0, /* cb75 */
+ "bit 6,(hl)", 0, /* cb76 */
+ "bit 6,a", 0, /* cb77 */
+
+ "bit 7,b", 0, /* cb78 */
+ "bit 7,c", 0, /* cb79 */
+ "bit 7,d", 0, /* cb7a */
+ "bit 7,e", 0, /* cb7b */
+ "bit 7,h", 0, /* cb7c */
+ "bit 7,l", 0, /* cb7d */
+ "bit 7,(hl)", 0, /* cb7e */
+ "bit 7,a", 0, /* cb7f */
+
+ "res 0,b", 0, /* cb80 */
+ "res 0,c", 0, /* cb81 */
+ "res 0,d", 0, /* cb82 */
+ "res 0,e", 0, /* cb83 */
+ "res 0,h", 0, /* cb84 */
+ "res 0,l", 0, /* cb85 */
+ "res 0,(hl)", 0, /* cb86 */
+ "res 0,a", 0, /* cb87 */
+
+ "res 1,b", 0, /* cb88 */
+ "res 1,c", 0, /* cb89 */
+ "res 1,d", 0, /* cb8a */
+ "res 1,e", 0, /* cb8b */
+ "res 1,h", 0, /* cb8c */
+ "res 1,l", 0, /* cb8d */
+ "res 1,(hl)", 0, /* cb8e */
+ "res 1,a", 0, /* cb8f */
+
+ "res 2,b", 0, /* cb90 */
+ "res 2,c", 0, /* cb91 */
+ "res 2,d", 0, /* cb92 */
+ "res 2,e", 0, /* cb93 */
+ "res 2,h", 0, /* cb94 */
+ "res 2,l", 0, /* cb95 */
+ "res 2,(hl)", 0, /* cb96 */
+ "res 2,a", 0, /* cb97 */
+
+ "res 3,b", 0, /* cb98 */
+ "res 3,c", 0, /* cb99 */
+ "res 3,d", 0, /* cb9a */
+ "res 3,e", 0, /* cb9b */
+ "res 3,h", 0, /* cb9c */
+ "res 3,l", 0, /* cb9d */
+ "res 3,(hl)", 0, /* cb9e */
+ "res 3,a", 0, /* cb9f */
+
+ "res 4,b", 0, /* cba0 */
+ "res 4,c", 0, /* cba1 */
+ "res 4,d", 0, /* cba2 */
+ "res 4,e", 0, /* cba3 */
+ "res 4,h", 0, /* cba4 */
+ "res 4,l", 0, /* cba5 */
+ "res 4,(hl)", 0, /* cba6 */
+ "res 4,a", 0, /* cba7 */
+
+ "res 5,b", 0, /* cba8 */
+ "res 5,c", 0, /* cba9 */
+ "res 5,d", 0, /* cbaa */
+ "res 5,e", 0, /* cbab */
+ "res 5,h", 0, /* cbac */
+ "res 5,l", 0, /* cbad */
+ "res 5,(hl)", 0, /* cbae */
+ "res 5,a", 0, /* cbaf */
+
+ "res 6,b", 0, /* cbb0 */
+ "res 6,c", 0, /* cbb1 */
+ "res 6,d", 0, /* cbb2 */
+ "res 6,e", 0, /* cbb3 */
+ "res 6,h", 0, /* cbb4 */
+ "res 6,l", 0, /* cbb5 */
+ "res 6,(hl)", 0, /* cbb6 */
+ "res 6,a", 0, /* cbb7 */
+
+ "res 7,b", 0, /* cbb8 */
+ "res 7,c", 0, /* cbb9 */
+ "res 7,d", 0, /* cbba */
+ "res 7,e", 0, /* cbbb */
+ "res 7,h", 0, /* cbbc */
+ "res 7,l", 0, /* cbbd */
+ "res 7,(hl)", 0, /* cbbe */
+ "res 7,a", 0, /* cbbf */
+
+ "set 0,b", 0, /* cbc0 */
+ "set 0,c", 0, /* cbc1 */
+ "set 0,d", 0, /* cbc2 */
+ "set 0,e", 0, /* cbc3 */
+ "set 0,h", 0, /* cbc4 */
+ "set 0,l", 0, /* cbc5 */
+ "set 0,(hl)", 0, /* cbc6 */
+ "set 0,a", 0, /* cbc7 */
+
+ "set 1,b", 0, /* cbc8 */
+ "set 1,c", 0, /* cbc9 */
+ "set 1,d", 0, /* cbca */
+ "set 1,e", 0, /* cbcb */
+ "set 1,h", 0, /* cbcc */
+ "set 1,l", 0, /* cbcd */
+ "set 1,(hl)", 0, /* cbce */
+ "set 1,a", 0, /* cbcf */
+
+ "set 2,b", 0, /* cbd0 */
+ "set 2,c", 0, /* cbd1 */
+ "set 2,d", 0, /* cbd2 */
+ "set 2,e", 0, /* cbd3 */
+ "set 2,h", 0, /* cbd4 */
+ "set 2,l", 0, /* cbd5 */
+ "set 2,(hl)", 0, /* cbd6 */
+ "set 2,a", 0, /* cbd7 */
+
+ "set 3,b", 0, /* cbd8 */
+ "set 3,c", 0, /* cbd9 */
+ "set 3,d", 0, /* cbda */
+ "set 3,e", 0, /* cbdb */
+ "set 3,h", 0, /* cbdc */
+ "set 3,l", 0, /* cbdd */
+ "set 3,(hl)", 0, /* cbde */
+ "set 3,a", 0, /* cbdf */
+
+ "set 4,b", 0, /* cbe0 */
+ "set 4,c", 0, /* cbe1 */
+ "set 4,d", 0, /* cbe2 */
+ "set 4,e", 0, /* cbe3 */
+ "set 4,h", 0, /* cbe4 */
+ "set 4,l", 0, /* cbe5 */
+ "set 4,(hl)", 0, /* cbe6 */
+ "set 4,a", 0, /* cbe7 */
+
+ "set 5,b", 0, /* cbe8 */
+ "set 5,c", 0, /* cbe9 */
+ "set 5,d", 0, /* cbea */
+ "set 5,e", 0, /* cbeb */
+ "set 5,h", 0, /* cbec */
+ "set 5,l", 0, /* cbed */
+ "set 5,(hl)", 0, /* cbee */
+ "set 5,a", 0, /* cbef */
+
+ "set 6,b", 0, /* cbf0 */
+ "set 6,c", 0, /* cbf1 */
+ "set 6,d", 0, /* cbf2 */
+ "set 6,e", 0, /* cbf3 */
+ "set 6,h", 0, /* cbf4 */
+ "set 6,l", 0, /* cbf5 */
+ "set 6,(hl)", 0, /* cbf6 */
+ "set 6,a", 0, /* cbf7 */
+
+ "set 7,b", 0, /* cbf8 */
+ "set 7,c", 0, /* cbf9 */
+ "set 7,d", 0, /* cbfa */
+ "set 7,e", 0, /* cbfb */
+ "set 7,h", 0, /* cbfc */
+ "set 7,l", 0, /* cbfd */
+ "set 7,(hl)", 0, /* cbfe */
+ "set 7,a", 0, /* cbff */
+ /* dd */
+ undefined, 0, /* dd00 */
+ undefined, 0, /* dd01 */
+ undefined, 0, /* dd02 */
+ undefined, 0, /* dd03 */
+ undefined, 0, /* dd04 */
+ undefined, 0, /* dd05 */
+ undefined, 0, /* dd06 */
+ undefined, 0, /* dd07 */
+
+ undefined, 0, /* dd08 */
+ "add ix,bc", 0, /* dd09 */
+ undefined, 0, /* dd0a */
+ undefined, 0, /* dd0b */
+ undefined, 0, /* dd0c */
+ undefined, 0, /* dd0d */
+ undefined, 0, /* dd0e */
+ undefined, 0, /* dd0f */
+
+ undefined, 0, /* dd10 */
+ undefined, 0, /* dd11 */
+ undefined, 0, /* dd12 */
+ undefined, 0, /* dd13 */
+ undefined, 0, /* dd14 */
+ undefined, 0, /* dd15 */
+ undefined, 0, /* dd16 */
+ undefined, 0, /* dd17 */
+
+ undefined, 0, /* dd18 */
+ "add ix,de", 0, /* dd19 */
+ undefined, 0, /* dd1a */
+ undefined, 0, /* dd1b */
+ undefined, 0, /* dd1c */
+ undefined, 0, /* dd1d */
+ undefined, 0, /* dd1e */
+ undefined, 0, /* dd1f */
+
+ undefined, 0, /* dd20 */
+ "ld ix,%02x%02xh", 2, /* dd21 */
+ "ld (%02x%02xh),ix",2, /* dd22 */
+ "inc ix", 0, /* dd23 */
+ undefined, 0, /* dd24 */
+ undefined, 0, /* dd25 */
+ undefined, 0, /* dd26 */
+ undefined, 0, /* dd27 */
+
+ undefined, 0, /* dd28 */
+ "add ix,ix", 0, /* dd29 */
+ "ld ix,(%02x%02xh)",2, /* dd2a */
+ "dec ix", 0, /* dd2b */
+ undefined, 0, /* dd2c */
+ undefined, 0, /* dd2d */
+ undefined, 0, /* dd2e */
+ undefined, 0, /* dd2f */
+
+ undefined, 0, /* dd30 */
+ undefined, 0, /* dd31 */
+ undefined, 0, /* dd32 */
+ undefined, 0, /* dd33 */
+ "inc (ix+%02xh)", 1, /* dd34 */
+ "dec (ix+%02xh)", 1, /* dd35 */
+ "ld (ix+%02xh),%02xh",2, /* dd36 */
+ undefined, 0, /* dd37 */
+
+ undefined, 0, /* dd38 */
+ "add ix,sp", 0, /* dd39 */
+ undefined, 0, /* dd3a */
+ undefined, 0, /* dd3b */
+ undefined, 0, /* dd3c */
+ undefined, 0, /* dd3d */
+ undefined, 0, /* dd3e */
+ undefined, 0, /* dd3f */
+
+ undefined, 0, /* dd40 */
+ undefined, 0, /* dd41 */
+ undefined, 0, /* dd42 */
+ undefined, 0, /* dd43 */
+ undefined, 0, /* dd44 */
+ undefined, 0, /* dd45 */
+ "ld b,(ix+%02xh)", 1, /* dd46 */
+ undefined, 0, /* dd47 */
+
+ undefined, 0, /* dd48 */
+ undefined, 0, /* dd49 */
+ undefined, 0, /* dd4a */
+ undefined, 0, /* dd4b */
+ undefined, 0, /* dd4c */
+ undefined, 0, /* dd4d */
+ "ld c,(ix+%02xh)", 1, /* dd4e */
+ undefined, 0, /* dd4f */
+
+ undefined, 0, /* dd50 */
+ undefined, 0, /* dd51 */
+ undefined, 0, /* dd52 */
+ undefined, 0, /* dd53 */
+ undefined, 0, /* dd54 */
+ undefined, 0, /* dd55 */
+ "ld d,(ix+%02xh)", 1, /* dd56 */
+ undefined, 0, /* dd57 */
+
+ undefined, 0, /* dd58 */
+ undefined, 0, /* dd59 */
+ undefined, 0, /* dd5a */
+ undefined, 0, /* dd5b */
+ undefined, 0, /* dd5c */
+ undefined, 0, /* dd5d */
+ "ld e,(ix+%02xh)", 1, /* dd5e */
+ undefined, 0, /* dd5f */
+
+ undefined, 0, /* dd60 */
+ undefined, 0, /* dd61 */
+ undefined, 0, /* dd62 */
+ undefined, 0, /* dd63 */
+ undefined, 0, /* dd64 */
+ undefined, 0, /* dd65 */
+ "ld h,(ix+%02xh)", 1, /* dd66 */
+ undefined, 0, /* dd67 */
+
+ undefined, 0, /* dd68 */
+ undefined, 0, /* dd69 */
+ undefined, 0, /* dd6a */
+ undefined, 0, /* dd6b */
+ undefined, 0, /* dd6c */
+ undefined, 0, /* dd6d */
+ "ld l,(ix+%02xh)", 1, /* dd6e */
+ undefined, 0, /* dd6f */
+
+ "ld (ix+%02xh),b", 1, /* dd70 */
+ "ld (ix+%02xh),c", 1, /* dd71 */
+ "ld (ix+%02xh),d", 1, /* dd72 */
+ "ld (ix+%02xh),e", 1, /* dd73 */
+ "ld (ix+%02xh),h", 1, /* dd74 */
+ "ld (ix+%02xh),l", 1, /* dd75 */
+ undefined, 0, /* dd76 */
+ "ld (ix+%02xh),a", 1, /* dd77 */
+
+ undefined, 0, /* dd78 */
+ undefined, 0, /* dd79 */
+ undefined, 0, /* dd7a */
+ undefined, 0, /* dd7b */
+ undefined, 0, /* dd7c */
+ undefined, 0, /* dd7d */
+ "ld a,(ix+%02xh)", 1, /* dd7e */
+ undefined, 0, /* dd7f */
+
+ undefined, 0, /* dd80 */
+ undefined, 0, /* dd81 */
+ undefined, 0, /* dd82 */
+ undefined, 0, /* dd83 */
+ undefined, 0, /* dd84 */
+ undefined, 0, /* dd85 */
+ "add a,(ix+%02xh)", 1, /* dd86 */
+ undefined, 0, /* dd87 */
+
+ undefined, 0, /* dd88 */
+ undefined, 0, /* dd89 */
+ undefined, 0, /* dd8a */
+ undefined, 0, /* dd8b */
+ undefined, 0, /* dd8c */
+ undefined, 0, /* dd8d */
+ "adc a,(ix+%02xh)", 1, /* dd8e */
+ undefined, 0, /* dd8f */
+
+ undefined, 0, /* dd90 */
+ undefined, 0, /* dd91 */
+ undefined, 0, /* dd92 */
+ undefined, 0, /* dd93 */
+ undefined, 0, /* dd94 */
+ undefined, 0, /* dd95 */
+ "sub (ix+%02xh)", 1, /* dd96 */
+ undefined, 0, /* dd97 */
+
+ undefined, 0, /* dd98 */
+ undefined, 0, /* dd99 */
+ undefined, 0, /* dd9a */
+ undefined, 0, /* dd9b */
+ undefined, 0, /* dd9c */
+ undefined, 0, /* dd9d */
+ "sbc a,(ix+%02xh)", 1, /* dd9e */
+ undefined, 0, /* dd9f */
+
+ undefined, 0, /* dda0 */
+ undefined, 0, /* dda1 */
+ undefined, 0, /* dda2 */
+ undefined, 0, /* dda3 */
+ undefined, 0, /* dda4 */
+ undefined, 0, /* dda5 */
+ "and (ix+%02xh)", 1, /* dda6 */
+ undefined, 0, /* dda7 */
+
+ undefined, 0, /* dda8 */
+ undefined, 0, /* dda9 */
+ undefined, 0, /* ddaa */
+ undefined, 0, /* ddab */
+ undefined, 0, /* ddac */
+ undefined, 0, /* ddad */
+ "xor (ix+%02xh)", 1, /* ddae */
+ undefined, 0, /* ddaf */
+
+ undefined, 0, /* ddb0 */
+ undefined, 0, /* ddb1 */
+ undefined, 0, /* ddb2 */
+ undefined, 0, /* ddb3 */
+ undefined, 0, /* ddb4 */
+ undefined, 0, /* ddb5 */
+ "or (ix+%02xh)", 1, /* ddb6 */
+ undefined, 0, /* ddb7 */
+
+ undefined, 0, /* ddb8 */
+ undefined, 0, /* ddb9 */
+ undefined, 0, /* ddba */
+ undefined, 0, /* ddbb */
+ undefined, 0, /* ddbc */
+ undefined, 0, /* ddbd */
+ "cp (ix+%02xh)", 1, /* ddbe */
+ undefined, 0, /* ddbf */
+
+ undefined, 0, /* ddc0 */
+ undefined, 0, /* ddc1 */
+ undefined, 0, /* ddc2 */
+ undefined, 0, /* ddc3 */
+ undefined, 0, /* ddc4 */
+ undefined, 0, /* ddc5 */
+ undefined, 0, /* ddc6 */
+ undefined, 0, /* ddc7 */
+
+ undefined, 0, /* ddc8 */
+ undefined, 0, /* ddc9 */
+ undefined, 0, /* ddca */
+ "dd cb %02x,%02x", 2, /* ddcb */
+ undefined, 0, /* ddcc */
+ undefined, 0, /* ddcd */
+ undefined, 0, /* ddce */
+ undefined, 0, /* ddcf */
+
+ undefined, 0, /* ddd0 */
+ undefined, 0, /* ddd1 */
+ undefined, 0, /* ddd2 */
+ undefined, 0, /* ddd3 */
+ undefined, 0, /* ddd4 */
+ undefined, 0, /* ddd5 */
+ undefined, 0, /* ddd6 */
+ undefined, 0, /* ddd7 */
+
+ undefined, 0, /* ddd8 */
+ undefined, 0, /* ddd9 */
+ undefined, 0, /* ddda */
+ undefined, 0, /* dddb */
+ undefined, 0, /* dddc */
+ undefined, 0, /* dddd */
+ undefined, 0, /* ddde */
+ undefined, 0, /* dddf */
+
+ undefined, 0, /* dde0 */
+ "pop ix", 0, /* dde1 */
+ undefined, 0, /* dde2 */
+ "ex (sp),ix", 0, /* dde3 */
+ undefined, 0, /* dde4 */
+ "push ix", 0, /* dde5 */
+ undefined, 0, /* dde6 */
+ undefined, 0, /* dde7 */
+
+ undefined, 0, /* dde8 */
+ "jp (ix)", 0, /* dde9 */
+ undefined, 0, /* ddea */
+ undefined, 0, /* ddeb */
+ undefined, 0, /* ddec */
+ undefined, 0, /* dded */
+ undefined, 0, /* ddee */
+ undefined, 0, /* ddef */
+
+ undefined, 0, /* ddf0 */
+ undefined, 0, /* ddf1 */
+ undefined, 0, /* ddf2 */
+ undefined, 0, /* ddf3 */
+ undefined, 0, /* ddf4 */
+ undefined, 0, /* ddf5 */
+ undefined, 0, /* ddf6 */
+ undefined, 0, /* ddf7 */
+
+ undefined, 0, /* ddf8 */
+ "ld sp,ix", 0, /* ddf9 */
+ undefined, 0, /* ddfa */
+ undefined, 0, /* ddfb */
+ undefined, 0, /* ddfc */
+ undefined, 0, /* ddfd */
+ undefined, 0, /* ddfe */
+ undefined, 0, /* ddff */
+ /* ed */
+ undefined, 0, /* ed00 */
+ undefined, 0, /* ed01 */
+ undefined, 0, /* ed02 */
+ undefined, 0, /* ed03 */
+ undefined, 0, /* ed04 */
+ undefined, 0, /* ed05 */
+ undefined, 0, /* ed06 */
+ undefined, 0, /* ed07 */
+
+ undefined, 0, /* ed08 */
+ undefined, 0, /* ed09 */
+ undefined, 0, /* ed0a */
+ undefined, 0, /* ed0b */
+ undefined, 0, /* ed0c */
+ undefined, 0, /* ed0d */
+ undefined, 0, /* ed0e */
+ undefined, 0, /* ed0f */
+
+ undefined, 0, /* ed10 */
+ undefined, 0, /* ed11 */
+ undefined, 0, /* ed12 */
+ undefined, 0, /* ed13 */
+ undefined, 0, /* ed14 */
+ undefined, 0, /* ed15 */
+ undefined, 0, /* ed16 */
+ undefined, 0, /* ed17 */
+
+ undefined, 0, /* ed18 */
+ undefined, 0, /* ed19 */
+ undefined, 0, /* ed1a */
+ undefined, 0, /* ed1b */
+ undefined, 0, /* ed1c */
+ undefined, 0, /* ed1d */
+ undefined, 0, /* ed1e */
+ undefined, 0, /* ed1f */
+
+ undefined, 0, /* ed20 */
+ undefined, 0, /* ed21 */
+ undefined, 0, /* ed22 */
+ undefined, 0, /* ed23 */
+ undefined, 0, /* ed24 */
+ undefined, 0, /* ed25 */
+ undefined, 0, /* ed26 */
+ undefined, 0, /* ed27 */
+
+ undefined, 0, /* ed28 */
+ undefined, 0, /* ed29 */
+ undefined, 0, /* ed2a */
+ undefined, 0, /* ed2b */
+ undefined, 0, /* ed2c */
+ undefined, 0, /* ed2d */
+ undefined, 0, /* ed2e */
+ undefined, 0, /* ed2f */
+
+ undefined, 0, /* ed30 */
+ undefined, 0, /* ed31 */
+ undefined, 0, /* ed32 */
+ undefined, 0, /* ed33 */
+ undefined, 0, /* ed34 */
+ undefined, 0, /* ed35 */
+ undefined, 0, /* ed36 */
+ undefined, 0, /* ed37 */
+
+ undefined, 0, /* ed38 */
+ undefined, 0, /* ed39 */
+ undefined, 0, /* ed3a */
+ undefined, 0, /* ed3b */
+ undefined, 0, /* ed3c */
+ undefined, 0, /* ed3d */
+ undefined, 0, /* ed3e */
+ undefined, 0, /* ed3f */
+
+ "in b,(c)", 0, /* ed40 */
+ "out (c),b", 0, /* ed41 */
+ "sbc hl,bc", 0, /* ed42 */
+ "ld (%02x%02xh),bc",2, /* ed43 */
+ "neg", 0, /* ed44 */
+ "retn", 0, /* ed45 */
+ "im 0", 0, /* ed46 */
+ "ld i,a", 0, /* ed47 */
+
+ "in c,(c)", 0, /* ed48 */
+ "out (c),c", 0, /* ed49 */
+ "adc hl,bc", 0, /* ed4a */
+ "ld bc,(%02x%02xh)",2, /* ed4b */
+ undefined, 0, /* ed4c */
+ "reti", 0, /* ed4d */
+ undefined, 0, /* ed4e */
+ undefined, 0, /* ed4f */
+
+ "in d,(c)", 0, /* ed50 */
+ "out (c),d", 0, /* ed51 */
+ "sbc hl,de", 0, /* ed52 */
+ "ld (%02x%02xh),de",2, /* ed53 */
+ undefined, 0, /* ed54 */
+ undefined, 0, /* ed55 */
+ "im 1", 0, /* ed56 */
+ "ld a,i", 0, /* ed57 */
+
+ "in e,(c)", 0, /* ed58 */
+ "out (c),e", 0, /* ed59 */
+ "adc hl,de", 0, /* ed5a */
+ "ld de,(%02x%02xh)",2, /* ed5b */
+ undefined, 0, /* ed5c */
+ undefined, 0, /* ed5d */
+ "im 2", 0, /* ed5e */
+ undefined, 0, /* ed5f */
+
+ "in h,(c)", 0, /* ed60 */
+ "out (c),h", 0, /* ed61 */
+ "sbc hl,hl", 0, /* ed62 */
+ undefined, 0, /* ed63 */
+ undefined, 0, /* ed64 */
+ undefined, 0, /* ed65 */
+ undefined, 0, /* ed66 */
+ "rrd", 0, /* ed67 */
+
+ "in l,(c)", 0, /* ed68 */
+ "out (c),l", 0, /* ed69 */
+ "adc hl,hl", 0, /* ed6a */
+ undefined, 0, /* ed6b */
+ undefined, 0, /* ed6c */
+ undefined, 0, /* ed6d */
+ undefined, 0, /* ed6e */
+ "rld", 0, /* ed6f */
+
+ undefined, 0, /* ed70 */
+ undefined, 0, /* ed71 */
+ "sbc hl,sp", 0, /* ed72 */
+ "ld (%02x%02xh),sp",2, /* ed73 */
+ undefined, 0, /* ed74 */
+ undefined, 0, /* ed75 */
+ undefined, 0, /* ed76 */
+ undefined, 0, /* ed77 */
+
+ "in a,(c)", 0, /* ed78 */
+ "out (c),a", 0, /* ed79 */
+ "adc hl,sp", 0, /* ed7a */
+ "ld sp,(%02x%02xh)",2, /* ed7b */
+ undefined, 0, /* ed7c */
+ undefined, 0, /* ed7d */
+ undefined, 0, /* ed7e */
+ undefined, 0, /* ed7f */
+
+ undefined, 0, /* ed80 */
+ undefined, 0, /* ed81 */
+ undefined, 0, /* ed82 */
+ undefined, 0, /* ed83 */
+ undefined, 0, /* ed84 */
+ undefined, 0, /* ed85 */
+ undefined, 0, /* ed86 */
+ undefined, 0, /* ed87 */
+
+ undefined, 0, /* ed88 */
+ undefined, 0, /* ed89 */
+ undefined, 0, /* ed8a */
+ undefined, 0, /* ed8b */
+ undefined, 0, /* ed8c */
+ undefined, 0, /* ed8d */
+ undefined, 0, /* ed8e */
+ undefined, 0, /* ed8f */
+
+ undefined, 0, /* ed90 */
+ undefined, 0, /* ed91 */
+ undefined, 0, /* ed92 */
+ undefined, 0, /* ed93 */
+ undefined, 0, /* ed94 */
+ undefined, 0, /* ed95 */
+ undefined, 0, /* ed96 */
+ undefined, 0, /* ed97 */
+
+ undefined, 0, /* ed98 */
+ undefined, 0, /* ed99 */
+ undefined, 0, /* ed9a */
+ undefined, 0, /* ed9b */
+ undefined, 0, /* ed9c */
+ undefined, 0, /* ed9d */
+ undefined, 0, /* ed9e */
+ undefined, 0, /* ed9f */
+
+ "ldi", 0, /* eda0 */
+ "cpi", 0, /* eda1 */
+ "ini", 0, /* eda2 */
+ "outi", 0, /* eda3 */
+ undefined, 0, /* eda4 */
+ undefined, 0, /* eda5 */
+ undefined, 0, /* eda6 */
+ undefined, 0, /* eda7 */
+
+ "ldd", 0, /* eda8 */
+ "cpd", 0, /* eda9 */
+ "ind", 0, /* edaa */
+ "outd", 0, /* edab */
+ undefined, 0, /* edac */
+ undefined, 0, /* edad */
+ undefined, 0, /* edae */
+ undefined, 0, /* edaf */
+
+ "ldir", 0, /* edb0 */
+ "cpir", 0, /* edb1 */
+ "inir", 0, /* edb2 */
+ "otir", 0, /* edb3 */
+ undefined, 0, /* edb4 */
+ undefined, 0, /* edb5 */
+ undefined, 0, /* edb6 */
+ undefined, 0, /* edb7 */
+
+ "lddr", 0, /* edb8 */
+ "cpdr", 0, /* edb9 */
+ "indr", 0, /* edba */
+ "otdr", 0, /* edbb */
+ undefined, 0, /* edbc */
+ undefined, 0, /* edbd */
+ undefined, 0, /* edbe */
+ undefined, 0, /* edbf */
+
+ undefined, 0, /* edc0 */
+ undefined, 0, /* edc1 */
+ undefined, 0, /* edc2 */
+ undefined, 0, /* edc3 */
+ undefined, 0, /* edc4 */
+ undefined, 0, /* edc5 */
+ undefined, 0, /* edc6 */
+ undefined, 0, /* edc7 */
+
+ undefined, 0, /* edc8 */
+ undefined, 0, /* edc9 */
+ undefined, 0, /* edca */
+ undefined, 0, /* edcb */
+ undefined, 0, /* edcc */
+ undefined, 0, /* edcd */
+ undefined, 0, /* edce */
+ undefined, 0, /* edcf */
+
+ undefined, 0, /* edd0 */
+ undefined, 0, /* edd1 */
+ undefined, 0, /* edd2 */
+ undefined, 0, /* edd3 */
+ undefined, 0, /* edd4 */
+ undefined, 0, /* edd5 */
+ undefined, 0, /* edd6 */
+ undefined, 0, /* edd7 */
+
+ undefined, 0, /* edd8 */
+ undefined, 0, /* edd9 */
+ undefined, 0, /* edda */
+ undefined, 0, /* eddb */
+ undefined, 0, /* eddc */
+ undefined, 0, /* eddd */
+ undefined, 0, /* edde */
+ undefined, 0, /* eddf */
+
+ undefined, 0, /* ede0 */
+ undefined, 0, /* ede1 */
+ undefined, 0, /* ede2 */
+ undefined, 0, /* ede3 */
+ undefined, 0, /* ede4 */
+ undefined, 0, /* ede5 */
+ undefined, 0, /* ede6 */
+ undefined, 0, /* ede7 */
+
+ undefined, 0, /* ede8 */
+ undefined, 0, /* ede9 */
+ undefined, 0, /* edea */
+ undefined, 0, /* edeb */
+ undefined, 0, /* edec */
+ undefined, 0, /* eded */
+ undefined, 0, /* edee */
+ undefined, 0, /* edef */
+
+ undefined, 0, /* edf0 */
+ undefined, 0, /* edf1 */
+ undefined, 0, /* edf2 */
+ undefined, 0, /* edf3 */
+ undefined, 0, /* edf4 */
+ undefined, 0, /* edf5 */
+ undefined, 0, /* edf6 */
+ undefined, 0, /* edf7 */
+
+ undefined, 0, /* edf8 */
+ undefined, 0, /* edf9 */
+ undefined, 0, /* edfa */
+ undefined, 0, /* edfb */
+ undefined, 0, /* edfc */
+ undefined, 0, /* edfd */
+ undefined, 0, /* edfe */
+ undefined, 0, /* edff */
+ /* fd */
+ undefined, 0, /* fd00 */
+ undefined, 0, /* fd01 */
+ undefined, 0, /* fd02 */
+ undefined, 0, /* fd03 */
+ undefined, 0, /* fd04 */
+ undefined, 0, /* fd05 */
+ undefined, 0, /* fd06 */
+ undefined, 0, /* fd07 */
+
+ undefined, 0, /* fd08 */
+ "add iy,bc", 0, /* fd09 */
+ undefined, 0, /* fd0a */
+ undefined, 0, /* fd0b */
+ undefined, 0, /* fd0c */
+ undefined, 0, /* fd0d */
+ undefined, 0, /* fd0e */
+ undefined, 0, /* fd0f */
+
+ undefined, 0, /* fd10 */
+ undefined, 0, /* fd11 */
+ undefined, 0, /* fd12 */
+ undefined, 0, /* fd13 */
+ undefined, 0, /* fd14 */
+ undefined, 0, /* fd15 */
+ undefined, 0, /* fd16 */
+ undefined, 0, /* fd17 */
+
+ undefined, 0, /* fd18 */
+ "add iy,de", 0, /* fd19 */
+ undefined, 0, /* fd1a */
+ undefined, 0, /* fd1b */
+ undefined, 0, /* fd1c */
+ undefined, 0, /* fd1d */
+ undefined, 0, /* fd1e */
+ undefined, 0, /* fd1f */
+
+ undefined, 0, /* fd20 */
+ "ld iy,%02x%02xh", 2, /* fd21 */
+ "ld (%02x%02xh),iy",2, /* fd22 */
+ "inc iy", 0, /* fd23 */
+ undefined, 0, /* fd24 */
+ undefined, 0, /* fd25 */
+ undefined, 0, /* fd26 */
+ undefined, 0, /* fd27 */
+
+ undefined, 0, /* fd28 */
+ "add iy,iy", 0, /* fd29 */
+ "ld iy,(%02x%02xh)",2, /* fd2a */
+ "dec iy", 0, /* fd2b */
+ undefined, 0, /* fd2c */
+ undefined, 0, /* fd2d */
+ undefined, 0, /* fd2e */
+ undefined, 0, /* fd2f */
+
+ undefined, 0, /* fd30 */
+ undefined, 0, /* fd31 */
+ undefined, 0, /* fd32 */
+ undefined, 0, /* fd33 */
+ "inc (iy+%02xh)", 1, /* fd34 */
+ "dec (iy+%02xh)", 1, /* fd35 */
+ "ld (iy+%02xh),%02xh",2, /* fd36 */
+ undefined, 0, /* fd37 */
+
+ undefined, 0, /* fd38 */
+ "add iy,sp", 0, /* fd39 */
+ undefined, 0, /* fd3a */
+ undefined, 0, /* fd3b */
+ undefined, 0, /* fd3c */
+ undefined, 0, /* fd3d */
+ undefined, 0, /* fd3e */
+ undefined, 0, /* fd3f */
+
+ undefined, 0, /* fd40 */
+ undefined, 0, /* fd41 */
+ undefined, 0, /* fd42 */
+ undefined, 0, /* fd43 */
+ undefined, 0, /* fd44 */
+ undefined, 0, /* fd45 */
+ "ld b,(iy+%02xh)", 1, /* fd46 */
+ undefined, 0, /* fd47 */
+
+ undefined, 0, /* fd48 */
+ undefined, 0, /* fd49 */
+ undefined, 0, /* fd4a */
+ undefined, 0, /* fd4b */
+ undefined, 0, /* fd4c */
+ undefined, 0, /* fd4d */
+ "ld c,(iy+%02xh)", 1, /* fd4e */
+ undefined, 0, /* fd4f */
+
+ undefined, 0, /* fd50 */
+ undefined, 0, /* fd51 */
+ undefined, 0, /* fd52 */
+ undefined, 0, /* fd53 */
+ undefined, 0, /* fd54 */
+ undefined, 0, /* fd55 */
+ "ld d,(iy+%02xh)", 1, /* fd56 */
+ undefined, 0, /* fd57 */
+
+ undefined, 0, /* fd58 */
+ undefined, 0, /* fd59 */
+ undefined, 0, /* fd5a */
+ undefined, 0, /* fd5b */
+ undefined, 0, /* fd5c */
+ undefined, 0, /* fd5d */
+ "ld e,(iy+%02xh)", 1, /* fd5e */
+ undefined, 0, /* fd5f */
+
+ undefined, 0, /* fd60 */
+ undefined, 0, /* fd61 */
+ undefined, 0, /* fd62 */
+ undefined, 0, /* fd63 */
+ undefined, 0, /* fd64 */
+ undefined, 0, /* fd65 */
+ "ld h,(iy+%02xh)", 1, /* fd66 */
+ undefined, 0, /* fd67 */
+
+ undefined, 0, /* fd68 */
+ undefined, 0, /* fd69 */
+ undefined, 0, /* fd6a */
+ undefined, 0, /* fd6b */
+ undefined, 0, /* fd6c */
+ undefined, 0, /* fd6d */
+ "ld l,(iy+%02xh)", 1, /* fd6e */
+ undefined, 0, /* fd6f */
+
+ "ld (iy+%02xh),b", 1, /* fd70 */
+ "ld (iy+%02xh),c", 1, /* fd71 */
+ "ld (iy+%02xh),d", 1, /* fd72 */
+ "ld (iy+%02xh),e", 1, /* fd73 */
+ "ld (iy+%02xh),h", 1, /* fd74 */
+ "ld (iy+%02xh),l", 1, /* fd75 */
+ undefined, 0, /* fd76 */
+ "ld (iy+%02xh),a", 1, /* fd77 */
+
+ undefined, 0, /* fd78 */
+ undefined, 0, /* fd79 */
+ undefined, 0, /* fd7a */
+ undefined, 0, /* fd7b */
+ undefined, 0, /* fd7c */
+ undefined, 0, /* fd7d */
+ "ld a,(iy+%02xh)", 1, /* fd7e */
+ undefined, 0, /* fd7f */
+
+ undefined, 0, /* fd80 */
+ undefined, 0, /* fd81 */
+ undefined, 0, /* fd82 */
+ undefined, 0, /* fd83 */
+ undefined, 0, /* fd84 */
+ undefined, 0, /* fd85 */
+ "add a,(iy+%02xh)", 1, /* fd86 */
+ undefined, 0, /* fd87 */
+
+ undefined, 0, /* fd88 */
+ undefined, 0, /* fd89 */
+ undefined, 0, /* fd8a */
+ undefined, 0, /* fd8b */
+ undefined, 0, /* fd8c */
+ undefined, 0, /* fd8d */
+ "adc a,(iy+%02xh)", 1, /* fd8e */
+ undefined, 0, /* fd8f */
+
+ undefined, 0, /* fd90 */
+ undefined, 0, /* fd91 */
+ undefined, 0, /* fd92 */
+ undefined, 0, /* fd93 */
+ undefined, 0, /* fd94 */
+ undefined, 0, /* fd95 */
+ "sub (iy+%02xh)", 1, /* fd96 */
+ undefined, 0, /* fd97 */
+
+ undefined, 0, /* fd98 */
+ undefined, 0, /* fd99 */
+ undefined, 0, /* fd9a */
+ undefined, 0, /* fd9b */
+ undefined, 0, /* fd9c */
+ undefined, 0, /* fd9d */
+ "sbc a,(iy+%02xh)", 1, /* fd9e */
+ undefined, 0, /* fd9f */
+
+ undefined, 0, /* fda0 */
+ undefined, 0, /* fda1 */
+ undefined, 0, /* fda2 */
+ undefined, 0, /* fda3 */
+ undefined, 0, /* fda4 */
+ undefined, 0, /* fda5 */
+ "and (iy+%02xh)", 1, /* fda6 */
+ undefined, 0, /* fda7 */
+
+ undefined, 0, /* fda8 */
+ undefined, 0, /* fda9 */
+ undefined, 0, /* fdaa */
+ undefined, 0, /* fdab */
+ undefined, 0, /* fdac */
+ undefined, 0, /* fdad */
+ "xor (iy+%02xh)", 1, /* fdae */
+ undefined, 0, /* fdaf */
+
+ undefined, 0, /* fdb0 */
+ undefined, 0, /* fdb1 */
+ undefined, 0, /* fdb2 */
+ undefined, 0, /* fdb3 */
+ undefined, 0, /* fdb4 */
+ undefined, 0, /* fdb5 */
+ "or (iy+%02xh)", 1, /* fdb6 */
+ undefined, 0, /* fdb7 */
+
+ undefined, 0, /* fdb8 */
+ undefined, 0, /* fdb9 */
+ undefined, 0, /* fdba */
+ undefined, 0, /* fdbb */
+ undefined, 0, /* fdbc */
+ undefined, 0, /* fdbd */
+ "cp (iy+%02xh)", 1, /* fdbe */
+ undefined, 0, /* fdbf */
+
+ undefined, 0, /* fdc0 */
+ undefined, 0, /* fdc1 */
+ undefined, 0, /* fdc2 */
+ undefined, 0, /* fdc3 */
+ undefined, 0, /* fdc4 */
+ undefined, 0, /* fdc5 */
+ undefined, 0, /* fdc6 */
+ undefined, 0, /* fdc7 */
+
+ undefined, 0, /* fdc8 */
+ undefined, 0, /* fdc9 */
+ undefined, 0, /* fdca */
+ "fd cb %02x,%02x", 2, /* fdcb */
+ undefined, 0, /* fdcc */
+ undefined, 0, /* fdcd */
+ undefined, 0, /* fdce */
+ undefined, 0, /* fdcf */
+
+ undefined, 0, /* fdd0 */
+ undefined, 0, /* fdd1 */
+ undefined, 0, /* fdd2 */
+ undefined, 0, /* fdd3 */
+ undefined, 0, /* fdd4 */
+ undefined, 0, /* fdd5 */
+ undefined, 0, /* fdd6 */
+ undefined, 0, /* fdd7 */
+
+ undefined, 0, /* fdd8 */
+ undefined, 0, /* fdd9 */
+ undefined, 0, /* fdda */
+ undefined, 0, /* fddb */
+ undefined, 0, /* fddc */
+ undefined, 0, /* fddd */
+ undefined, 0, /* fdde */
+ undefined, 0, /* fddf */
+
+ undefined, 0, /* fde0 */
+ "pop iy", 0, /* fde1 */
+ undefined, 0, /* fde2 */
+ "ex (sp),iy", 0, /* fde3 */
+ undefined, 0, /* fde4 */
+ "push iy", 0, /* fde5 */
+ undefined, 0, /* fde6 */
+ undefined, 0, /* fde7 */
+
+ undefined, 0, /* fde8 */
+ "jp (iy)", 0, /* fde9 */
+ undefined, 0, /* fdea */
+ undefined, 0, /* fdeb */
+ undefined, 0, /* fdec */
+ undefined, 0, /* fded */
+ undefined, 0, /* fdee */
+ undefined, 0, /* fdef */
+
+ undefined, 0, /* fdf0 */
+ undefined, 0, /* fdf1 */
+ undefined, 0, /* fdf2 */
+ undefined, 0, /* fdf3 */
+ undefined, 0, /* fdf4 */
+ undefined, 0, /* fdf5 */
+ undefined, 0, /* fdf6 */
+ undefined, 0, /* fdf7 */
+
+ undefined, 0, /* fdf8 */
+ "ld sp,iy", 0, /* fdf9 */
+ undefined, 0, /* fdfa */
+ undefined, 0, /* fdfb */
+ undefined, 0, /* fdfc */
+ undefined, 0, /* fdfd */
+ undefined, 0, /* fdfe */
+ undefined, 0, /* fdff */
+};
+
+int curaddr = 0;
+
+main ()
+{
+ int i, j, arg1, arg2;
+ struct opcode *code;
+ int addr;
+
+ for (;;) {
+ addr = curaddr;
+ i = gethex();
+ if (!major[i].name) {
+ j = major[i].args;
+ i = gethex();
+ while (!minor[j][i].name) {
+ j = minor[j][i].args;
+ i = gethex ();
+ }
+ code = &minor[j][i];
+ } else
+ code = &major[i];
+ printf ("%04x\t", addr);
+ switch (code->args) {
+ case 2:
+ printf (code->name, gethex(), gethex());
+ break;
+ case 1:
+ printf (code->name, gethex());
+ break;
+ case 0:
+ printf (code->name);
+ break;
+ }
+ putchar ('\n');
+ }
+}
+
+int inline;
+int index;
+
+char linebuf[1024];
+
+int hexbuf[1024];
+
+gethex ()
+{
+ if (index == inline) {
+ again: ;
+ if (gets (linebuf) == 0)
+ exit (0);
+ if (strlen (linebuf) < 9)
+ goto again;
+ inline = fromhex (linebuf+1);
+ for (index = 0; index < inline; index++)
+ hexbuf[index] = fromhex (linebuf+9 + 2 * index);
+ index = 0;
+ }
+ ++curaddr;
+ return hexbuf[index++];
+}
+
+
+#define hexval(c) (('0' <= (c) && (c) <= '9') ? (c) - '0' :\
+ (('a' <= (c) && (c) <= 'f') ? (c) - 'a' + 10 :\
+ (('A' <= (c) && (c) <= 'F') ? (c) - 'A' + 10 :\
+ -1 )))
+
+fromhex (c)
+char *c;
+{
+ return hexval(c[0]) * 16 + hexval(c[1]);
+}
diff --git a/z80asm/zmac.1 b/z80asm/zmac.1
new file mode 100644
index 0000000..723a705
--- /dev/null
+++ b/z80asm/zmac.1
@@ -0,0 +1,67 @@
+.TH ZMAC l
+.SH NAME
+zmac \- macro cross-assembler for the Zilog Z80 microprocessor
+.SH SYNOPSIS
+zmac [-bdefgilLmnopst] infile
+.SH DESCRIPTION
+The
+.I Zmac
+assembler is modeled after the Intel 8080 macro cross-assembler
+for the Intel 8080 by Ken Borgendale. The major features are: Full
+macro capabilities, Conditional assembly, A very flexible set of
+listing options and pseudo-ops, Symbol table output, Error report,
+Elimination of sequential searching, Commenting of source, Facilities
+for system definiton files.
+.PP
+.I Zmac
+assembles the specified input file (default extension .asm) and
+produces a .hex output file. The options are:
+.TP 8
+.B b
+no binary
+.TP 8
+.B d
+debug
+.TP 8
+.B e
+error list only
+.TP 8
+.B f
+print if skipped lines
+.TP 8
+.B g
+do not list extra code
+.TP 8
+.B i
+do not list include files
+.TP 8
+.B l
+no list
+.TP 8
+.B L
+force listing of everything
+.TP 8
+.B m
+print macro expansions
+.TP 8
+.B n
+put line numbers off
+.TP 8
+.B o
+list to standard output
+.TP 8
+.B p
+put out four \\n's for eject
+.TP 8
+.B s
+don't produce a symbol list
+.TP 8
+.B t
+don't know what this option does
+.SH SEE ALSO
+zdis(l)
+.SH FILES
+Source is in /usr/local/src/zmac directory.
+.SH BUGS
+The man page is incomplete. If anyone discovers more information about
+using zmac, please consider helping to update the man page.
diff --git a/z80asm/zmac.y b/z80asm/zmac.y
new file mode 100644
index 0000000..552b6eb
--- /dev/null
+++ b/z80asm/zmac.y
@@ -0,0 +1,2957 @@
+%{
+/*
+ * zmac -- macro cross-assembler for the Zilog Z80 microprocessor
+ *
+ * Bruce Norskog 4/78
+ *
+ * Last modification 1-18-87 by cdk
+ * This assembler is modeled after the Intel 8080 macro cross-assembler
+ * for the Intel 8080 by Ken Borgendale. The major features are:
+ * 1. Full macro capabilities
+ * 2. Conditional assembly
+ * 3. A very flexible set of listing options and pseudo-ops
+ * 4. Symbol table output
+ * 5. Error report
+ * 6. Elimination of sequential searching
+ * 7. Commenting of source
+ * 8. Facilities for system definiton files
+ *
+ * Revision History:
+ *
+ * jrp 3-8-82 Converted to run on Vax, updated syntax to conform better
+ * to the Zilog standard.
+ *
+ * jrp 3-15-82 Added underscore as a character type in the lex table
+ * 'numpart' (0x5F).
+ *
+ * Changed maximum number of characters in a label to 15
+ * from 7. Note that 'putsymtab' uses this value inside
+ * of a quoted string, so we use 15.
+ *
+ * jrp 2-15-83 Fixed 'getlocal' to return better local labels. It used
+ * to crash after 6 invocations.
+ *
+ * jrp 6-7-83 Fixed bug in the ADD IX,... instruction.
+ *
+ * jrp 5-11-84 Added code to print unused labels out with the symbol table
+ * Also sped up the macro processor by using stdio.
+ *
+ * jrp 5-22-84 Added include files ala ormac
+ *
+ * jrp 8-27-84 Added PHASE/DEPHASE commands
+ *
+ * cdk 9-20-86 Converted to run on a Pyramid. This meant changing yylval
+ * to be a %union, and then putting in the appropriate
+ * typecasts where ints are pointers are used interchangeably.
+ * The current version still probably won't run on machines where
+ * sizeof(int) != sizeof(char *).
+ * Also changed emit() to use varargs, and got rid of the
+ * old style = in front of yacc action code.
+ * -Colin Kelley vu-vlsi!colin
+ *
+ * cdk 10-2-86 Added some more typecasts to keep lint a little happier.
+ * Removed several unused variables. Changed most vars
+ * declared as char to int, since many of them were being
+ * compared with -1! I still don't know what's going on with
+ * est[][] being malloc'd and free'd everywhere...it looks pretty
+ * fishy...
+ *
+ * cdk 1-18-87 Added MIO code to emulate 'mfile' using malloc()'d memory.
+ * This was needed to get the code to work when compiled under
+ * MSC 4.0 on a PC, and it's probably faster anyway.
+ *
+ * cdk 2-5-87 Added 'cmp' as a synonym for 'cp', 'jmp' as a synonym for
+ * 'jp', and added tolerance of accumulator specification for arithmetic
+ * and logical instructions. (For example, 'or a,12' is now accepted,
+ * same as 'or 12'.)
+ */
+
+
+#define MIO /* use emulation routines from mio.c */
+
+#include <stdio.h>
+#ifdef MSDOS
+#include <fcntl.h>
+#else
+#include <sys/file.h> /* for open() calls */
+#endif
+
+#ifdef vax11c
+#define unlink(filename) delete(filename)
+#endif
+
+#ifdef MIO
+FILE *mfopen();
+#else
+#define mfopen(filename,mode) fopen(filename,mode)
+#define mfclose(filename,mode) fclose(filename,mode)
+#define mfputc(c,f) putc(c,f)
+#define mfgetc(f) getc(f)
+#define mfseek(f,loc,origin) fseek(f,loc,origin)
+#define mfread(ptr,size,nitems,f) fread(ptr,size,nitems,f)
+#define mfwrite(ptr,size,nitems,f) fread(ptr,size,nitems,f)
+#endif /* MIO */
+
+/*
+ * DEBUG turns on pass reporting.
+ * Macro debug and Token debug enables.
+#define DEBUG
+#define M_DEBUG
+#define T_DEBUG
+ */
+
+#define ITEMTABLESIZE 2000
+#define TEMPBUFSIZE 200
+#define LINEBUFFERSIZE 200
+#define EMITBUFFERSIZE 200
+#define MAXSYMBOLSIZE 15
+#define IFSTACKSIZE 20
+#define MAXIFS 150
+#define TITLELEN 50
+#define BINPERLINE 16
+#define PARMMAX 25
+#define MAXEXP 25
+#define SYMMAJIC 07203
+#define NEST_IN 32
+
+
+#define loop for(;;)
+
+yyerror(err)
+char *err;
+{} /* we will do our own error printing */
+
+struct item {
+ char *i_string;
+ int i_value;
+ int i_token;
+ int i_uses;
+};
+
+FILE *fout,
+ *fbuf,
+ *fin[NEST_IN],
+ *now_file ;
+
+char *malloc() ;
+
+int pass2; /*set when pass one completed*/
+int dollarsign ; /* location counter */
+int olddollar ; /* kept to put out binary */
+
+/* program counter save for PHASE/DEPHASE */
+int phdollar, phbegin, phaseflag ;
+
+char *src_name[NEST_IN] ;
+int linein[NEST_IN] ;
+int now_in ;
+
+
+
+#define bflag 0 /* balance error */
+#define eflag 1 /* expression error */
+#define fflag 2 /* format error */
+#define iflag 3 /* bad digits */
+#define mflag 4 /* multiply defined */
+#define pflag 5 /* phase error */
+#define uflag 6 /* undeclared used */
+#define vflag 7 /* value out of range */
+#define oflag 8 /* phase/dephase error */
+
+#define FLAGS 9 /* number of flags */
+
+char err[FLAGS];
+int keeperr[FLAGS];
+char errlet[]="BEFIMPUVO";
+char *errname[]={
+ "Balance",
+ "Expression",
+ "Format",
+ "Digit",
+ "Mult. def.",
+ "Phase",
+ "Undeclared",
+ "Value",
+ "Phase/Dephase",
+};
+
+
+char linebuf[LINEBUFFERSIZE];
+char *lineptr;
+char *linemax = &linebuf[LINEBUFFERSIZE];
+
+char outbin[BINPERLINE];
+char *outbinp = outbin;
+char *outbinm = &outbin[BINPERLINE];
+
+char emitbuf[EMITBUFFERSIZE];
+char *emitptr;
+
+char ifstack[IFSTACKSIZE];
+char *ifptr;
+char *ifstmax = &ifstack[IFSTACKSIZE-1];
+
+
+char expif[MAXIFS];
+char *expifp;
+char *expifmax = &expif[MAXIFS];
+
+char hexadec[] = "0123456789ABCDEF" ;
+char *expstack[MAXEXP];
+int expptr;
+
+
+int nitems;
+int linecnt;
+int nbytes;
+int invented;
+
+
+char tempbuf[TEMPBUFSIZE];
+char *tempmax = &tempbuf[TEMPBUFSIZE-1];
+
+char inmlex;
+char arg_flag;
+char quoteflag;
+int parm_number;
+int exp_number;
+char symlong[] = "Symbol too long";
+
+int disp;
+#define FLOC PARMMAX
+#define TEMPNUM PARMMAX+1
+char **est;
+char **est2;
+
+char *floc;
+int mfptr;
+FILE *mfile;
+
+char *writesyms;
+
+
+char *title;
+char titlespace[TITLELEN];
+char *timp,*ctime();
+char *sourcef;
+char src[15];
+char bin[15];
+char mtmp[15];
+char listf[15];
+
+char bopt = 1,
+ edef = 1,
+ eopt = 1,
+ fdef = 0,
+ fopt = 0,
+ gdef = 1,
+ gopt = 1,
+ iopt = 0 , /* list include files */
+ lstoff = 0,
+ lston = 0, /* flag to force listing on */
+ lopt = 0,
+ mdef = 0,
+ mopt = 0,
+ nopt = 1 , /* line numbers on as default */
+ oopt = 0,
+ popt = 1, /* form feed as default page eject */
+ sopt = 0, /* turn on symbol table listing */
+ topt = 1;
+ saveopt;
+
+char xeq_flag = 0;
+int xeq;
+
+long now;
+int line;
+int page = 1;
+
+struct stab {
+ char t_name[MAXSYMBOLSIZE+1];
+ int t_value;
+ int t_token;
+};
+
+/*
+ * push back character
+ */
+int peekc;
+
+
+/*
+ * add a character to the output line buffer
+ */
+addtoline(ac)
+int ac;
+{
+ /* check for EOF from stdio */
+ if (ac == -1)
+ ac = 0 ;
+ if (inmlex)
+ return(ac);
+ if (lineptr >= linemax)
+ error("line buffer overflow");
+ *lineptr++ = ac;
+ return(ac);
+}
+
+#include <varargs.h>
+
+/*
+ * put values in buffer for outputing
+ */
+
+/*VARARGS*/
+/*ARGSUSED*/
+emit(va_alist)
+va_dcl
+{
+ register int bytes;
+ va_list ap;
+ va_start(ap);
+
+ bytes = va_arg(ap,int);
+
+ while (--bytes >= 0)
+ if (emitptr >= &emitbuf[EMITBUFFERSIZE])
+ error("emit buffer overflow");
+ else {
+ *emitptr++ = va_arg(ap,int);
+ }
+ va_end(ap);
+}
+
+
+emit1(opcode,regvalh,data16,type)
+int opcode,regvalh,data16,type;
+{
+ if (regvalh & 0x8000) {
+ if (type & 1 == 0 && (disp > 127 || disp < -128))
+ err[vflag]++;
+ switch(type) {
+ case 0:
+ if (opcode & 0x8000)
+ emit(4, regvalh >> 8, opcode >> 8, disp, opcode);
+ else
+ emit(3, regvalh >> 8, opcode, disp);
+ break;
+ case 1:
+ emit(2, regvalh >> 8, opcode);
+ break;
+ case 2:
+ if (data16 > 255 || data16 < -128)
+ err[vflag]++;
+ emit(4, regvalh >> 8, opcode, disp, data16);
+ break;
+ case 5:
+ emit(4, regvalh >> 8, opcode, data16, data16 >> 8);
+ }
+ } else
+ switch(type) {
+ case 0:
+ if (opcode & 0100000)
+ emit(2, opcode >> 8, opcode);
+ else
+ emit(1, opcode);
+ break;
+ case 1:
+ if (opcode & 0100000)
+ emit(2, opcode >> 8, opcode);
+ else
+ emit(1, opcode);
+ break;
+ case 2:
+ if (data16 > 255 || data16 < -128)
+ err[vflag]++;
+ emit(2, opcode, data16);
+ break;
+ case 3:
+ if (data16 >255 || data16 < -128)
+ err[vflag]++;
+ emit(2, opcode, data16);
+ break;
+ case 5:
+ if (opcode & 0100000)
+ emit(4, opcode >> 8, opcode, data16, data16 >> 8);
+ else
+ emit(3, opcode, data16, data16 >> 8);
+ }
+}
+
+
+
+
+emitdad(rp1,rp2)
+int rp1,rp2;
+{
+ if (rp1 & 0x8000)
+ emit(2,rp1 >> 8, rp2 + 9);
+ else
+ emit(1,rp2 + 9);
+}
+
+
+emitjr(opcode,expr)
+int opcode,expr;
+{
+ disp = expr - dollarsign - 2;
+ if (disp > 127 || disp < -128)
+ err[vflag]++;
+ emit(2, opcode, disp);
+}
+
+
+
+
+/*
+ * put out a byte of binary
+ */
+putbin(v)
+{
+ if(!pass2 || !bopt) return;
+ *outbinp++ = v;
+ if (outbinp >= outbinm) flushbin();
+}
+
+
+
+/*
+ * output one line of binary in INTEL standard form
+ */
+flushbin()
+{
+ register char *p;
+ register check;
+
+ if (!pass2 || !bopt)
+ return;
+ nbytes += outbinp-outbin;
+ if (check = outbinp-outbin) {
+ putc(':', fbuf);
+ puthex(check, fbuf);
+ puthex(olddollar>>8, fbuf);
+ puthex(olddollar, fbuf);
+ puthex(0, fbuf);
+ check += (olddollar >> 8) + olddollar;
+ olddollar += (outbinp-outbin);
+ for (p=outbin; p<outbinp; p++) {
+ puthex(*p, fbuf);
+ check += *p;
+ }
+ puthex(256-check, fbuf);
+ putc('\n', fbuf);
+ outbinp = outbin;
+ }
+}
+
+
+
+/*
+ * put out one byte of hex
+ */
+puthex(byte, buf)
+char byte;
+FILE *buf;
+{
+ putc(hexadec[(byte >> 4) & 017], buf);
+ putc(hexadec[byte & 017], buf);
+}
+
+/*
+ * put out a line of output -- also put out binary
+ */
+list(optarg)
+int optarg;
+{
+ register char * p;
+ register int i;
+ int lst;
+
+ if (!expptr)
+ linecnt++;
+ addtoline('\0');
+ if (pass2) {
+ lst = iflist();
+ if (lst) {
+ lineout();
+ if (nopt)
+ fprintf(fout, "%4d:\t", linein[now_in]);
+ puthex(optarg >> 8, fout);
+ puthex(optarg, fout);
+ fputs(" ", fout);
+ for (p = emitbuf; (p < emitptr) && (p - emitbuf < 4); p++) {
+ puthex(*p, fout);
+ }
+ for (i = 4 - (p-emitbuf); i > 0; i--)
+ fputs(" ", fout);
+ putc('\t', fout);
+ fputs(linebuf, fout);
+ }
+
+ if (bopt) {
+ for (p = emitbuf; p < emitptr; p++)
+ putbin(*p);
+ }
+
+
+ p = emitbuf+4;
+ while (lst && gopt && p < emitptr) {
+ lineout();
+ if (nopt) putc('\t', fout);
+ fputs(" ", fout);
+ for (i = 0; (i < 4) && (p < emitptr);i++) {
+ puthex(*p, fout);
+ p++;
+ }
+ putc('\n', fout);
+ }
+
+
+ lsterr2(lst);
+ } else
+ lsterr1();
+ dollarsign += emitptr - emitbuf;
+ emitptr = emitbuf;
+ lineptr = linebuf;
+}
+
+
+
+/*
+ * keep track of line numbers and put out headers as necessary
+ */
+lineout()
+{
+ if (line == 60) {
+ if (popt)
+ putc('\014', fout); /* send the form feed */
+ else
+ fputs("\n\n\n\n\n", fout);
+ line = 0;
+ }
+ if (line == 0) {
+ fprintf(fout, "\n\n%s %s\t%s\t Page %d\n\n\n",
+ &timp[4], &timp[20], title, page++);
+ line = 4;
+ }
+ line++;
+}
+
+
+/*
+ * cause a page eject
+ */
+eject()
+{
+ if (pass2 && iflist()) {
+ if (popt) {
+ putc('\014', fout); /* send the form feed */
+ } else {
+ while (line < 65) {
+ line++;
+ putc('\n', fout);
+ }
+ }
+ }
+ line = 0;
+}
+
+
+/*
+ * space n lines on the list file
+ */
+space(n)
+{
+ int i ;
+ if (pass2 && iflist())
+ for (i = 0; i<n; i++) {
+ lineout();
+ putc('\n', fout);
+ }
+}
+
+
+/*
+ * Error handling - pass 1
+ */
+lsterr1() {
+ register int i;
+ if (topt)
+ for (i = 0; i <= 4; i++)
+ if (err[i]) {
+ errorprt(i);
+ err[i] = 0;
+ }
+}
+
+
+/*
+ * Error handling - pass 2.
+ */
+lsterr2(lst)
+int lst;
+{
+ register int i;
+ for (i=0; i<FLAGS; i++)
+ if (err[i]) {
+ if (lst) {
+ lineout();
+ putc(errlet[i], fout);
+ putc('\n', fout);
+ }
+ err[i] = 0;
+ keeperr[i]++;
+ if (i > 4 && topt)
+ errorprt(i);
+ }
+
+ fflush(fout); /*to avoid putc(har) mix bug*/
+}
+
+/*
+ * print diagnostic to error terminal
+ */
+errorprt(errnum)
+int errnum;
+{
+ fprintf(stderr,"%d: %s error\n%s\n",
+ linecnt, errname[errnum], linebuf) ;
+ fflush(stderr) ;
+ return ;
+}
+
+
+/*
+ * list without address -- for comments and if skipped lines
+ */
+list1()
+{
+ int lst;
+
+ addtoline('\0');
+ lineptr = linebuf;
+ if (!expptr) linecnt++;
+ if (pass2)
+ if (lst = iflist()) {
+ lineout();
+ if (nopt)
+ fprintf(fout, "%4d:\t", linein[now_in]);
+ fprintf(fout, "\t\t%s", linebuf);
+ lsterr2(lst);
+ }
+ else
+ lsterr1();
+}
+
+
+/*
+ * see if listing is desired
+ */
+iflist()
+{
+ register i, j;
+
+ if (lston)
+ return(1) ;
+ if (lopt)
+ return(0);
+ if (*ifptr && !fopt)
+ return(0);
+ if (!lstoff && !expptr)
+ return(1);
+ j = 0;
+ for (i=0; i<FLAGS; i++)
+ if (err[i])
+ j++;
+ if (expptr)
+ return(mopt || j);
+ if (eopt && j)
+ return(1);
+ return(0);
+}
+
+
+%}
+
+%union {
+ struct item *itemptr;
+ int ival;
+ char *cval;
+ }
+
+%token <cval> STRING
+%token <itemptr> NOOPERAND
+%token <itemptr> ARITHC
+%token ADD
+%token <itemptr> LOGICAL
+%token <itemptr> BIT
+%token CALL
+%token <itemptr> INCDEC
+%token <itemptr> DJNZ
+%token EX
+%token <itemptr> IM
+%token PHASE
+%token DEPHASE
+%token <itemptr> IN
+%token JP
+%token <itemptr> JR
+%token LD
+%token <itemptr> OUT
+%token <itemptr> PUSHPOP
+%token <itemptr> RET
+%token <itemptr> SHIFT
+%token <itemptr> RST
+%token <itemptr> REGNAME
+%token <itemptr> ACC
+%token <itemptr> C
+%token <itemptr> RP
+%token <itemptr> HL
+%token <itemptr> INDEX
+%token <itemptr> AF
+%token <itemptr> SP
+%token <itemptr> MISCREG
+%token F
+%token <itemptr> COND
+%token <itemptr> SPCOND
+%token <ival> NUMBER
+%token <itemptr> UNDECLARED
+%token END
+%token ORG
+%token DEFB
+%token DEFS
+%token DEFW
+%token EQU
+%token DEFL
+%token <itemptr> LABEL
+%token <itemptr> EQUATED
+%token <itemptr> WASEQUATED
+%token <itemptr> DEFLED
+%token <itemptr> MULTDEF
+%token <ival> MOD
+%token <ival> SHL
+%token <ival> SHR
+%token <ival> NOT
+%token IF
+%token ENDIF
+%token <itemptr> ARGPSEUDO
+%token <itemptr> LIST
+%token <itemptr> MINMAX
+%token MACRO
+%token <itemptr> MNAME
+%token <itemptr> OLDMNAME
+%token ARG
+%token ENDM
+%token MPARM
+%token <ival> ONECHAR
+%token <ival> TWOCHAR
+
+%type <itemptr> label.part symbol
+%type <ival> reg evenreg realreg mem pushable bcdesp bcdehlsp mar condition
+%type <ival> spcondition parenexpr expression lxexpression
+
+%left '|' '^'
+%left '&'
+%nonassoc NOT
+%left '+' '-'
+%left '*' '/' MOD SHL SHR
+%left UNARY
+%%
+
+%{
+char *cp;
+int i;
+%}
+
+program:
+ statements
+|
+ error { error("file bad"); }
+;
+
+
+statements:
+ statement
+|
+ statements statement
+|
+ statements error {
+ fprintf(stderr,"statement error\n");
+ err[fflag]++;
+ quoteflag = 0;
+ while(yychar != '\n' && yychar != '\0') yychar = yylex();
+ list(dollarsign);
+ yyclearin;yyerrok;
+ }
+;
+
+
+statement:
+ label.part '\n' {
+ if ($1) list(dollarsign);
+ else list1();
+ }
+|
+ label.part operation '\n' {
+ list(dollarsign);
+ }
+|
+ symbol EQU expression '\n' {
+ switch($1->i_token) {
+ case UNDECLARED: case WASEQUATED:
+ $1->i_token = EQUATED;
+ $1->i_value = $3;
+ break;
+ default:
+ err[mflag]++;
+ $1->i_token = MULTDEF;
+ }
+ list($3);
+ }
+|
+ symbol DEFL expression '\n' {
+ switch($1->i_token) {
+ case UNDECLARED: case DEFLED:
+ $1->i_token = DEFLED;
+ $1->i_value = $3;
+ break;
+ default:
+ err[mflag]++;
+ $1->i_token = MULTDEF;
+ }
+ list($3);
+ }
+|
+ symbol MINMAX expression ',' expression '\n' {
+ switch ($1->i_token) {
+ case UNDECLARED: case DEFLED:
+ $1->i_token = DEFLED;
+ if ($2->i_value) /* max */
+ list($1->i_value = ($3 > $5? $3:$5));
+ else list($1->i_value = ($3 < $5? $3:$5));
+ break;
+ default:
+ err[mflag]++;
+ $1->i_token = MULTDEF;
+ list($1->i_value);
+ }
+ }
+|
+ IF expression '\n' {
+ if (ifptr >= ifstmax)
+ error("Too many ifs");
+ else {
+ if (pass2) {
+ *++ifptr = *expifp++;
+ if (*ifptr != !(yypv[2].ival)) err[pflag]++;
+ } else {
+ if (expifp >= expifmax)
+ error("Too many ifs!");
+ *expifp++ = !(yypv[2].ival);
+ *++ifptr = !(yypv[2].ival);
+ }
+ }
+ saveopt = fopt;
+ fopt = 1;
+ list(yypv[2].ival);
+ fopt = saveopt;
+ }
+|
+ ENDIF '\n' {
+ if (ifptr == ifstack) err[bflag]++;
+ else --ifptr;
+ list1();
+ }
+|
+ label.part END '\n' {
+ list(dollarsign);
+ peekc = 0;
+ }
+|
+ label.part END expression '\n' {
+ xeq_flag++;
+ xeq = $3;
+ list($3);
+ peekc = 0;
+ }
+|
+ label.part DEFS expression '\n' {
+ if ($3 < 0) err[vflag]++;
+ list(dollarsign);
+ if ($3) {
+ flushbin();
+ dollarsign += $3;
+ olddollar = dollarsign;
+ }
+ }
+|
+ ARGPSEUDO arg_on ARG arg_off '\n' {
+ list1();
+ switch ($1->i_value) {
+
+ case 0: /* title */
+ lineptr = linebuf;
+ cp = tempbuf;
+ title = titlespace;
+ while ((*title++ = *cp++) && (title < &titlespace[TITLELEN]));
+ *title = 0;
+ title = titlespace;
+ break;
+
+ case 1: /* rsym */
+ if (pass2) break;
+ insymtab(tempbuf);
+ break;
+
+ case 2: /* wsym */
+ writesyms = malloc(strlen(tempbuf)+1);
+ strcpy(writesyms, tempbuf);
+ break;
+ case 3: /* include file */
+ next_source(tempbuf) ;
+ break ;
+ }
+ }
+|
+ ARGPSEUDO arg_on '\n' arg_off {
+ fprintf(stderr,"ARGPSEUDO error\n");
+ err[fflag]++;
+ list(dollarsign);
+ }
+|
+ LIST '\n' {
+ if ($1 != (struct item *) -1) $<ival>2 = 1;
+ goto dolopt; }
+|
+ LIST expression '\n' {
+ dolopt:
+ linecnt++;
+ if (pass2) {
+ lineptr = linebuf;
+ switch ($1->i_value) {
+ case 0: /* list */
+ if ($2 < 0) lstoff = 1;
+ if ($2 > 0) lstoff = 0;
+ break;
+
+ case 1: /* eject */
+ if ($2) eject();
+ break;
+
+ case 2: /* space */
+ if ((line + $2) > 60) eject();
+ else space($2);
+ break;
+
+ case 3: /* elist */
+ eopt = edef;
+ if ($2 < 0) eopt = 0;
+ if ($2 > 0) eopt = 1;
+ break;
+
+ case 4: /* fopt */
+ fopt = fdef;
+ if ($2 < 0) fopt = 0;
+ if ($2 > 0) fopt = 1;
+ break;
+
+ case 5: /* gopt */
+ gopt = gdef;
+ if ($2 < 0) gopt = 1;
+ if ($2 > 0) gopt = 0;
+ break;
+
+ case 6: /* mopt */
+ mopt = mdef;
+ if ($2 < 0) mopt = 0;
+ if ($2 > 0) mopt = 1;
+ }
+ }
+ }
+|
+ UNDECLARED MACRO parm.list '\n' {
+ $1->i_token = MNAME;
+ $1->i_value = mfptr;
+ mfseek(mfile, (long)mfptr, 0);
+ list1();
+ mlex() ;
+ parm_number = 0;
+ }
+|
+ OLDMNAME MACRO {
+ $1->i_token = MNAME;
+ while (yychar != ENDM && yychar) {
+ while (yychar != '\n' && yychar)
+ yychar = yylex();
+ list1();
+ yychar = yylex();
+ }
+ while (yychar != '\n' && yychar) yychar = yylex();
+ list1();
+ yychar = yylex();
+ }
+|
+ label.part MNAME al arg.list '\n' {
+ expand:
+ $2->i_uses++ ;
+ arg_flag = 0;
+ parm_number = 0;
+ list(dollarsign);
+ expptr++;
+ est = est2;
+ est[FLOC] = floc;
+ est[TEMPNUM] = (char *)exp_number++;
+ floc = (char *)($2->i_value);
+ mfseek(mfile, (long)floc, 0);
+ }
+;
+
+
+label.part:
+ /*empty*/
+ { $$ = NULL; }
+|
+ symbol ':' {
+ switch($1->i_token) {
+ case UNDECLARED:
+ if (pass2)
+ err[pflag]++;
+ else {
+ $1->i_token = LABEL;
+ $1->i_value = dollarsign;
+ }
+ break;
+ case LABEL:
+ if (!pass2) {
+ $1->i_token = MULTDEF;
+ err[mflag]++;
+ } else if ($1->i_value != dollarsign)
+ err[pflag]++;
+ break;
+ default:
+ err[mflag]++;
+ $1->i_token = MULTDEF;
+ }
+ }
+;
+
+
+operation:
+ NOOPERAND
+ { emit1($1->i_value, 0, 0, 1); }
+|
+ JP expression
+ { emit(3, 0303, $2, $2 >> 8); }
+|
+ CALL expression
+ { emit(3, 0315, $2, $2 >> 8); }
+|
+ RST expression
+ { if ($2 > 7 || $2 < 0)
+ err[vflag]++;
+ emit(1, $1->i_value + (($2 & 7) << 3));
+ }
+|
+ ADD ACC ',' expression
+ { emit1(0306, 0, $4, 3); }
+|
+ ARITHC ACC ',' expression
+ { emit1(0306 + ($1->i_value << 3), 0, $4, 3); }
+|
+ LOGICAL expression
+ { emit1(0306 | ($1->i_value << 3), 0, $2, 3); }
+|
+ LOGICAL ACC ',' expression /* -cdk */
+ { emit1(0306 | ($1->i_value << 3), 0, $4, 3); }
+|
+ ADD ACC ',' reg
+ { emit1(0200 + ($4 & 0377), $4, 0, 0); }
+|
+ ARITHC ACC ',' reg
+ { emit1(0200 + ($1->i_value << 3) + ($4 & 0377), $4, 0, 0); }
+|
+ LOGICAL reg
+ { emit1(0200 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0); }
+|
+ LOGICAL ACC ',' reg /* -cdk */
+ { emit1(0200 + ($1->i_value << 3) + ($4 & 0377), $4, 0, 0); }
+|
+ SHIFT reg
+ { emit1(0145400 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0); }
+|
+ INCDEC reg
+ { emit1($1->i_value + (($2 & 0377) << 3) + 4, $2, 0, 0); }
+|
+ ARITHC HL ',' bcdehlsp
+ { if ($1->i_value == 1)
+ emit(2,0355,0112+$4);
+ else
+ emit(2,0355,0102+$4);
+ }
+|
+ ADD mar ',' bcdesp
+ { emitdad($2,$4); }
+|
+ ADD mar ',' mar
+ {
+ if ($2 != $4) {
+ fprintf(stderr,"ADD mar, mar error\n");
+ err[fflag]++;
+ }
+ emitdad($2,$4);
+ }
+|
+ INCDEC evenreg
+ { emit1(($1->i_value << 3) + ($2 & 0377) + 3, $2, 0, 1); }
+|
+ PUSHPOP pushable
+ { emit1($1->i_value + ($2 & 0377), $2, 0, 1); }
+|
+ BIT expression ',' reg
+ {
+ if ($2 < 0 || $2 > 7)
+ err[vflag]++;
+ emit1($1->i_value + (($2 & 7) << 3) + ($4 & 0377), $4, 0, 0);
+ }
+|
+ JP condition ',' expression
+ { emit(3, 0302 + $2, $4, $4 >> 8); }
+|
+ JP '(' mar ')'
+ { emit1(0351, $3, 0, 1); }
+|
+ CALL condition ',' expression
+ { emit(3, 0304 + $2, $4, $4 >> 8); }
+|
+ JR expression
+ { emitjr(030,$2); }
+|
+ JR spcondition ',' expression
+ { emitjr($1->i_value + $2, $4); }
+|
+ DJNZ expression
+ { emitjr($1->i_value, $2); }
+|
+ RET
+ { emit(1, $1->i_value); }
+|
+ RET condition
+ { emit(1, 0300 + $2); }
+|
+ LD reg ',' reg
+ {
+ if (($2 & 0377) == 6 && ($4 & 0377) == 6) {
+ fprintf(stderr,"LD reg, reg error\n");
+ err[fflag]++;
+ }
+ emit1(0100 + (($2 & 7) << 3) + ($4 & 7),$2 | $4, 0, 0);
+ }
+|
+ LD reg ',' expression
+ { emit1(6 + (($2 & 0377) << 3), $2, $4, 2); }
+|
+ LD reg ',' '(' RP ')'
+ { if ($2 != 7) {
+ fprintf(stderr,"LD reg, (RP) error\n");
+ err[fflag]++;
+ }
+ else emit(1, 012 + $5->i_value);
+ }
+|
+ LD reg ',' parenexpr
+ {
+ if ($2 != 7) {
+ fprintf(stderr,"LD reg, (expr) error\n");
+ err[fflag]++;
+ }
+ else emit(3, 072, $4, $4 >> 8);
+ }
+|
+ LD '(' RP ')' ',' ACC
+ { emit(1, 2 + $3->i_value); }
+|
+ LD parenexpr ',' ACC
+ { emit(3, 062, $2, $2 >> 8); }
+|
+ LD reg ',' MISCREG
+ {
+ if ($2 != 7) {
+ fprintf(stderr,"LD reg, MISCREG error\n");
+ err[fflag]++;
+ }
+ else emit(2, 0355, 0127 + $4->i_value);
+ }
+|
+ LD MISCREG ',' ACC
+ { emit(2, 0355, 0107 + $2->i_value); }
+|
+ LD evenreg ',' lxexpression
+ { emit1(1 + ($2 & 060), $2, $4, 5); }
+|
+ LD evenreg ',' parenexpr
+ {
+ if (($2 & 060) == 040)
+ emit1(052, $2, $4, 5);
+ else
+ emit(4, 0355, 0113 + $2, $4, $4 >> 8);
+ }
+|
+ LD parenexpr ',' evenreg
+ {
+ if (($4 & 060) == 040)
+ emit1(042, $4, $2, 5);
+ else
+ emit(4, 0355, 0103 + $4, $2, $2 >> 8);
+ }
+|
+ LD evenreg ',' mar
+ {
+ if ($2 != 060) {
+ fprintf(stderr,"LD evenreg error\n");
+ err[fflag]++;
+ }
+ else
+ emit1(0371, $4, 0, 1);
+ }
+|
+ EX RP ',' HL
+ {
+ if ($2->i_value != 020) {
+ fprintf(stderr,"EX RP, HL error\n");
+ err[fflag]++;
+ }
+ else
+ emit(1, 0353);
+ }
+|
+ EX AF ',' AF setqf '\'' clrqf
+ { emit(1, 010); }
+|
+ EX '(' SP ')' ',' mar
+ { emit1(0343, $6, 0, 1); }
+|
+ IN realreg ',' parenexpr
+ {
+ if ($2 != 7) {
+ fprintf(stderr,"IN reg, (expr) error\n");
+ err[fflag]++;
+ }
+ else {
+ if ($4 < 0 || $4 > 255)
+ err[vflag]++;
+ emit(2, $1->i_value, $4);
+ }
+ }
+|
+ IN realreg ',' '(' C ')'
+ { emit(2, 0355, 0100 + ($2 << 3)); }
+|
+ IN F ',' '(' C ')'
+ { emit(2, 0355, 0160); }
+|
+ OUT parenexpr ',' ACC
+ {
+ if ($2 < 0 || $2 > 255)
+ err[vflag]++;
+ emit(2, $1->i_value, $2);
+ }
+|
+ OUT '(' C ')' ',' realreg
+ { emit(2, 0355, 0101 + ($6 << 3)); }
+|
+ IM expression
+ {
+ if ($2 > 2 || $2 < 0)
+ err[vflag]++;
+ else
+ emit(2, $1->i_value >> 8, $1->i_value + (($2 + ($2 > 0)) << 3));
+ }
+|
+ PHASE expression
+ {
+ if (phaseflag) {
+ err[oflag]++;
+ } else {
+ phaseflag = 1;
+ phdollar = dollarsign;
+ dollarsign = $2;
+ phbegin = dollarsign;
+ }
+ }
+|
+ DEPHASE
+ {
+ if (!phaseflag) {
+ err[oflag]++;
+ } else {
+ phaseflag = 0;
+ dollarsign = phdollar + dollarsign - phbegin;
+ }
+ }
+|
+ ORG expression
+ {
+ if (phaseflag) {
+ err[oflag]++;
+ dollarsign = phdollar + dollarsign - phbegin;
+ phaseflag = 0;
+ }
+ if ($2-dollarsign) {
+ flushbin();
+ olddollar = $2;
+ dollarsign = $2;
+ }
+ }
+|
+ DEFB db.list
+|
+ DEFW dw.list
+|
+ ENDM
+;
+
+
+parm.list:
+|
+ parm.element
+|
+ parm.list ',' parm.element
+;
+
+
+parm.element:
+ UNDECLARED
+ {
+ $1->i_token = MPARM;
+ if (parm_number >= PARMMAX)
+ error("Too many parameters");
+ $1->i_value = parm_number++;
+ }
+;
+
+
+arg.list:
+ /* empty */
+|
+ arg.element
+|
+ arg.list ',' arg.element
+;
+
+
+arg.element:
+ ARG
+ {
+ cp = malloc(strlen(tempbuf)+1);
+ est2[parm_number++] = cp;
+ strcpy(cp, tempbuf);
+ }
+;
+reg:
+ realreg
+|
+ mem
+;
+realreg:
+ REGNAME
+ {
+ $$ = $1->i_value;
+ }
+|
+ ACC
+ {
+ $$ = $1->i_value;
+ }
+|
+ C
+ {
+ $$ = $1->i_value;
+ }
+;
+mem:
+ '(' HL ')'
+ {
+ $$ = 6;
+ }
+|
+ '(' INDEX expression ')'
+ {
+ disp = $3;
+ $$ = ($2->i_value & 0177400) | 6;
+ }
+|
+ '(' INDEX ')'
+ {
+ disp = 0;
+ $$ = ($2->i_value & 0177400) | 6;
+ }
+;
+evenreg:
+ bcdesp
+|
+ mar
+;
+pushable:
+ RP
+ {
+ $$ = $1->i_value;
+ }
+|
+ AF
+ {
+ $$ = $1->i_value;
+ }
+|
+ mar
+;
+bcdesp:
+ RP
+ {
+ $$ = $1->i_value;
+ }
+|
+ SP
+ {
+ $$ = $1->i_value;
+ }
+;
+bcdehlsp:
+ bcdesp
+|
+ HL
+ {
+ $$ = $1->i_value;
+ }
+;
+mar:
+ HL
+ {
+ $$ = $1->i_value;
+ }
+|
+ INDEX
+ {
+ $$ = $1->i_value;
+ }
+;
+condition:
+ spcondition
+|
+ COND
+ {
+ $$ = $1->i_value;
+ }
+;
+spcondition:
+ SPCOND
+ {
+ $$ = $1->i_value;
+ }
+|
+ C
+ { $$ = 030; }
+;
+db.list:
+ db.list.element
+|
+ db.list ',' db.list.element
+;
+db.list.element:
+ TWOCHAR
+ {
+ emit(2, $1, $1>>8);
+ }
+|
+ STRING
+ {
+ cp = $1;
+ while (*cp != '\0')
+ emit(1,*cp++);
+ }
+|
+ expression
+ {
+ if ($1 < -128 || $1 > 255)
+ err[vflag]++;
+ emit(1, $1 & 0377);
+ }
+;
+
+
+dw.list:
+ dw.list.element
+|
+ dw.list ',' dw.list.element
+;
+
+
+dw.list.element:
+ expression
+ {
+ emit(2, $1, $1>>8);
+ }
+;
+
+
+
+lxexpression:
+ expression
+|
+ TWOCHAR
+;
+
+parenexpr:
+ '(' expression ')'
+ { $$ = $2; }
+;
+
+expression:
+ error
+ {
+ err[eflag]++;
+ $$ = 0;
+ }
+|
+ LABEL
+ { $$ = $1->i_value; $1->i_uses++ ; }
+|
+ NUMBER
+|
+ ONECHAR
+|
+ EQUATED
+ { $$ = $1->i_value; }
+|
+ WASEQUATED
+ { $$ = $1->i_value; }
+|
+ DEFLED
+ { $$ = $1->i_value; }
+|
+ '$'
+ { $$ = dollarsign; }
+|
+ UNDECLARED
+ {
+ err[uflag]++;
+ $$ = 0;
+ }
+|
+ MULTDEF
+ { $$ = $1->i_value; }
+|
+ expression '+' expression
+ { $$ = $1 + $3; }
+|
+ expression '-' expression
+ { $$ = $1 - $3; }
+|
+ expression '/' expression
+ { $$ = $1 / $3; }
+|
+ expression '*' expression
+ { $$ = $1 * $3; }
+|
+ expression MOD expression
+ { $$ = $1 % $3; }
+|
+ expression '&' expression
+ { $$ = $1 & $3; }
+|
+ expression '|' expression
+ { $$ = $1 | $3; }
+|
+ expression '^' expression
+ { $$ = $1 ^ $3; }
+|
+ expression SHL expression
+ { $$ = $1 << $3; }
+|
+ expression SHR expression
+ { $$ = (($1 >> 1) & 077777) >> ($3 - 1); }
+|
+ '[' expression ']'
+ { $$ = $2; }
+|
+ NOT expression
+ { $$ = ~$2; }
+|
+ '+' expression %prec UNARY
+ { $$ = $2; }
+|
+ '-' expression %prec UNARY
+ { $$ = -$2; }
+;
+
+symbol:
+ UNDECLARED
+|
+ LABEL
+|
+ MULTDEF
+|
+ EQUATED
+|
+ WASEQUATED
+|
+ DEFLED
+;
+
+
+al:
+ {
+ if (expptr >= MAXEXP)
+ error("Macro expansion level");
+ est2 = (char **) malloc((PARMMAX +4) * sizeof(char *));
+ expstack[expptr] = (char *)est2 ;
+ for (i=0; i<PARMMAX; i++)
+ est2[i] = 0;
+ arg_flag++;
+ }
+;
+
+
+arg_on:
+ { arg_flag++; }
+;
+
+arg_off:
+ { arg_flag = 0; }
+;
+
+setqf:
+ { quoteflag++; }
+;
+
+clrqf:
+ { quoteflag = 0; }
+
+;
+
+%%
+/*extern int yylval;*/
+
+#define F_END 0
+#define OTHER 1
+#define SPACE 2
+#define DIGIT 3
+#define LETTER 4
+#define STARTER 5
+
+
+/*
+ * This is the table of character classes. It is used by the lexical
+ * analyser. (yylex())
+ */
+char charclass[] = {
+ F_END, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
+ OTHER, SPACE, OTHER, OTHER, OTHER, SPACE, OTHER, OTHER,
+ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
+ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
+ SPACE, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
+ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
+ DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
+ DIGIT, DIGIT, OTHER, OTHER, OTHER, OTHER, OTHER, STARTER,
+ STARTER,LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+ LETTER, LETTER, LETTER, OTHER, OTHER, OTHER, OTHER, LETTER,
+ OTHER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+ LETTER, LETTER, LETTER, OTHER, OTHER, OTHER, OTHER, OTHER,
+};
+
+
+/*
+ * the following table tells which characters are parts of numbers.
+ * The entry is non-zero for characters which can be parts of numbers.
+ */
+char numpart[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 0, 0, 0, 0, 0, 0,
+ 0, 'A', 'B', 'C', 'D', 'E', 'F', 0,
+ 'H', 0, 0, 0, 0, 0, 0, 'O',
+ 0, 'Q', 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 'a', 'b', 'c', 'd', 'e', 'f', 0,
+ 'h', 0, 0, 0, 0, 0, 0, 'o',
+ 0, 'q', 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0};
+
+
+
+
+/*
+ * the following table is a list of assembler mnemonics;
+ * for each mnemonic the associated machine-code bit pattern
+ * and symbol type are given.
+ */
+struct item keytab[] = {
+ "a", 7, ACC, 0,
+ "adc", 1, ARITHC, 0,
+ "add", 0, ADD, 0,
+ "af", 060, AF, 0,
+ "and", 4, LOGICAL, 0,
+ "ascii",0, DEFB, 0,
+ "b", 0, REGNAME, 0,
+ "bc", 0, RP, 0,
+ "bit", 0145500,BIT, 0,
+ "block",0, DEFS, 0,
+ "byte", 0, DEFB, 0,
+ "c", 1, C, 0,
+ "call", 0315, CALL, 0,
+ "ccf", 077, NOOPERAND, 0,
+ "cmp", 7, LOGICAL, 0, /* -cdk */
+ "cp", 7, LOGICAL, 0,
+ "cpd", 0166651,NOOPERAND, 0,
+ "cpdr", 0166671,NOOPERAND, 0,
+ "cpi", 0166641,NOOPERAND, 0,
+ "cpir", 0166661,NOOPERAND, 0,
+ "cpl", 057, NOOPERAND, 0,
+ "d", 2, REGNAME, 0,
+ "daa", 0047, NOOPERAND, 0,
+ "de", 020, RP, 0,
+ "dec", 1, INCDEC, 0,
+ "defb", 0, DEFB, 0,
+ "defl",0, DEFL, 0,
+ "defs", 0, DEFS, 0,
+ "defw", 0, DEFW, 0,
+ "dephase", 0, DEPHASE, 0,
+ "di", 0363, NOOPERAND, 0,
+ "djnz", 020, DJNZ, 0,
+ "e", 3, REGNAME, 0,
+ "ei", 0373, NOOPERAND, 0,
+ "eject",1, LIST, 0,
+ "elist",3, LIST, 0,
+ "end", 0, END, 0,
+ "endif",0, ENDIF, 0,
+ "endm", 0, ENDM, 0,
+ "equ", 0, EQU, 0,
+ "ex", 0, EX, 0,
+ "exx", 0331, NOOPERAND, 0,
+ "f", 0, F, 0,
+ "flist",4, LIST, 0,
+ "glist",5, LIST, 0,
+ "h", 4, REGNAME, 0,
+ "halt", 0166, NOOPERAND, 0,
+ "hl", 040, HL, 0,
+ "i", 0, MISCREG, 0,
+ "if", 0, IF, 0,
+ "im", 0166506,IM, 0,
+ "in", 0333, IN, 0,
+ "inc", 0, INCDEC, 0,
+ "include", 3, ARGPSEUDO, 0,
+ "ind", 0166652,NOOPERAND, 0,
+ "indr", 0166672,NOOPERAND, 0,
+ "ini", 0166642,NOOPERAND, 0,
+ "inir", 0166662,NOOPERAND, 0,
+ "ix", 0156440,INDEX, 0,
+ "iy", 0176440,INDEX, 0,
+ "jmp", 0303, JP, 0, /* -cdk */
+ "jp", 0303, JP, 0,
+ "jr", 040, JR, 0,
+ "l", 5, REGNAME, 0,
+ "ld", 0, LD, 0,
+ "ldd", 0166650,NOOPERAND, 0,
+ "lddr", 0166670,NOOPERAND, 0,
+ "ldi", 0166640,NOOPERAND, 0,
+ "ldir", 0166660,NOOPERAND, 0,
+ "list", 0, LIST, 0,
+ "m", 070, COND, 0,
+ "macro",0, MACRO, 0,
+ "max", 1, MINMAX, 0,
+ "min", 0, MINMAX, 0,
+ "mlist",6, LIST, 0,
+ "mod", 0, MOD, 0,
+ "nc", 020, SPCOND, 0,
+ "neg", 0166504,NOOPERAND, 0,
+ "nolist",-1, LIST, 0,
+ "nop", 0, NOOPERAND, 0,
+ "not", 0, NOT, 0,
+ "nv", 040, COND, 0,
+ "nz", 0, SPCOND, 0,
+ "or", 6, LOGICAL, 0,
+ "org", 0, ORG, 0,
+ "otdr",0166673,NOOPERAND, 0,
+ "otir",0166663,NOOPERAND, 0,
+ "out", 0323, OUT, 0,
+ "outd", 0166653,NOOPERAND, 0,
+ "outi", 0166643,NOOPERAND, 0,
+ "p", 060, COND, 0,
+ "pe", 050, COND, 0,
+ "phase", 0, PHASE, 0,
+ "po", 040, COND, 0,
+ "pop", 0301, PUSHPOP, 0,
+ "push", 0305, PUSHPOP, 0,
+ "r", 010, MISCREG, 0,
+ "res", 0145600,BIT, 0,
+ "ret", 0311, RET, 0,
+ "reti", 0166515,NOOPERAND, 0,
+ "retn", 0166505,NOOPERAND, 0,
+ "rl", 2, SHIFT, 0,
+ "rla", 027, NOOPERAND, 0,
+ "rlc", 0, SHIFT, 0,
+ "rlca", 07, NOOPERAND, 0,
+ "rld", 0166557,NOOPERAND, 0,
+ "rr", 3, SHIFT, 0,
+ "rra", 037, NOOPERAND, 0,
+ "rrc", 1, SHIFT, 0,
+ "rrca", 017, NOOPERAND, 0,
+ "rrd", 0166547,NOOPERAND, 0,
+ "rst", 0307, RST, 0,
+ "rsym", 1, ARGPSEUDO, 0,
+ "sbc", 3, ARITHC, 0,
+ "scf", 067, NOOPERAND, 0,
+ "set", 0145700,BIT, 0,
+ "shl", 0, SHL, 0,
+ "shr", 0, SHR, 0,
+ "sla", 4, SHIFT, 0,
+ "sp", 060, SP, 0,
+ "space",2, LIST, 0,
+ "sra", 5, SHIFT, 0,
+ "srl", 7, SHIFT, 0,
+ "sub", 2, LOGICAL, 0,
+ "title",0, ARGPSEUDO, 0,
+ "v", 050, COND, 0,
+ "word", 0, DEFW, 0,
+ "wsym", 2, ARGPSEUDO, 0,
+ "xor", 5, LOGICAL, 0,
+ "z", 010, SPCOND, 0,
+};
+
+/*
+ * user-defined items are tabulated in the following table.
+ */
+
+struct item itemtab[ITEMTABLESIZE];
+struct item *itemmax = &itemtab[ITEMTABLESIZE];
+
+
+
+
+
+/*
+ * lexical analyser, called by yyparse.
+ */
+yylex()
+{
+ register char c;
+ register char *p;
+ register int radix;
+ int limit;
+
+ if (arg_flag)
+ return(getarg());
+loop switch(charclass[c = nextchar()]) {
+ case F_END:
+ if (expptr) {
+ popsi();
+ continue;
+ } else return(0);
+
+ case SPACE:
+ break;
+ case LETTER:
+ case STARTER:
+ p = tempbuf;
+ do {
+ if (p >= tempmax)
+ error(symlong);
+ *p++ = (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
+ while ((c = nextchar()) == '$')
+ ;
+ } while (charclass[c]==LETTER || charclass[c]==DIGIT);
+ if (p - tempbuf > MAXSYMBOLSIZE)
+ p = tempbuf + MAXSYMBOLSIZE;
+ *p++ = '\0';
+ peekc = c;
+ return(tokenofitem(UNDECLARED));
+ case DIGIT:
+ if (*ifptr) return(skipline(c));
+ p = tempbuf;
+ do {
+ if (p >= tempmax)
+ error(symlong);
+ *p++ = (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
+ while ((c = nextchar()) == '$');
+ }
+ while(numpart[c]);
+ peekc = c;
+ *p-- = '\0';
+ switch(*p) {
+ case 'o':
+ case 'q':
+ radix = 8;
+ limit = 020000;
+ *p = '\0';
+ break;
+ case 'd':
+ radix = 10;
+ limit = 3276;
+ *p = '\0';
+ break;
+ case 'h':
+ radix = 16;
+ limit = 010000;
+ *p = '\0';
+ break;
+ case 'b':
+ radix = 2;
+ limit = 077777;
+ *p = '\0';
+ break;
+ default:
+ radix = 10;
+ limit = 3276;
+ p++;
+ break;
+ }
+
+ /*
+ * tempbuf now points to the number, null terminated
+ * with radix 'radix'.
+ */
+ yylval.ival = 0;
+ p = tempbuf;
+ do {
+ c = *p - (*p > '9' ? ('a' - 10) : '0');
+ if (c >= radix)
+ {
+ err[iflag]++;
+ yylval.ival = 0;
+ break;
+ }
+ if (yylval.ival < limit ||
+ (radix == 10 && yylval.ival == 3276 && c < 8) ||
+ (radix == 2 && yylval.ival == limit))
+ yylval.ival = yylval.ival * radix + c;
+ else {
+ err[vflag]++;
+ yylval.ival = 0;
+ break;
+ }
+ }
+ while(*++p != '\0');
+ return(NUMBER);
+ default:
+ if (*ifptr)
+ return(skipline(c));
+ switch(c) {
+ case ';':
+ return(skipline(c));
+ case '\'':
+ if (quoteflag) return('\'');
+ p = tempbuf;
+ p[1] = 0;
+ do switch(c = nextchar()) {
+ case '\0':
+ case '\n':
+ err[bflag]++;
+ goto retstring;
+ case '\'':
+ if ((c = nextchar()) != '\'') {
+ retstring:
+ peekc = c;
+ *p = '\0';
+ if ((p-tempbuf) >2) {
+ yylval.cval = tempbuf;
+ return(STRING);
+ } else if (p-tempbuf == 2) {
+ p = tempbuf;
+ yylval.ival = *p++ ;
+ yylval.ival |= *p<<8;
+ return(TWOCHAR);
+ } else {
+ p = tempbuf;
+ yylval.ival = *p++;
+ return(ONECHAR);
+ }
+ }
+ default:
+ *p++ = c;
+ } while (p < tempmax);
+ /*
+ * if we break out here, our string is longer than
+ * our input line
+ */
+ error("string buffer overflow");
+ default:
+ return(c);
+ }
+ }
+}
+
+/*
+ * return the token associated with the string pointed to by
+ * tempbuf. if no token is associated with the string, associate
+ * deftoken with the string and return deftoken.
+ * in either case, cause yylval to point to the relevant
+ * symbol table entry.
+ */
+
+tokenofitem(deftoken)
+int deftoken;
+{
+ register char *p;
+ register struct item * ip;
+ register i;
+ int r, l, u, hash;
+
+
+#ifdef T_DEBUG
+ fputs("'tokenofitem entry' ", stderr) ;
+ fputs(tempbuf, stderr) ;
+#endif
+ /*
+ * binary search
+ */
+ l = 0;
+ u = (sizeof keytab/sizeof keytab[0])-1;
+ while (l <= u) {
+ i = (l+u)/2;
+ ip = &keytab[i];
+ if ((r = strcmp(tempbuf, ip->i_string)) == 0)
+ goto found;
+ if (r < 0)
+ u = i-1;
+ else
+ l = i+1;
+ }
+
+ /*
+ * hash into item table
+ */
+ hash = 0;
+ p = tempbuf;
+ while (*p) hash += *p++;
+ hash %= ITEMTABLESIZE;
+ ip = &itemtab[hash];
+
+ loop {
+ if (ip->i_token == 0)
+ break;
+ if (strcmp(tempbuf, ip->i_string) == 0)
+ goto found;
+ if (++ip >= itemmax)
+ ip = itemtab;
+ }
+
+ if (!deftoken) {
+ i = 0 ;
+ goto token_done ;
+ }
+ if (++nitems > ITEMTABLESIZE-20)
+ error("item table overflow");
+ ip->i_string = malloc(strlen(tempbuf)+1);
+ ip->i_token = deftoken;
+ ip->i_uses = 0 ;
+ strcpy(ip->i_string, tempbuf);
+
+found:
+ if (*ifptr) {
+ if (ip->i_token == ENDIF) {
+ i = ENDIF ;
+ goto token_done ;
+ }
+ if (ip->i_token == IF) {
+ if (ifptr >= ifstmax)
+ error("Too many ifs");
+ else *++ifptr = 1;
+ }
+ i = skipline(' ');
+ goto token_done ;
+ }
+ yylval.itemptr = ip;
+ i = ip->i_token;
+token_done:
+#ifdef T_DEBUG
+ fputs("\t'tokenofitem exit'\n", stderr) ;
+#endif
+ return(i) ;
+}
+
+
+/*
+ * interchange two entries in the item table -- used by qsort
+ */
+interchange(i, j)
+{
+ register struct item *fp, *tp;
+ struct item temp;
+
+ fp = &itemtab[i];
+ tp = &itemtab[j];
+ temp.i_string = fp->i_string;
+ temp.i_value = fp->i_value;
+ temp.i_token = fp->i_token;
+ temp.i_uses = fp->i_uses;
+
+ fp->i_string = tp->i_string;
+ fp->i_value = tp->i_value;
+ fp->i_token = tp->i_token;
+ fp->i_uses = tp->i_uses;
+
+ tp->i_string = temp.i_string;
+ tp->i_value = temp.i_value;
+ tp->i_token = temp.i_token;
+ tp->i_uses = temp.i_uses;
+}
+
+
+
+/*
+ * quick sort -- used by putsymtab to sort the symbol table
+ */
+qsort(m, n)
+{
+ register i, j;
+
+ if (m < n) {
+ i = m;
+ j = n+1;
+ loop {
+ do i++; while(strcmp(itemtab[i].i_string,
+ itemtab[m].i_string) < 0);
+ do j--; while(strcmp(itemtab[j].i_string,
+ itemtab[m].i_string) > 0);
+ if (i < j) interchange(i, j); else break;
+ }
+ interchange(m, j);
+ qsort(m, j-1);
+ qsort(j+1, n);
+ }
+}
+
+
+
+/*
+ * get the next character
+ */
+nextchar()
+{
+ register int c, ch;
+ static char *earg;
+ char *getlocal();
+
+ if (peekc != -1) {
+ c = peekc;
+ peekc = -1;
+ return(c);
+ }
+
+start:
+ if (earg) {
+ if (*earg)
+ return(addtoline(*earg++));
+ earg = 0;
+ }
+
+ if (expptr) {
+ if ((ch = getm()) == '\1') { /* expand argument */
+ ch = getm() - 'A';
+ if (ch >= 0 && ch < PARMMAX && est[ch])
+ earg = est[ch];
+ goto start;
+ }
+ if (ch == '\2') { /* local symbol */
+ ch = getm() - 'A';
+ if (ch >= 0 && ch < PARMMAX && est[ch]) {
+ earg = est[ch];
+ goto start;
+ }
+ earg = getlocal(ch, (int)est[TEMPNUM]);
+ goto start;
+ }
+
+ return(addtoline(ch));
+ }
+ ch = getc(now_file) ;
+ /* if EOF, check for include file */
+ if (ch == EOF) {
+ while (ch == EOF && now_in) {
+ fclose(fin[now_in]) ;
+ free(src_name[now_in]) ;
+ now_file = fin[--now_in] ;
+ ch = getc(now_file) ;
+ }
+ if (linein[now_in] < 0) {
+ lstoff = 1 ;
+ linein[now_in] = -linein[now_in] ;
+ } else {
+ lstoff = 0 ;
+ }
+ if (pass2 && iflist()) {
+ lineout() ;
+ fprintf(fout, "**** %s ****\n", src_name[now_in]) ;
+ }
+ }
+ if (ch == '\n')
+ linein[now_in]++ ;
+
+ return(addtoline(ch)) ;
+}
+
+
+/*
+ * skip to rest of the line -- comments and if skipped lines
+ */
+skipline(ac)
+{
+ register c;
+
+ c = ac;
+ while (c != '\n' && c != '\0')
+ c = nextchar();
+ return('\n');
+}
+
+
+
+main(argc, argv)
+char **argv;
+{
+ register struct item *ip;
+ register i;
+ int files;
+#ifdef DBUG
+ extern yydebug;
+#endif
+
+ fout = stdout ;
+ fin[0] = stdin ;
+ now_file = stdin ;
+ files = 0;
+
+ for (i=1; i<argc; i++) {
+ if (*argv[i] == '-') while (*++argv[i]) switch(*argv[i]) {
+
+ case 'b': /* no binary */
+ bopt = 0;
+ continue;
+
+#ifdef DBUG
+ case 'd': /* debug */
+ yydebug++;
+ continue;
+#endif
+
+ case 'e': /* error list only */
+ eopt = 0;
+ edef = 0;
+ continue;
+
+ case 'f': /* print if skipped lines */
+ fopt++;
+ fdef++;
+ continue;
+
+ case 'g': /* do not list extra code */
+ gopt = 0;
+ gdef = 0;
+ continue;
+
+ case 'i': /* do not list include files */
+ iopt = 1 ;
+ continue ;
+
+ case 'l': /* no list */
+ lopt++;
+ continue;
+
+ case 'L': /* force listing of everything */
+ lston++;
+ continue;
+
+ case 'm': /* print macro expansions */
+ mdef++;
+ mopt++;
+ continue;
+
+ case 'n': /* put line numbers off */
+ nopt-- ;
+ continue;
+
+ case 'o': /* list to standard output */
+ oopt++;
+ continue;
+
+ case 'p': /* put out four \n's for eject */
+ popt-- ;
+ continue;
+
+ case 's': /* don't produce a symbol list */
+ sopt++;
+ continue;
+
+ case 't':
+ topt = 0;
+ continue;
+
+ default: /* error */
+ error("Unknown option");
+
+ } else if (files++ == 0) {
+ sourcef = argv[i];
+ strcpy(src, sourcef);
+ suffix(src,".asm");
+ if ((now_file = fopen(src, "r")) == NULL)
+ error("Cannot open source file");
+ now_in = 0 ;
+ fin[now_in] = now_file ;
+ src_name[now_in] = src ;
+ } else if (files)
+ error("Too many arguments");
+ }
+
+
+ if (files == 0)
+ error("No source file");
+ strcpy(bin, sourcef);
+ suffix(bin,".hex");
+ if (bopt)
+#ifdef MSDOS
+ if (( fbuf = fopen(bin, "wb")) == NULL)
+#else
+ if (( fbuf = fopen(bin, "w")) == NULL)
+#endif
+ error("Cannot create binary file");
+ if (!lopt && !oopt) {
+ strcpy(listf, sourcef);
+ suffix(listf,".lst");
+ if ((fout = fopen(listf, "w")) == NULL)
+ error("Cannot create list file");
+ } else
+ fout = stdout ;
+ strcpy(mtmp, sourcef);
+ suffix(mtmp,".tmp");
+#ifdef MSDOS
+ mfile = mfopen(mtmp,"w+b") ;
+#else
+ mfile = mfopen(mtmp,"w+") ;
+#endif
+ if (mfile == NULL) {
+ error("Cannot create temp file");
+ }
+ /*unlink(mtmp);*/
+
+ /*
+ * get the time
+ */
+ time(&now);
+ timp = ctime(&now);
+ timp[16] = 0;
+ timp[24] = 0;
+
+ title = sourcef;
+ /*
+ * pass 1
+ */
+#ifdef DEBUG
+ fputs("DEBUG-pass 1\n", stderr) ;
+#endif
+ setvars();
+ yyparse();
+ pass2++;
+ ip = &itemtab[-1];
+ while (++ip < itemmax) {
+ /* reset use count */
+ ip->i_uses = 0 ;
+
+ /* set macro names, equated and defined names */
+ switch (ip->i_token) {
+ case MNAME:
+ ip->i_token = OLDMNAME;
+ break;
+
+ case EQUATED:
+ ip->i_token = WASEQUATED;
+ break;
+
+ case DEFLED:
+ ip->i_token = UNDECLARED;
+ break;
+ }
+ }
+ setvars();
+ fseek(now_file, (long)0, 0);
+
+#ifdef DEBUG
+ fputs("DEBUG- pass 2\n", stderr) ;
+#endif
+ yyparse();
+
+
+ if (bopt) {
+ flushbin();
+ putc(':', fbuf);
+ if (xeq_flag) {
+ puthex(0, fbuf);
+ puthex(xeq >> 8, fbuf);
+ puthex(xeq, fbuf);
+ puthex(1, fbuf);
+ puthex(255-(xeq >> 8)-xeq, fbuf);
+ } else
+ for (i = 0; i < 10; i++)
+ putc('0', fbuf);
+ putc('\n', fbuf);
+ fflush(fbuf);
+ }
+
+ if (!lopt)
+ fflush(fout);
+ if (writesyms)
+ outsymtab(writesyms);
+ if (eopt)
+ erreport();
+ if (!lopt && !sopt)
+ putsymtab();
+ if (!lopt) {
+ eject();
+ fflush(fout);
+ }
+ exit(0);
+}
+
+
+/*
+ * set some data values before each pass
+ */
+setvars()
+{
+ register i;
+
+ peekc = -1;
+ linein[now_in] = linecnt = 0;
+ exp_number = 0;
+ emitptr = emitbuf;
+ lineptr = linebuf;
+ ifptr = ifstack;
+ expifp = expif;
+ *ifptr = 0;
+ dollarsign = 0;
+ olddollar = 0;
+ phaseflag = 0;
+ for (i=0; i<FLAGS; i++) err[i] = 0;
+}
+
+
+
+/*
+ * print out an error message and die
+ */
+error(as)
+char *as;
+{
+
+ *linemax = 0;
+ fprintf(fout, "%s\n", linebuf);
+ fflush(fout);
+ fprintf(stderr, "%s\n", as) ;
+ exit(1);
+}
+
+
+
+/*
+ * output the symbol table
+ */
+putsymtab()
+{
+ register struct item *tp, *fp;
+ int i, j, k, t, rows;
+ char c, c1 ;
+
+ if (!nitems)
+ return;
+
+ /* compact the table so unused and UNDECLARED entries are removed */
+ tp = &itemtab[-1];
+ for (fp = itemtab; fp<itemmax; fp++) {
+ if (fp->i_token == UNDECLARED) {
+ nitems--;
+ continue;
+ }
+ if (fp->i_token == 0)
+ continue;
+ tp++;
+ if (tp != fp) {
+ tp->i_string = fp->i_string;
+ tp->i_value = fp->i_value;
+ tp->i_token = fp->i_token;
+ tp->i_uses = fp->i_uses ;
+ }
+ }
+
+ tp++;
+ tp->i_string = "{";
+
+ /* sort the table */
+ qsort(0, nitems-1);
+
+ title = "** Symbol Table **";
+
+ rows = (nitems+3) / 4;
+ if (rows+5+line > 60)
+ eject();
+ lineout();
+ fprintf(fout,"\n\n\nSymbol Table:\n\n") ;
+ line += 4;
+
+ for (i=0; i<rows; i++) {
+ for(j=0; j<4; j++) {
+ k = rows*j+i;
+ if (k < nitems) {
+ tp = &itemtab[k];
+ t = tp->i_token;
+ c = ' ' ;
+ if (t == EQUATED || t == DEFLED)
+ c = '=' ;
+ if (tp->i_uses == 0)
+ c1 = '+' ;
+ else
+ c1 = ' ' ;
+ fprintf(fout, "%-15s%c%4x%c ",
+ tp->i_string, c, tp->i_value & 0xffff, c1);
+ }
+ }
+ lineout();
+ putc('\n', fout);
+ }
+}
+
+
+
+
+/*
+ * put out error report
+ */
+erreport()
+{
+ register i, numerr;
+
+ if (line > 50) eject();
+ lineout();
+ numerr = 0;
+ for (i=0; i<FLAGS; i++) numerr += keeperr[i];
+ if (numerr) {
+ fputs("\n\n\nError report:\n\n", fout);
+ fprintf(fout, "%6d errors\n", numerr);
+ line += 5;
+ } else {
+ fputs("\n\n\nStatistics:\n", fout);
+ line += 3;
+ }
+
+ for (i=0; i<FLAGS; i++)
+ if (keeperr[i]) {
+ lineout();
+ fprintf(fout, "%6d %c -- %s error\n",
+ keeperr[i], errlet[i], errname[i]);
+ }
+
+ if (line > 55) eject();
+ lineout();
+ fprintf(fout, "\n%6d\tsymbols\n", nitems);
+ fprintf(fout, "%6d\tbytes\n", nbytes);
+ line += 2;
+ if (mfptr) {
+ if (line > 53) eject();
+ lineout();
+ fprintf(fout, "\n%6d\tmacro calls\n", exp_number);
+ fprintf(fout, "%6d\tmacro bytes\n", mfptr);
+ fprintf(fout, "%6d\tinvented symbols\n", invented/2);
+ line += 3;
+ }
+}
+
+
+/*
+ * lexical analyser for macro definition
+ */
+mlex()
+{
+ register char *p;
+ register c;
+ int t;
+
+ /*
+ * move text onto macro file, changing formal parameters
+ */
+#ifdef M_DEBUG
+ fprintf(stderr,"enter 'mlex'\t") ;
+#endif
+ inmlex++;
+
+ c = nextchar();
+loop {
+ switch(charclass[c]) {
+
+ case DIGIT:
+ while (numpart[c]) {
+ putm(c);
+ c = nextchar();
+ }
+ continue;
+
+ case STARTER:
+ case LETTER:
+ t = 0;
+ p = tempbuf+MAXSYMBOLSIZE+2;
+ do {
+ if (p >= tempmax)
+ error(symlong);
+ *p++ = c;
+ if (t < MAXSYMBOLSIZE)
+ tempbuf[t++] = (c >= 'A' && c <= 'Z') ?
+ c+'a'-'A' : c;
+ c = nextchar();
+ } while (charclass[c]==LETTER || charclass[c]==DIGIT);
+
+ tempbuf[t] = 0;
+ *p++ = '\0';
+ p = tempbuf+MAXSYMBOLSIZE+2;
+ t = tokenofitem(0);
+ if (t != MPARM) while (*p) putm(*p++);
+ else {
+ if (*(yylval.itemptr->i_string) == '?') putm('\2');
+ else putm('\1');
+ putm(yylval.itemptr->i_value + 'A');
+ }
+ if (t == ENDM) goto done;
+ continue;
+
+ case F_END:
+ if (expptr) {
+ popsi();
+ c = nextchar();
+ continue;
+ }
+
+ goto done;
+
+ default:
+ if (c == '\n') {
+ linecnt++;
+ }
+ if (c != '\1') putm(c);
+ c = nextchar();
+ }
+}
+
+ /*
+ * finish off the file entry
+ */
+done:
+ while(c != EOF && c != '\n' && c != '\0') c = nextchar();
+ linecnt++;
+ putm('\n');
+ putm('\n');
+ putm(0);
+
+ for (c=0; c<ITEMTABLESIZE; c++)
+ if (itemtab[c].i_token == MPARM) {
+ itemtab[c].i_token = UNDECLARED;
+ }
+ inmlex = 0;
+#ifdef M_DEBUG
+ fprintf(stderr,"exit 'mlex'\n") ;
+#endif
+}
+
+
+
+/*
+ * lexical analyser for the arguments of a macro call
+ */
+getarg()
+{
+ register int c;
+ register char *p;
+ static int comma;
+
+ *tempbuf = 0;
+ yylval.cval = tempbuf;
+ while(charclass[c = nextchar()] == SPACE);
+
+ switch(c) {
+
+ case '\0':
+ popsi();
+ case '\n':
+ case ';':
+ comma = 0;
+ return(skipline(c));
+
+ case ',':
+ if (comma) {
+ comma = 0;
+ return(',');
+ }
+ else {
+ comma++;
+ return(ARG);
+ }
+
+ case '\'':
+ p = tempbuf;
+ do switch (c = nextchar()) {
+ case '\0':
+ case '\n':
+ peekc = c;
+ *p = 0;
+ err[bflag]++;
+ return(ARG);
+ case '\'':
+ if ((c = nextchar()) != '\'') {
+ peekc = c;
+ *p = '\0';
+ comma++;
+ return(ARG);
+ }
+ default:
+ *p++ = c;
+ } while (p < tempmax);
+ error(symlong);
+
+ default: /* unquoted string */
+ p = tempbuf;
+ peekc = c;
+ do switch(c = nextchar()) {
+ case '\0':
+ case '\n':
+ case '\t':
+ case ' ':
+ case ',':
+ peekc = c;
+ *p = '\0';
+ comma++;
+ return(ARG);
+ default:
+ *p++ = c;
+ } while (p < tempmax);
+ }
+}
+
+
+
+
+
+/*
+ * add a suffix to a string
+ */
+suffix(str,suff)
+char *str,*suff;
+{
+ while(*str != '\0' && *str != '.')
+ *str++;
+ strcpy(str, suff);
+}
+
+
+
+
+/*
+ * put out a byte to the macro file, keeping the offset
+ */
+putm(c)
+char c ;
+{
+ mfptr++;
+ mfputc(c,mfile) ;
+}
+
+
+
+/*
+ * get a byte from the macro file
+ */
+getm()
+{
+ int ch;
+
+ floc++;
+ ch = mfgetc(mfile) ;
+ if (ch == EOF) {
+ ch = 0;
+ fprintf(stderr,"bad macro read\n") ;
+ }
+ return(ch);
+}
+
+
+
+/*
+ * pop standard input
+ */
+popsi()
+{
+ register i;
+
+ for (i=0; i<PARMMAX; i++) {
+ if (est[i]) free(est[i]);
+ }
+ floc = est[FLOC];
+ free(est);
+ expptr--;
+ est = expptr ? (char **) expstack[expptr-1] : (char **) 0;
+ mfseek(mfile, (long)floc, 0);
+ if (lineptr > linebuf) lineptr--;
+}
+
+
+
+/*
+ * return a unique name for a local symbol
+ * c is the parameter number, n is the macro number.
+ */
+
+char *
+getlocal(c, n)
+int c,n;
+{
+static char local_label[10];
+ invented++;
+ if (c >= 26)
+ c += 'a' - '0';
+ sprintf(local_label, "?%c%04d", c+'a', n) ;
+ return(local_label);
+}
+
+
+
+/*
+ * read in a symbol table
+ */
+insymtab(name)
+char *name;
+{
+ register struct stab *t;
+ int s, i, sfile;
+
+ t = (struct stab *) tempbuf;
+#ifdef MSDOS
+ if ((sfile = open(name, O_RDONLY | O_BINARY)) < 0)
+#else
+ if ((sfile = open(name, O_RDONLY)) < 0)
+#endif
+ return;
+ read(sfile, (char *)t, sizeof *t);
+ if (t->t_value != SYMMAJIC)
+ return;
+
+ s = t->t_token;
+ for (i=0; i<s; i++) {
+ read(sfile, (char *)t, sizeof *t);
+ if (tokenofitem(UNDECLARED) != UNDECLARED)
+ continue;
+ yylval.itemptr->i_token = t->t_token;
+ yylval.itemptr->i_value = t->t_value;
+ if (t->t_token == MACRO)
+ yylval.itemptr->i_value += mfptr;
+ }
+
+ while ((s = read(sfile, tempbuf, TEMPBUFSIZE)) > 0) {
+ mfptr += s;
+ mfwrite(tempbuf, 1, s, mfile) ;
+ }
+}
+
+
+
+/*
+ * write out symbol table
+ */
+outsymtab(name)
+char *name;
+{
+ register struct stab *t;
+ register struct item *ip;
+ int i, sfile;
+
+ t = (struct stab *) tempbuf;
+ if ((sfile = creat(name, 0644)) < 0)
+ return;
+ for (ip=itemtab; ip<itemmax; ip++) {
+ if (ip->i_token == UNDECLARED) {
+ ip->i_token = 0;
+ nitems--;
+ }
+ }
+
+ copyname(title, (char *)t);
+ t->t_value = SYMMAJIC;
+ t->t_token = nitems;
+ write(sfile, (char *)t, sizeof *t);
+
+ for (ip=itemtab; ip<itemmax; ip++) {
+ if (ip->i_token != 0) {
+ t->t_token = ip->i_token;
+ t->t_value = ip->i_value;
+ copyname(ip->i_string, (char *)t);
+ write(sfile, (char *)t, sizeof *t);
+ }
+ }
+
+ mfseek(mfile, (long)0, 0);
+ while((i = mfread(tempbuf, 1, TEMPBUFSIZE, mfile) ) > 0)
+ write(sfile, tempbuf, i);
+}
+
+
+
+/*
+ * copy a name into the symbol file
+ */
+copyname(st1, st2)
+char *st1, *st2;
+{
+ register char *s1, *s2;
+ register i;
+
+ i = (MAXSYMBOLSIZE+2) & ~01;
+ s1 = st1;
+ s2 = st2;
+
+ while(*s2++ = *s1++) i--;
+ while(--i > 0) *s2++ = '\0';
+}
+
+/* get the next source file */
+next_source(sp)
+char *sp ;
+{
+
+ if(now_in == NEST_IN -1)
+ error("Too many nested includes") ;
+ if ((now_file = fopen(sp, "r")) == NULL) {
+ char ebuf[100] ;
+ sprintf(ebuf,"Can't open include file: %s", sp) ;
+ error(ebuf) ;
+ }
+ if (pass2 && iflist()) {
+ lineout() ;
+ fprintf(fout, "**** %s ****\n",sp) ;
+ }
+
+ /* save the list control flag with the current line number */
+ if (lstoff)
+ linein[now_in] = - linein[now_in] ;
+
+ /* no list if include files are turned off */
+ lstoff |= iopt ;
+
+ /* save the new file descriptor. */
+ fin[++now_in] = now_file ;
+ /* start with line 0 */
+ linein[now_in] = 0 ;
+ /* save away the file name */
+ src_name[now_in] = malloc(strlen(sp)+1) ;
+ strcpy(src_name[now_in],sp) ;
+}