changeset 30:c0c2e99b6bb0

fixed negative rel8 address bug in assembler
author james <jb302@eecs.qmul.ac.uk>
date Tue, 15 Apr 2014 12:21:22 +0100
parents 83e80c2c489c
children 7a35e6ae1c36
files .cli.py.swp asm/language.py asm/language.pyc bin/emu cli.py dbg/dbg.pyc doc/general/ede.lyx doc/general/ede.lyx~ emu/.iset.c.swp emu/.mem.c.swp emu/.mem.h.swp emu/iset.c emu/mem.c emu/mem.h tests/emu/a.out tests/emu/test.c
diffstat 16 files changed, 319 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
Binary file .cli.py.swp has changed
--- a/asm/language.py	Sun Apr 13 22:42:57 2014 +0100
+++ b/asm/language.py	Tue Apr 15 12:21:22 2014 +0100
@@ -332,7 +332,10 @@
             else:
                 sym.append('addr')
                 fmt = '>H'
-            val = stoi(a)
+            if is_neg == 1:
+                val = stoi('-' + a)
+            else:
+                val = stoi(a)
             data = data + struct.pack(fmt, val)
             continue
         # immediate ints (signed when negative)
Binary file asm/language.pyc has changed
Binary file bin/emu has changed
--- a/cli.py	Sun Apr 13 22:42:57 2014 +0100
+++ b/cli.py	Tue Apr 15 12:21:22 2014 +0100
@@ -19,7 +19,7 @@
         'SPH':5,
         'PCH':6,
         'TMPH':7,
-        'RO_1':8,
+        'R0_1':8,
         'R1_1':9,
         'R2_1':10,
         'R3_1':11,
@@ -73,7 +73,7 @@
             print 'invalid instruction'
             continue
         
-        print hex(pcl | (pch << 8)), [hex(b) for b in byte_array]
+        print 'PC -> ', hex(pcl | (pch << 8)), [hex(b) for b in byte_array]
         # write to emu memory and execute
         emu.set_block(pch, pcl, byte_array)
         emu.step()
@@ -102,38 +102,39 @@
         cmd = inp[0]
         args = []
     
-        #try:
-        # deal with inline execution independently
-        if cmd == 'exc':
-            exc()
-            continue
+        try:
+            # deal with inline execution independently
+            if cmd == 'exc':
+                exc()
+                continue
 
-        # set block has unique argument syntax
-        if cmd == 'sb':
-            args.append(int(inp[1], 0))
-            args.append(int(inp[2], 0))
-            args.append([int(x, 0) for x in inp[3:]])
-            cmds[cmd](*args)
+            # set block has unique argument syntax
+            if cmd == 'sb':
+                args.append(int(inp[1], 0))
+                args.append(int(inp[2], 0))
+                args.append([int(x, 0) for x in inp[3:]])
+                cmds[cmd](*args)
+                continue
+                
+            # decode args
+            i = 0
+            for word in inp[1:]:
+                if word in syms.keys():
+                    args.append(syms[word])
+                # only arguments after 3 will be data for set block
+                # this needs to be in a list
+                else:
+                    args.append(int(word, 0))
+                i = i + 1
+            
+            resp = cmds[cmd](*args)
+            if resp == None:
+                continue
+            else:
+                print [hex(struct.unpack('>B', x)[0]) for x in resp]
+
+        except Exception, e:
+            print e
+            print 'invalid command or argument syntax'
             continue
             
-        # decode args
-        i = 0
-        for word in inp[1:]:
-            if word in syms.keys():
-                args.append(syms[word])
-            # only arguments after 3 will be data for set block
-            # this needs to be in a list
-            else:
-                args.append(int(word, 0))
-            i = i + 1
-        
-        resp = cmds[cmd](*args)
-        if resp == None:
-            continue
-        else:
-            print [hex(struct.unpack('>B', x)[0]) for x in resp]
-
-        #except:
-        #    print 'invalid command or argument syntax'
-        #    continue
-            
Binary file dbg/dbg.pyc has changed
--- a/doc/general/ede.lyx	Sun Apr 13 22:42:57 2014 +0100
+++ b/doc/general/ede.lyx	Tue Apr 15 12:21:22 2014 +0100
@@ -329,6 +329,14 @@
 Assembler
 \end_layout
 
+\begin_layout Section
+Assembler Overview
+\end_layout
+
+\begin_layout Section
+Assembler Implementation
+\end_layout
+
 \begin_layout Standard
 The assembler is written in pure Python 2 using only the standard library.
  It assembles the assembly the language described in the ELB816 specification
@@ -449,8 +457,8 @@
  However it must be noted that these are abstract and high level descriptions
  that do not fully explain minor routines, but give an overview of the entire
  process.
- The full source code is attached in the Appendix and should be referenced
- for a deeper understanding of the program's operation.
+ The full commented source code is attached provided with the supporting
+ and should be referenced for a deeper understanding of the program's operation.
  The final section is a short programmers manual demonstrating the assembler's
  features.
 \end_layout
@@ -462,7 +470,7 @@
 
 \end_layout
 
-\begin_layout Section
+\begin_layout Subsection
 Data Structures
 \end_layout
 
@@ -735,7 +743,7 @@
 
 \end_layout
 
-\begin_layout Section
+\begin_layout Subsection
 Functions
 \end_layout
 
@@ -1148,7 +1156,7 @@
 
 \end_layout
 
-\begin_layout Subsection
+\begin_layout Subsubsection
 \begin_inset listings
 lstparams "basicstyle={\ttfamily}"
 inline true
@@ -1371,7 +1379,7 @@
 
 \end_layout
 
-\begin_layout Subsection
+\begin_layout Subsubsection
 \begin_inset listings
 lstparams "basicstyle={\ttfamily}"
 inline true
@@ -1573,7 +1581,7 @@
 
 \end_layout
 
-\begin_layout Subsection
+\begin_layout Subsubsection
 \begin_inset listings
 lstparams "basicstyle={\ttfamily}"
 inline true
@@ -1622,7 +1630,7 @@
 
 \end_layout
 
-\begin_layout Subsection
+\begin_layout Subsubsection
 \begin_inset listings
 lstparams "basicstyle={\ttfamily}"
 inline true
@@ -1671,27 +1679,20 @@
 
 \end_layout
 
-\begin_layout Section
-Assembly language manual
-\end_layout
-
-\begin_layout Standard
-\begin_inset Newpage newpage
-\end_inset
-
-
-\end_layout
-
 \begin_layout Part
 Emulator
 \end_layout
 
 \begin_layout Section
-Core microprocessor emulation
+Emulator Overview
 \end_layout
 
+\begin_layout Section
+Core microprocessor implementation
+\end_layout
+
 \begin_layout Standard
-The core of the emulator is written in C using only standard libraries.
+The core of the emulator is written in C89 using only standard libraries.
  It executes the machine code output by the assembler according to the ELB816
  specification.
  It consists of the following files:
@@ -1772,7 +1773,7 @@
 
 \begin_layout Plain Layout
 
-emu.c
+main.c
 \end_layout
 
 \end_inset
@@ -1797,7 +1798,20 @@
  function.
  It initializes the emulator and executes the programs fetch/decode/execute
  cycle.
- 
+ It also contains the programs 
+\begin_inset listings
+lstparams "basicstyle={\ttfamily}"
+inline true
+status open
+
+\begin_layout Plain Layout
+
+dbgi()
+\end_layout
+
+\end_inset
+
+ function, which deals with emulator control and communication.
 \end_layout
 
 \begin_layout Standard
@@ -1915,8 +1929,7 @@
 \end_layout
 
 \begin_layout Standard
-The figures bellow illustrate the emulator's memory layout as defined in
- the 
+The 
 \begin_inset listings
 lstparams "basicstyle={\ttfamily}"
 inline true
@@ -1929,7 +1942,8 @@
 
 \end_inset
 
- header file.
+ header file describes the emulators internal memory structure and makes
+ this structure available the rest the code.
 \end_layout
 
 \begin_layout Standard
@@ -1980,7 +1994,7 @@
 
 \begin_layout Plain Layout
 
-emu.c
+main.c
 \end_layout
 
 \end_inset
@@ -2013,8 +2027,20 @@
 \begin_layout Standard
 It first executes a number of initialization procedures and then passes
  control over to the main fetch/decode/execute cycle.
- This procedure is shown below as a flowchart.
- To understand this it you must be familiar with C's function pointer syntax.
+ Every cycle it calls the 
+\begin_inset listings
+lstparams "basicstyle={\ttfamily}"
+inline true
+status open
+
+\begin_layout Plain Layout
+
+dbgi()
+\end_layout
+
+\end_inset
+
+
 \end_layout
 
 \begin_layout Standard
@@ -2034,37 +2060,14 @@
 \end_layout
 
 \begin_layout Standard
-\begin_inset ERT
-status open
-
-\begin_layout Plain Layout
-
-
-\backslash
-centerline{
+\begin_inset Newpage newpage
+\end_inset
+
+
 \end_layout
 
-\end_inset
-
-
-\begin_inset Graphics
-	filename /home/jmz/qm/ede/doc/images/emulator/fetch_decode_exe.svg
-	scale 70
-
-\end_inset
-
-
-\begin_inset ERT
-status open
-
-\begin_layout Plain Layout
-
-}
-\end_layout
-
-\end_inset
-
-
+\begin_layout Section
+Peripheral Design
 \end_layout
 
 \begin_layout Standard
@@ -2074,16 +2077,5 @@
 
 \end_layout
 
-\begin_layout Section
-Peripherals
-\end_layout
-
-\begin_layout Standard
-\begin_inset Newpage newpage
-\end_inset
-
-
-\end_layout
-
 \end_body
 \end_document
--- a/doc/general/ede.lyx~	Sun Apr 13 22:42:57 2014 +0100
+++ b/doc/general/ede.lyx~	Tue Apr 15 12:21:22 2014 +0100
@@ -605,7 +605,7 @@
 
 \begin_layout Plain Layout
 
-mneumonic: (arg type, arg type, ...): [opcode, width]
+mnemonic: (arg type, arg type, ...): [opcode, width]
 \end_layout
 
 \end_inset
Binary file emu/.iset.c.swp has changed
Binary file emu/.mem.c.swp has changed
Binary file emu/.mem.h.swp has changed
--- a/emu/iset.c	Sun Apr 13 22:42:57 2014 +0100
+++ b/emu/iset.c	Tue Apr 15 12:21:22 2014 +0100
@@ -214,7 +214,7 @@
                 /* 0b00100nnn - MOV @DPTR, Rn*/
                 case 0x20:
                     set_wide(TMP, get_wide(DPTR));
-                    set_reg(NNN, mem[get_wide(TMP)]);
+                    mem[get_wide(TMP)] = get_reg(NNN);
                     break;
                 
                 /* 0b00101nnn - immediate movs - MOV Rn, #data8*/
@@ -227,7 +227,7 @@
                     set_reg(NNN, A);
                     break;
                 
-                /* 0b00111nnn */
+                /* 0b00111nnn MOV A, Rn */
                 case 0x38:
                     A = get_reg(NNN);
                     break;
@@ -237,7 +237,8 @@
                 }
             break;;
         
-        /* 0b01mmmnnn */
+        /* 0b01mmmnnn MOV Rm Rn
+         *   if m == n: MOV Rm, @DPTR */
         case 0x40:
             if (NNN == MMM) {
                 set_wide(TMP, get_wide(DPTR));
@@ -253,17 +254,92 @@
     }
 }
 
+
+/* 0x80 - ANL A, R0
+ * 0x81 - ANL A, R1
+ * 0x82 - ANL A, R2
+ * 0x83 - ANL A, R3
+ * 0x84 - ANL A, DPH
+ * 0x85 - ANL A, DPL
+ * 0x86 - ANL A, #data8
+ * 0x87 - ANL A, @DPTR */
 void
 ANL(void) {
+    if (NNN < 6) {
+        A = A & get_reg(NNN);
+    }
+    else {
+        switch (NNN) {
+            
+            case 6:
+                A = A & fetch();
+                break;
+
+            case 7:
+                set_wide(TMP, get_wide(DPTR));
+                A = A & mem[TMP];
+                break;
+        }
+    }
+    set_zp(A);
 }
 
+/* 0x88 - ORL A, R0
+ * 0x89 - ORL A, R1
+ * 0x8A - ORL A, R2
+ * 0x8B - ORL A, R3
+ * 0x8C - ORL A, DPH
+ * 0x8D - ORL A, DPL
+ * 0x8E - ORL A, #data8
+ * 0x8F - ORL A, @DPTR */
 void
 ORL(void) {
+    if (NNN < 6) {
+        A = A | get_reg(NNN);
+    }
+    else {
+        switch (NNN) {
+            
+            case 6:
+                A = A | fetch();
+                break;
+
+            case 7:
+                set_wide(TMP, get_wide(DPTR));
+                A = A | mem[TMP];
+                break;
+        }
+    }
+    set_zp(A);
 }
 
+/* 0x90 - XRL A, R0
+ * 0x91 - XRL A, R1
+ * 0x92 - XRL A, R2
+ * 0x93 - XRL A, R3
+ * 0x94 - XRL A, DPH
+ * 0x95 - XRL A, DPL
+ * 0x96 - XRL A, #data8
+ * 0x97 - XRL A, @DPTR */
 void
 XRL(void) {
+    if (NNN < 6) {
+        A = A ^ get_reg(NNN);
+    }
+    else {
+        switch (NNN) {
+            
+            case 6:
+                A = A ^ fetch();
+                break;
 
+            case 7:
+                set_wide(TMP, get_wide(DPTR));
+                A = A ^ mem[TMP];
+                break;
+        }
+    }
+    set_zp(A);
 }
 
 /* 0x98 - RL A */
@@ -275,7 +351,9 @@
 /* 0x99 - RLC A */
 void
 RLC(void) {
-    /* implement me */
+     tmpb = A;
+     A = (A << 1) | get_flag(C);
+     set_flag(C, tmpb >> 7);
 }
 
 /* 0x9A - RR A */
@@ -287,32 +365,129 @@
 /* 0x9B - RRC A */
 void
 RRC(void) { 
-    /* implement me */
+    tmpb = A;
+    A = (A >> 1) | (get_flag(C) << 7);
+    set_flag(C, tmpb & 0x01);
 }
 
 /* 0x9C - INC DPTR
  * 0x9E - INC A */
 void
-INC(void) {    
+INC(void) {
+    switch (IR) {
+
+        case 0x9C:
+            tmpw = get_wide(DPTR);
+            if ((tmpw + 1) > 0xFFFF) {
+                set_flag(OV, 1);
+            }
+            set_wide(DPTR, tmpw + 1);
+            set_zp(DPL);
+            set_zp(DPH);
+            break;
+
+        case 0x9E:
+            if ((A + 1) > 0xFF) {
+                set_flag(OV, 1);
+            }
+            A++;
+            set_zp(A);
+
+    }
 }
 
 /* 0x9D - DEC DPTR
  * 0x9F - DEC A */
 void
 DEC(void) {
+    switch (IR) {
+
+        case 0x9D:
+            tmpw = get_wide(DPTR);
+            if ((tmpw - 1) < 0) {
+                set_flag(OV, 1);
+            }
+            set_wide(DPTR, tmpw - 1);
+            set_zp(DPL);
+            set_zp(DPH);
+
+        case 0x9F:
+            if ((A - 1) < 0) {
+                set_flag(OV, 1);
+            }
+            A--;
+            set_zp(A);
+    }    
 }
 
+/* 0xA0 - ADD A, R0
+ * 0xA1 - ADD A, R1
+ * 0xA2 - ADD A, R2
+ * 0xA3 - ADD A, R3
+ * 0xA4 - ADD A, DPH
+ * 0xA5 - ADD A, DPL
+ * 0xA6 - ADD A, #data8
+ * 0xA7 - ADD A, @DPTR */
 void
 ADD(void) {
+    if (NNN < 6) {
+        if ((A + get_reg(NNN)) > 0xFF){
+        }
+        A = A + get_reg(NNN);
+        set_zp(A);
+    }
+    else {
+        switch (NNN) {
+            
+            case 6:
+                A = A + fetch();
+                set_zp(A);
+                break;
+
+            case 7:
+                set_wide(TMP, get_wide(DPTR));
+                A = A + mem[TMP];
+                set_zp(A);
+                break;
+        }
+    }
+
 }
 
 void
 ADDC(void) {
-/* implement me */    
+/* implement me */
 }
 
+/* 0xB0 - SUB A, R0
+ * 0xB1 - SUB A, R1
+ * 0xB2 - SUB A, R2
+ * 0xB3 - SUB A, R3
+ * 0xB4 - SUB A, DPH
+ * 0xB5 - SUB A, DPL
+ * 0xB6 - SUB A, #data8
+ * 0xB7 - SUB A, @DPTR */
 void
 SUB(void) {
+    if (NNN < 6) {
+        A = A - get_reg(NNN);
+        set_zp(A);
+    }
+    else {
+        switch (NNN) {
+            
+            case 6:
+                A = A - fetch();
+                set_zp(A);
+                break;
+
+            case 7:
+                set_wide(TMP, get_wide(DPTR));
+                A = A - mem[TMP];
+                set_zp(A);
+                break;
+        }
+    }
 }
 
 void
@@ -365,6 +540,7 @@
 /* 0xDC - SJMP rel8 */
 void
 SJMP(void) {
+    set_wide(PC, get_wide(PC) + (signed char)fetch());
 }
 
 /* 0xDD - JMP @A+DPTR
--- a/emu/mem.c	Sun Apr 13 22:42:57 2014 +0100
+++ b/emu/mem.c	Tue Apr 15 12:21:22 2014 +0100
@@ -28,6 +28,28 @@
     }
 }
 
+/* sets zero and parity flags based on content of byte */
+void
+set_zp(BYTE val){
+    if (val == 0) {
+        set_flag(Z, 1);
+        set_flag(P, 0);
+    }
+    else {
+        /* think of this as folding */
+        val ^= val >> 4;
+        val ^= val >> 2;
+        val ^= val >> 1;
+        val &= 1;
+        if (val == 0) {
+            set_flag(P, 1);
+        }
+        else {
+            set_flag(P, 0);
+        }
+    }
+}
+
 WIDE
 get_wide(BYTE reg) {
     /* high, low */
@@ -57,7 +79,7 @@
 
 WIDE
 fetch_wide(void) {
-    WIDE val = MWIDE(mem[get_wide(PC)], mem[get_wide(PC) + g1]);
+    WIDE val = MWIDE(mem[get_wide(PC)], mem[get_wide(PC) + 1]);
     inc_pc(2);
     return val;
 }
--- a/emu/mem.h	Sun Apr 13 22:42:57 2014 +0100
+++ b/emu/mem.h	Tue Apr 15 12:21:22 2014 +0100
@@ -89,6 +89,15 @@
 EXTERN void
 set_flag(BYTE flag, BYTE on);
 
+EXTERN void
+set_zp(BYTE val);
+
+/* this function a byte and returns a byte
+ * with zero and parity flags set or unset.
+ * result should be or'd with flags reg */
+EXTERN BYTE
+gen_flags(BYTE val);
+
 /* functions for dealing with 16-bit registers
  * access the 16 bit registers.
  * register map for these function:
@@ -120,4 +129,5 @@
 EXTERN void
 set_reg(BYTE reg, BYTE val);
 
+
 #endif
Binary file tests/emu/a.out has changed
--- a/tests/emu/test.c	Sun Apr 13 22:42:57 2014 +0100
+++ b/tests/emu/test.c	Tue Apr 15 12:21:22 2014 +0100
@@ -4,10 +4,6 @@
 
 void
 main(void) {
-        unsigned char* enregs[8];
-        unsigned char *p;
-        p = regs;
-        *enregs[8] =  {p, p+1, p+2, p+3, p+12, p+4, p+13, p+5};
-        *enregs[4] = 0xFF;
-        printf("%d", regs[12]);
+        unsigned char C = 0xFD;
+        printf("%i", (signed char)C);
 }