cc: initial Z80 support
authorAlan Cox <alan@linux.intel.com>
Thu, 23 Jun 2016 12:12:35 +0000 (13:12 +0100)
committerAlan Cox <alan@linux.intel.com>
Thu, 23 Jun 2016 12:12:35 +0000 (13:12 +0100)
20 files changed:
Applications/SmallC/6809/ccstart.u [new file with mode: 0644]
Applications/SmallC/6809/crunas09.u [new file with mode: 0644]
Applications/SmallC/6809/exit.u [new file with mode: 0644]
Applications/SmallC/6809/faults.u [new file with mode: 0644]
Applications/SmallC/6809/io.u [new file with mode: 0644]
Applications/SmallC/6809/mrabs.u [new file with mode: 0644]
Applications/SmallC/6809/prabs.u [new file with mode: 0644]
Applications/SmallC/6809/sdiv.u [new file with mode: 0644]
Applications/SmallC/6809/shift.u [new file with mode: 0644]
Applications/SmallC/6809/smod.u [new file with mode: 0644]
Applications/SmallC/6809/sumul.u [new file with mode: 0644]
Applications/SmallC/8080/arglist.c
Applications/SmallC/Makefile
Applications/SmallC/code6809.c
Applications/SmallC/code8080.c
Applications/SmallC/codez80.c [new file with mode: 0644]
Applications/SmallC/defs.h
Applications/SmallC/lib/Makefile [new file with mode: 0644]
Applications/SmallC/lib/lorder8080 [new file with mode: 0644]
Applications/SmallC/preproc.c

diff --git a/Applications/SmallC/6809/ccstart.u b/Applications/SmallC/6809/ccstart.u
new file mode 100644 (file)
index 0000000..ffeb176
--- /dev/null
@@ -0,0 +1,25 @@
+|       Run-time start off for ccv1 on the Physics 6809
+.globl  _edata
+.globl  _main
+| Initialize stack
+        lds     #/1000
+        ldx     #_edata | clear all of memory
+l2:     clr     (x)+
+        cmpx    #/0fff
+        bne     l2
+| Circumvent EPROM bug
+        ldx     #/ff3b
+        ldb     #6
+l1:     pshs    x
+        decb
+        bne l1
+|       clear everything so that start conds are
+|       always same
+        clra
+        clrb
+        tfr     a,dp
+        tfr     d,x
+        tfr     d,y
+        tfr     d,u
+        jsr     _main
+        jmp     /fc00
diff --git a/Applications/SmallC/6809/crunas09.u b/Applications/SmallC/6809/crunas09.u
new file mode 100644 (file)
index 0000000..4b20f81
--- /dev/null
@@ -0,0 +1,85 @@
+|       csa09 Small C v1 comparison support
+|       All are dyadic except for lneg.
+.globl  eq
+.globl  ne
+.globl  lt
+.globl  le
+.globl  gt
+.globl  ge
+.globl  ult
+.globl  ule
+.globl  ugt
+.globl  uge
+.globl  lneg
+.globl  bool
+.globl  _eend,_edata,_etext
+.globl  _Xstktop,_brkend
+
+eq:     cmpd 2(s)
+        lbeq true
+        lbra false
+
+ne:     cmpd 2(s)
+        lbne true
+        lbra false
+
+lt:     cmpd 2(s)
+        bgt true
+        bra false
+
+le:     cmpd 2(s)
+        bge true
+        bra false
+
+gt:     cmpd 2(s)
+        blt true
+        bra false
+
+ge:     cmpd 2(s)
+        ble true
+        bra false
+
+ult:    cmpd 2(s)
+        bhi true
+        bra false
+
+ule:    cmpd 2(s)
+        bhs true
+        bra false
+
+ugt:    cmpd 2(s)
+        blo true
+        bra false
+
+uge:    cmpd 2(s)
+        bls true
+        bra false
+
+lneg:   cmpd #0
+        beq ltrue
+        ldd #0
+        rts
+ltrue:  ldd #1
+        rts
+
+bool:   bsr     lneg
+        bra     lneg
+
+true:   ldd #1
+        ldx (s)
+        leas 4(s)
+        jmp (x)
+
+false:  clra
+        clrb
+        ldx (s)
+        leas 4(s)
+        jmp  (x)
+_Xstktop:       tfr     s,d
+        rts
+_etext  =       .
+        .bss
+_eend   =       .
+        .data
+_brkend:        .wval   _eend
+_edata  =       .
diff --git a/Applications/SmallC/6809/exit.u b/Applications/SmallC/6809/exit.u
new file mode 100644 (file)
index 0000000..423fd67
--- /dev/null
@@ -0,0 +1,3 @@
+|       Small C v1 exit routine (physics computer)
+.globl  _exit
+_exit:  jmp     /fc00
diff --git a/Applications/SmallC/6809/faults.u b/Applications/SmallC/6809/faults.u
new file mode 100644 (file)
index 0000000..6e7db80
--- /dev/null
@@ -0,0 +1,10 @@
+|       MC6809 Concurrent Euclid fault codes
+ASSERTFAIL = 0
+RANGECHECK = 1
+CASERANGE = 2
+| fault codes for runtime routines
+OUTOFSPACE = 20
+.globl ASSERTFAIL
+.globl RANGECHECK
+.globl CASERANGE
+.globl  OUTOFSPACE
diff --git a/Applications/SmallC/6809/io.u b/Applications/SmallC/6809/io.u
new file mode 100644 (file)
index 0000000..1f3a63f
--- /dev/null
@@ -0,0 +1,28 @@
+|       Small C v1 io (putchar) for physics machine
+.globl  _putchar
+_putchar=.
+        lda     /9000
+        bita    #2
+        beq     _putchar
+        lda     3(s)
+        sta     /9001
+        cmpa    #10.
+        bne     out
+        ldd     #13.
+        pshs    d
+        lbsr    _putchar
+        leas    2(s)
+out:    rts
+
+.globl  _getchar
+_getchar=.
+        lda     /9000
+        bita    #1
+        beq     _getchar
+        ldb     /9001
+        clra
+        andb    #/7F
+        cmpb    #04
+        bne     noteot
+        ldd     #-1
+noteot: rts
diff --git a/Applications/SmallC/6809/mrabs.u b/Applications/SmallC/6809/mrabs.u
new file mode 100644 (file)
index 0000000..97f0662
--- /dev/null
@@ -0,0 +1,26 @@
+|       mrabs.  converts both args to unsigned, and
+|       remembers result sign as the sign of the left
+|       argument.  (for signed modulo)
+|       result d contains right, sign is non-zero
+|       if result (from mod) should be negative.
+|
+|
+.globl mrabs
+        left=8.
+        right=4.
+        sign=3.
+mrabs:  clr     sign(s)
+        ldd     left(s)
+        bge     tryr
+        nega
+        negb
+        sbca    #0
+        std     left(s)
+        inc     sign(s)
+tryr:   ldd     right(s)
+        bge     done
+        nega
+        negb
+        sbca    #0
+        std     right(s)
+done:   rts
diff --git a/Applications/SmallC/6809/prabs.u b/Applications/SmallC/6809/prabs.u
new file mode 100644 (file)
index 0000000..40b6dc8
--- /dev/null
@@ -0,0 +1,27 @@
+|       prabs.  converts both args to unsigned, and
+|       remembers result sign as sign a eor sign b
+|       used only by divide support
+|       result d contains right, sign is non-zero
+|       if result (from divide) should be negative.
+|
+|
+.globl prabs
+        left=8.
+        right=4.
+        sign=3.
+prabs:  clr     sign(s)
+        ldd     left(s)
+        bge     tryr
+        nega
+        negb
+        sbca    #0
+        std     left(s)
+        inc     sign(s)
+tryr:   ldd     right(s)
+        bge     done
+        nega
+        negb
+        sbca    #0
+        dec     sign(s)
+        std     right(s)
+done:   rts
diff --git a/Applications/SmallC/6809/sdiv.u b/Applications/SmallC/6809/sdiv.u
new file mode 100644 (file)
index 0000000..3b17770
--- /dev/null
@@ -0,0 +1,55 @@
+|       signed divide
+|       calling: (left / right)
+|               push left
+|               ldd right
+|               jsr sdiv
+|       result in d, arg popped.
+|
+        left=6
+        right=2
+        sign=1
+        count=0
+        return=4
+        CARRY=1
+.globl sdiv,div,ASSERTFAIL
+.globl prabs
+sdiv:   leas    -4(s)
+        std     right(s)
+        bne     nozero
+        swi2
+        .byte   ASSERTFAIL
+nozero: jsr     prabs
+div:    clr     count(s)        | prescale divisor
+        inc     count(s)
+mscl:   inc     count(s)
+        aslb
+        rola
+        bpl     mscl
+        std     right(s)
+        ldd     left(s)
+        clr     left(s)
+        clr     left+1 <tel:+1>(s)
+div1:   subd    right(s)        | check subtract
+        bcc     div2
+        addd    right(s)
+        andcc   #~CARRY
+        bra     div3
+div2:   orcc    #CARRY
+div3:   rol     left+1 <tel:+1>(s)       | roll in carry
+        rol     left(s)
+        lsr     right(s)
+        ror     right+1 <tel:+1>(s)
+        dec     count(s)
+        bne     div1
+        ldd     left(s)
+        tst     sign(s)         | sign fiddle
+        beq     nochg
+        nega
+        negb
+        sbca    #0
+nochg:  std     right(s)        | move return addr
+        ldd     return(s)
+        std     left(s)
+        ldd     right(s)
+        leas    6(s)
+        rts
diff --git a/Applications/SmallC/6809/shift.u b/Applications/SmallC/6809/shift.u
new file mode 100644 (file)
index 0000000..0ced5ec
--- /dev/null
@@ -0,0 +1,32 @@
+|       Shift support for Small C v1 sa09
+.globl  asr
+asr:    tstb
+        bge     okr
+        negb
+        bra     asl
+okr:    incb
+        pshs    b
+        ldd     3(s)
+asrl:   dec     (s)
+        beq     return
+        asra
+        rorb
+        bra     asrl
+
+.globl  asl
+asl:    tstb
+        bge     okl
+        negb
+        bra     asr
+okl:    incb
+        pshs    b
+        ldd     3(s)
+asll:   dec     (s)
+        beq     return
+        aslb
+        rola
+        bra     asll
+
+return: ldx     1(s)
+        leas    5(s)
+        jmp     (x)
diff --git a/Applications/SmallC/6809/smod.u b/Applications/SmallC/6809/smod.u
new file mode 100644 (file)
index 0000000..737cb90
--- /dev/null
@@ -0,0 +1,54 @@
+|       signed mod
+|       calling: (left / right)
+|               push left
+|               ldd right
+|               jsr smod
+|       result in d, arg popped.
+|
+        left=6
+        right=2
+        sign=1
+        count=0
+        return=4
+        CARRY=1
+.globl smod,mod,ASSERTFAIL
+.globl mrabs
+smod:   leas    -4(s)
+        std     right(s)
+        bne     nozero
+        swi2
+        .byte   ASSERTFAIL
+nozero: jsr     mrabs
+mod:    clr     count(s)        | prescale divisor
+        inc     count(s)
+mscl:   inc     count(s)
+        aslb
+        rola
+        bpl     mscl
+        std     right(s)
+        ldd     left(s)
+        clr     left(s)
+        clr     left+1 <tel:+1>(s)
+mod1:   subd    right(s)        | check subtract
+        bcc     mod2
+        addd    right(s)
+        andcc   #~CARRY
+        bra     mod3
+mod2:   orcc    #CARRY
+mod3:   rol     left+1 <tel:+1>(s)       | roll in carry
+        rol     left(s)
+        lsr     right(s)
+        ror     right+1 <tel:+1>(s)
+        dec     count(s)
+        bne     mod1
+        tst     sign(s)         | sign fiddle
+        beq     nochg
+        nega
+        negb
+        sbca    #0
+nochg:  std     right(s)        | move return addr
+        ldd     return(s)
+        std     left(s)
+        ldd     right(s)
+        leas    6(s)
+        rts
diff --git a/Applications/SmallC/6809/sumul.u b/Applications/SmallC/6809/sumul.u
new file mode 100644 (file)
index 0000000..806c9ca
--- /dev/null
@@ -0,0 +1,32 @@
+|       signed/unsigned multiply
+|       calling (left * right)
+|       push left
+|       ldd right
+|       jsr [u|s]mul (same entry point)
+|       result in d, stack is popped
+.globl smul,umul
+smul=.
+umul:   pshs    d
+        lda     2+2 <tel:+2>(s)
+        mul             | left msb * right lsb
+        pshs    b       | save high order
+        ldb     -1+3 <tel:+3>(s) | right lsb
+        lda     3+3 <tel:+3>(s)  | left lsb
+        mul
+        pshs    d
+        lda     3+5 <tel:+5>(s)  | left lsb
+        ldb     -2+5 <tel:+5>(s) | right msb
+        beq     small   | is zero?
+        mul             | no, gotta do it too
+        tfr     b,a
+        clrb
+        addd    (s)++   | partial prod
+        bra     big
+small:  puls    d       | aha! don't need third mul
+big:    adda    (s)+
+        pshs    d
+        ldd     4(s)    | rearrange return address
+        std     6(s)
+        puls    d
+        leas    4(s)
+        rts
index f747b46..a0ac302 100644 (file)
@@ -10,7 +10,7 @@ int     Xargv[30];
 Xarglist(ap) char *ap; {
         char qc;
         Xargc = 0;
-        ap[(*ap)+1 <tel:+1>] = '\0';
+        ap[(*ap)+1] = '\0';
         ap++;
         while (isspace(*ap)) ap++;
         Xargv[Xargc++] = "arg0";
index 29b30e7..83c1160 100644 (file)
@@ -1,19 +1,26 @@
 .SUFFIXES: .c .rel
 
 CC = fcc
-CFLAGS = -DTINY -DM8080
+CFLAGS = -DTINY
 COPT = -O2
 
 OBJS = initials.rel data.rel error.rel expr.rel function.rel gen.rel io.rel lex.rel main.rel preproc.rel \
-       primary.rel stmt.rel sym.rel while.rel code6809.rel code8080.rel struct.rel
+       primary.rel stmt.rel sym.rel while.rel struct.rel
+
+OBJ_Z80 = codez80.rel
+OBJ_8080 = code8080.rel
 
 INC = data.h defs.h prototype.h
 
-all:    scc8080
+OBJS_ALL = $(OBJS) $(OBJ_Z80) $(OBJ_8080)
+all:    scc8080 sccz80
+
 
+sccz80: $(OBJS) $(OBJ_Z80)
+       $(CC) -o sccz80 --nostdio $(OBJS) $(OBJ_Z80)
 
-scc8080: $(OBJS)
-       $(CC) -o scc8080 --nostdio $(OBJS)
+scc8080: $(OBJS) $(OBJ_8080)
+       $(CC) -o scc8080 --nostdio $(OBJS) $(OBJ_8080)
 
 #scc6809: $(OBJS)
 #      $(CC) -o scc8080 --nostdio $(OBJS)
@@ -24,4 +31,4 @@ clean:
 .c.rel:
        $(CC) $(COPT) $(CFLAGS) -c $< -o $@
 
-$(OBJS) : $(INC)
+$(OBJS_ALL) : $(INC)
index b4762f7..a9c1730 100644 (file)
@@ -8,11 +8,6 @@
 #include "defs.h"
 #include "data.h"
 
-#ifdef M6809
-
-/*      Define ASNM and LDNM to the names of the assembler and linker
-        respectively */
-
 /*
  *      Some predefinitions:
  *
@@ -799,5 +794,3 @@ void gnargs(int d)
         newline();
 
 }
-
-#endif
index 847ff5c..8cac702 100644 (file)
@@ -7,11 +7,6 @@
 #include "defs.h"
 #include "data.h"
 
-#ifdef M8080
-
-/*      Define ASNM and LDNM to the names of the assembler and linker
-        respectively */
-
 /*
  *      Some predefinitions:
  *
@@ -795,4 +790,3 @@ void gen_multiply(int type, int size) {
     }
 }
 
-#endif
diff --git a/Applications/SmallC/codez80.c b/Applications/SmallC/codez80.c
new file mode 100644 (file)
index 0000000..0eb216d
--- /dev/null
@@ -0,0 +1,796 @@
+#include <stdio.h>
+#include "defs.h"
+#include "data.h"
+
+/*
+ *      Some predefinitions:
+ *
+ *      INTSIZE is the size of an integer in the target machine
+ *      BYTEOFF is the offset of an byte within an integer on the
+ *              target machine. (ie: 8080,pdp11 = 0, 6809 = 1,
+ *              360 = 3)
+ *      This compiler assumes that an integer is the SAME length as
+ *      a pointer - in fact, the compiler uses INTSIZE for both.
+ */
+
+/**
+ * print all assembler info before any code is generated
+ */
+void header (void) {
+    output_string ("; Small C Z80\n;\tCoder (ac0)\n;");
+    frontend_version();
+    newline ();
+    output_line ("\t;program area SMALLC_GENERATED is RELOCATABLE");
+    output_line ("\t.module SMALLC_GENERATED");
+    output_line ("\t.list   (err, loc, bin, eqt, cyc, lin, src, lst, md)");
+    output_line ("\t.nlist  (pag)");
+}
+
+/**
+ * prints new line
+ * @return 
+ */
+void newline (void) {
+#if __CYGWIN__ == 1
+    output_byte (CR);
+#endif
+    output_byte (LF);
+}
+
+void initmac(void) {
+    defmac("cpm\t1");
+    defmac("Z80\t1");
+    defmac("smallc\t1");
+}
+
+/**
+ * Output internal generated label prefix
+ */
+void output_label_prefix(void) {
+    output_byte('$');
+}
+
+/**
+ * Output a label definition terminator
+ */
+void output_label_terminator (void) {
+    output_byte (':');
+}
+
+/**
+ * begin a comment line for the assembler
+ */
+void gen_comment(void) {
+    output_byte (';');
+}
+
+/**
+ * print any assembler stuff needed after all code
+ */
+void trailer(void) {
+    output_line (";\t.end");
+}
+
+/**
+ * text (code) segment
+ */
+void code_segment_gtext(void) {
+    output_line ("\t.area  SMALLC_GENERATED  (REL,CON,CSEG)");
+}
+
+/**
+ * data segment
+ */
+void data_segment_gdata(void) {
+    output_line ("\t.area  SMALLC_GENERATED_DATA  (REL,CON,DSEG)");
+}
+
+/**
+ * Output the variable symbol at scptr as an extrn or a public
+ * @param scptr
+ */
+void ppubext(SYMBOL *scptr)  {
+    if (symbol_table[current_symbol_table_idx].storage == STATIC) return;
+    output_with_tab (scptr->storage == EXTERN ? ";extrn\t" : ".globl\t");
+    output_string (scptr->name);
+    newline();
+}
+
+/**
+ * Output the function symbol at scptr as an extrn or a public
+ * @param scptr
+ */
+void fpubext(SYMBOL *scptr) {
+    if (scptr->storage == STATIC) return;
+    output_with_tab (scptr->offset == FUNCTION ? ".globl\t" : ";extrn\t");
+    output_string (scptr->name);
+    newline ();
+}
+
+/**
+ * Output a decimal number to the assembler file, with # prefix
+ * @param num
+ */
+void output_number(int num) {
+    output_byte('#');
+    output_decimal(num);
+}
+
+static void output_bracketed(char *p)
+{
+    output_byte('(');
+    output_string(p);
+    output_byte(')');
+}
+
+/**
+ * fetch a static memory cell into the primary register
+ * @param sym
+ */
+void gen_get_memory(SYMBOL *sym) {
+    if ((sym->identity != POINTER) && (sym->type == CCHAR)) {
+        output_with_tab ("ld a,");
+        output_bracketed(sym->name);
+        newline ();
+        gen_call ("ccsxt");
+    } else if ((sym->identity != POINTER) && (sym->type == UCHAR)) {
+        output_with_tab("ld a,");
+        output_bracketed(sym->name);
+        newline();
+        output_line("ld l,a");
+        output_line("ld h,0");
+    } else {
+        output_with_tab ("ld hl,");
+        output_bracketed(sym->name);
+        newline ();
+    }
+}
+
+/**
+ * asm - fetch the address of the specified symbol into the primary register
+ * @param sym the symbol name
+ * @return which register pair contains result
+ */
+int gen_get_locale(SYMBOL *sym) {
+    if (sym->storage == LSTATIC) {
+        gen_immediate();
+        output_byte('(');
+        print_label(sym->offset);
+        output_byte(')');
+        newline();
+        return HL_REG;
+    } else {
+        if (uflag && !(sym->identity == ARRAY)) {// ||
+                //(sym->identity == VARIABLE && sym->type == STRUCT))) {
+            output_with_tab("ldsi\t");
+            output_number(sym->offset - stkp);
+            newline ();
+            return DE_REG;
+        } else {
+            gen_immediate();
+            output_number(sym->offset - stkp);
+            newline ();
+            output_line ("add hl, sp");
+            return HL_REG;
+        }
+    }
+}
+
+/**
+ * asm - store the primary register into the specified static memory cell
+ * @param sym
+ */
+void gen_put_memory(SYMBOL *sym) {
+    if ((sym->identity != POINTER) && (sym->type & CCHAR)) {
+        output_line ("ld a,l");
+        output_with_tab ("ld ");
+        output_bracketed(sym->name);
+        output_string(",a");
+    } else {
+        output_with_tab("ld ");
+        output_bracketed(sym->name);
+        output_string(",hl");
+    }
+    newline ();
+}
+
+/**
+ * store the specified object type in the primary register
+ * at the address in secondary register (on the top of the stack)
+ * @param typeobj
+ */
+void gen_put_indirect(char typeobj) {
+    gen_pop ();
+    if (typeobj & CCHAR) {
+        //gen_call("ccpchar");
+        output_line("ld l,a");
+        output_line("ld (de),a");
+    } else {
+        gen_call("ccpint");
+    }
+}
+
+/**
+ * fetch the specified object type indirect through the primary
+ * register into the primary register
+ * @param typeobj object type
+ */
+void gen_get_indirect(char typeobj, int reg) {
+    if (typeobj == CCHAR) {
+        if (reg & DE_REG) {
+            gen_swap();
+        }
+        gen_call("ccgchar");
+    } else if (typeobj == UCHAR) {
+        if (reg & DE_REG) {
+            gen_swap();
+        }
+        //gen_call("cguchar");
+        output_line("ld l,(hl)");
+        output_line("ld h,0");
+    } else { // int
+        if (uflag) {
+            if (reg & HL_REG) {
+                gen_swap();
+            }
+            output_line("lhlx");
+        } else {
+            output_line("ld a,(hl)");
+            output_line("inc hl");
+            output_line("ld h,(hl)");
+            output_line("ld l,a");
+        }
+    }
+}
+
+/**
+ * swap the primary and secondary registers
+ */
+void gen_swap(void) {
+    output_line("ex de,hl");
+}
+
+/**
+ * print partial instruction to get an immediate value into
+ * the primary register
+ */
+void gen_immediate(void) {
+    output_with_tab ("ld hl,");
+}
+
+/**
+ * push the primary register onto the stack
+ */
+void gen_push(int reg) {
+    if (reg & DE_REG) {
+        output_line ("push de");
+        stkp = stkp - INTSIZE;
+    } else {
+        output_line ("push hl");
+        stkp = stkp - INTSIZE;
+    }
+}
+
+/**
+ * pop the top of the stack into the secondary register
+ */
+void gen_pop(void) {
+    output_line ("pop de");
+    stkp = stkp + INTSIZE;
+}
+
+/**
+ * swap the primary register and the top of the stack
+ */
+void gen_swap_stack(void) {
+    output_line ("ex (sp),hl");
+}
+
+/**
+ * call the specified subroutine name
+ * @param sname subroutine name
+ */
+void gen_call(char *sname) {
+    output_with_tab ("call ");
+    output_string (sname);
+    newline ();
+}
+
+/**
+ * declare entry point
+ */
+void declare_entry_point(char *symbol_name) {
+    output_string(symbol_name);
+    output_label_terminator();
+    //newline();
+}
+
+/**
+ * return from subroutine
+ */
+void gen_ret(void) {
+    output_line ("ret");
+}
+
+/**
+ * perform subroutine call to value on top of stack
+ */
+void callstk(void) {
+    gen_immediate ();
+    output_string ("#.+5");
+    newline ();
+    gen_swap_stack ();
+    output_line ("jp (hl)");
+    stkp = stkp + INTSIZE;
+}
+
+/**
+ * jump to specified internal label number
+ * @param label the label
+ */
+void gen_jump(int label)
+{
+    output_with_tab ("jp ");
+    print_label (label);
+    newline ();
+}
+
+/**
+ * test the primary register and jump if false to label
+ * @param label the label
+ * @param ft if true jnz is generated, jz otherwise
+ */
+void gen_test_jump(int label, int ft)
+{
+    output_line ("ld a,h");
+    output_line ("or l");
+    if (ft)
+        output_with_tab ("jp nz,");
+    else
+        output_with_tab ("jp z,");
+    print_label (label);
+    newline ();
+}
+
+/**
+ * print pseudo-op  to define a byte
+ */
+void gen_def_byte(void) {
+    output_with_tab (".db ");
+}
+
+/**
+ * print pseudo-op to define storage
+ */
+void gen_def_storage(void) {
+    output_with_tab (".ds ");
+}
+
+/**
+ * print pseudo-op to define a word
+ */
+void gen_def_word(void) {
+    output_with_tab (".dw ");
+}
+
+/**
+ * modify the stack pointer to the new value indicated
+ * @param newstkp new value
+ */
+int gen_modify_stack(int newstkp) {
+    int k;
+
+    k = newstkp - stkp;
+    if (k == 0)
+        return (newstkp);
+    if (k > 0) {
+        if (k < 7) {
+            if (k & 1) {
+                output_line ("inc sp");
+                k--;
+            }
+            while (k) {
+                output_line ("pop bc");
+                k = k - INTSIZE;
+            }
+            return (newstkp);
+        }
+    } else {
+        if (k > -7) {
+            if (k & 1) {
+                output_line ("dec sp");
+                k++;
+            }
+            while (k) {
+                output_line ("pop bc");
+                k = k + INTSIZE;
+            }
+            return (newstkp);
+        }
+    }
+    gen_swap ();
+    gen_immediate ();
+    output_number (k);
+    newline ();
+    output_line ("dec sp");
+    output_line ("ld sp, hl");
+    gen_swap ();
+    return (newstkp);
+}
+
+/**
+ * multiply the primary register by INTSIZE
+ */
+void gen_multiply_by_two(void) {
+    output_line ("add hl,hl");
+}
+
+/**
+ * divide the primary register by INTSIZE, never used
+ */
+void gen_divide_by_two(void) {
+    gen_push(HL_REG);        /* push primary in prep for gasr */
+    gen_immediate ();
+    output_number (1);
+    newline ();
+    gen_arithm_shift_right ();  /* divide by two */
+}
+
+/**
+ * Case jump instruction
+ */
+void gen_jump_case(void) {
+    output_with_tab ("jp cccase");
+    newline ();
+}
+
+/**
+ * add the primary and secondary registers
+ * if lval2 is int pointer and lval is not, scale lval
+ * @param lval
+ * @param lval2
+ */
+void gen_add(LVALUE *lval, LVALUE *lval2) {
+    gen_pop ();
+    if (dbltest (lval2, lval)) {
+        gen_swap ();
+        gen_multiply_by_two();
+        gen_swap ();
+    }
+    output_line ("add hl,de");
+}
+
+/**
+ * subtract the primary register from the secondary
+ */
+void gen_sub(void) {
+    gen_pop ();
+    gen_call ("ccsub");
+}
+
+/**
+ * multiply the primary and secondary registers (result in primary)
+ */
+void gen_mult(void) {
+    gen_pop();
+    gen_call ("ccmul");
+}
+
+/**
+ * divide the secondary register by the primary
+ * (quotient in primary, remainder in secondary)
+ */
+void gen_div(void) {
+    gen_pop();
+    gen_call ("ccdiv");
+}
+
+/**
+ * unsigned divide the secondary register by the primary
+ * (quotient in primary, remainder in secondary)
+ */
+void gen_udiv(void) {
+    gen_pop();
+    gen_call ("ccudiv");
+}
+
+/**
+ * compute the remainder (mod) of the secondary register
+ * divided by the primary register
+ * (remainder in primary, quotient in secondary)
+ */
+void gen_mod(void) {
+    gen_div ();
+    gen_swap ();
+}
+
+/**
+ * compute the remainder (mod) of the secondary register
+ * divided by the primary register
+ * (remainder in primary, quotient in secondary)
+ */
+void gen_umod(void) {
+    gen_udiv ();
+    gen_swap ();
+}
+
+/**
+ * inclusive 'or' the primary and secondary registers
+ */
+void gen_or(void) {
+    gen_pop();
+    gen_call ("ccor");
+}
+
+/**
+ * exclusive 'or' the primary and secondary registers
+ */
+void gen_xor(void) {
+    gen_pop();
+    gen_call ("ccxor");
+}
+
+/**
+ * 'and' the primary and secondary registers
+ */
+void gen_and(void) {
+    gen_pop();
+    gen_call ("ccand");
+}
+
+/**
+ * arithmetic shift right the secondary register the number of
+ * times in the primary register (results in primary register)
+ */
+void gen_arithm_shift_right(void) {
+    gen_pop();
+    gen_call ("ccasr");
+}
+
+/**
+ * logically shift right the secondary register the number of
+ * times in the primary register (results in primary register)
+ */
+void gen_logical_shift_right(void) {
+    gen_pop();
+    gen_call ("cclsr");
+}
+
+/**
+ * arithmetic shift left the secondary register the number of
+ * times in the primary register (results in primary register)
+ */
+void gen_arithm_shift_left(void) {
+    gen_pop ();
+    gen_call ("ccasl");
+}
+
+/**
+ * two's complement of primary register
+ */
+void gen_twos_complement(void) {
+    gen_call ("ccneg");
+}
+
+/**
+ * logical complement of primary register
+ */
+void gen_logical_negation(void) {
+    gen_call ("cclneg");
+}
+
+/**
+ * one's complement of primary register
+ */
+void gen_complement(void) {
+    gen_call ("cccom");
+}
+
+/**
+ * Convert primary value into logical value (0 if 0, 1 otherwise)
+ */
+void gen_convert_primary_reg_value_to_bool(void) {
+    gen_call ("ccbool");
+}
+
+/**
+ * increment the primary register by 1 if char, INTSIZE if int
+ */
+void gen_increment_primary_reg(LVALUE *lval) {
+    switch (lval->ptr_type) {
+        case STRUCT:
+            gen_immediate2();
+            output_number(lval->tagsym->size);
+            newline();
+            output_line("add hl,de");
+            break ;
+        case CINT:
+        case UINT:
+            output_line("inc hl");
+        default:
+            output_line("inc hl");
+            break;
+    }
+}
+
+/**
+ * decrement the primary register by one if char, INTSIZE if int
+ */
+void gen_decrement_primary_reg(LVALUE *lval) {
+    output_line("dec hl");
+    switch (lval->ptr_type) {
+        case CINT:
+        case UINT:
+            output_line("dec hl");
+            break;
+        case STRUCT:
+            gen_immediate2();
+            output_number(lval->tagsym->size - 1);
+            newline();
+            // two's complement
+            output_line("ld a,d");
+            output_line("cpl");
+            output_line("ld d,a");
+            output_line("ld a,e");
+            output_line("cpl");
+            output_line("ld e,a");
+            output_line("inc de");
+            // substract
+            output_line("add hl,de");
+            break ;
+        default:
+            break;
+    }
+}
+
+/**
+ * following are the conditional operators.
+ * they compare the secondary register against the primary register
+ * and put a literal 1 in the primary if the condition is true,
+ * otherwise they clear the primary register
+ */
+
+/**
+ * equal
+ */
+void gen_equal(void) {
+    gen_pop();
+    gen_call ("cceq");
+}
+
+/**
+ * not equal
+ */
+void gen_not_equal(void) {
+    gen_pop();
+    gen_call ("ccne");
+}
+
+/**
+ * less than (signed)
+ */
+void gen_less_than(void) {
+    gen_pop();
+    gen_call ("cclt");
+}
+
+/**
+ * less than or equal (signed)
+ */
+void gen_less_or_equal(void) {
+    gen_pop();
+    gen_call ("ccle");
+}
+
+/**
+ * greater than (signed)
+ */
+void gen_greater_than(void) {
+    gen_pop();
+    gen_call ("ccgt");
+}
+
+/**
+ * greater than or equal (signed)
+ */
+void gen_greater_or_equal(void) {
+    gen_pop();
+    gen_call ("ccge");
+}
+
+/**
+ * less than (unsigned)
+ */
+void gen_unsigned_less_than(void) {
+    gen_pop();
+    gen_call ("ccult");
+}
+
+/**
+ * less than or equal (unsigned)
+ */
+void gen_unsigned_less_or_equal(void) {
+    gen_pop();
+    gen_call ("ccule");
+}
+
+/**
+ * greater than (unsigned)
+ */
+void gen_usigned_greater_than(void) {
+    gen_pop();
+    gen_call ("ccugt");
+}
+
+/**
+ * greater than or equal (unsigned)
+ */
+void gen_unsigned_greater_or_equal(void) {
+    gen_pop();
+    gen_call ("ccuge");
+}
+
+char *inclib(void) {
+#ifdef  cpm
+        return("B:");
+#endif
+#ifdef  unix
+#ifdef  INCDIR
+        return(INCDIR);
+#else
+        return "";
+#endif
+#endif
+}
+
+/**
+ * Squirrel away argument count in a register that modstk doesn't touch.
+ * @param d
+ */
+void gnargs(int d)
+{
+    output_with_tab ("ld a,");
+    output_number(d);
+    newline ();
+}
+
+/**
+ * print partial instruction to get an immediate value into
+ * the secondary register
+ */
+void gen_immediate2(void) {
+    output_with_tab ("ld de,");
+}
+
+/**
+ * add offset to primary register
+ * @param val the value
+ */
+void add_offset(int val) {
+    gen_immediate2();
+    output_number(val);
+    newline();
+    output_line ("add hl,de");
+}
+
+/**
+ * multiply the primary register by the length of some variable
+ * @param type
+ * @param size
+ */
+void gen_multiply(int type, int size) {
+       switch (type) {
+        case CINT:
+        case UINT:
+            gen_multiply_by_two();
+            break;
+        case STRUCT:
+            gen_immediate2();
+            output_number(size);
+            newline();
+            gen_call("ccmul");
+            break ;
+        default:
+            break;
+    }
+}
index c6fbc22..bef33a9 100644 (file)
@@ -2,10 +2,8 @@
  * File defs.h: 2.1 (83/03/21,02:07:20)
  */
 
-// Intel 8080 architecture defs
-#if defined(M6809) || defined(M8080)
+// Intel 8080 / Z80 architecture defs
 #define INTSIZE 2
-#endif
 
 // miscellaneous
 #define FOREVER for(;;)
diff --git a/Applications/SmallC/lib/Makefile b/Applications/SmallC/lib/Makefile
new file mode 100644 (file)
index 0000000..37c767a
--- /dev/null
@@ -0,0 +1,34 @@
+.SUFFIXES:      .o .obj .c .asm
+
+.c.o:
+        ../src/sccvax $*.c
+        as -o $*.o $*.s
+        rm $*.s
+ASSEMS =\
+        abs.asm        atoi.asm       binary.asm\
+        charclass.asm  fgets.asm      fputs.asm\
+        getchar.asm    gets.asm       index.asm\
+        itoa.asm       printn.asm     putchar.asm\
+        puts.asm       reverse.asm    shell.asm\
+        strcat.asm     strcmp.asm     strcpy.asm\
+        strlen.asm     rand.asm \
+        strncat.asm strncmp.asm strncpy.asm
+
+OBJ =\
+        abs.o        atoi.o       binary.o\
+        charclass.o  fgets.o      fputs.o\
+        getchar.o    gets.o       index.o\
+        itoa.o       printn.o     putchar.o\
+        puts.o       reverse.o    shell.o\
+        strcat.o     strcmp.o     strcpy.o\
+        strlen.o     rand.o \
+        strncat.o strncmp.o strncpy.o
+.c.asm:
+        ../src/scc8080 $*.c
+        mv $*.s $*.asm
+
+all:    $(ASSEMS)
+
+vaxlibc.a:      $(OBJ)
+        ar ur vaxlibc.a  $(OBJ)
+        ranlib vaxlibc.a
diff --git a/Applications/SmallC/lib/lorder8080 b/Applications/SmallC/lib/lorder8080
new file mode 100644 (file)
index 0000000..e36c585
--- /dev/null
@@ -0,0 +1,12 @@
+grep public $* | sed 's/:       public//
+/?/d
+s?\([^  ]*\)[    ]*\(.*\)?\2    \1?
+s/\.asm//'> /tmp/symdef$$
+grep extrn $* | sed 's/:        extrn//
+s/\.asm//
+s?\([^  ]*\)[    ]*\(.*\)?\2    \1?
+/?/d'   > /tmp/symref$$
+sort /tmp/symdef$$ -o /tmp/symdef$$
+sort /tmp/symref$$ -o /tmp/symref$$
+join /tmp/symref$$ /tmp/symdef$$ | sed 's/[^    ]* *//'
+rm /tmp/symdef$$ /tmp/symref$$
index a00ec38..a18875d 100644 (file)
@@ -34,8 +34,12 @@ int fix_include_name (void) {
         *(--ibp) = 0;
         fp = -1;
         if (c1 == '<' || ((fp = open(buf, O_RDONLY)) != -1)) {
+#ifndef __linux__
                 strcpy(buf2, DEFLIB);
                 strlcat(buf2, buf, sizeof(buf2));
+#else
+                snprintf(buf2, sizeof(buf2), "%s%s", DEFLIB, buf);
+#endif                
                 fp = open(buf2, O_RDONLY);
         }
         return (fp);