changeset 12:e9dc055a0f8b

emulator skeleton code
author james <jb302@eecs.qmul.ac.uk>
date Sat, 11 Jan 2014 02:33:32 +0000
parents bba1e3a7877b
children 7a988d894f74
files assembler/assembler.py assembler/assembler.pyc assembler/language.py assembler/language.pyc emulator/a.out emulator/emu.c emulator/iset.c emulator/iset.h emulator/mem.c emulator/mem.h emulator/test.c tests/mem.dump
diffstat 12 files changed, 330 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/assembler/assembler.py	Sun Dec 08 18:50:57 2013 +0000
+++ b/assembler/assembler.py	Sat Jan 11 02:33:32 2014 +0000
@@ -21,13 +21,16 @@
     asm = []
     # <line> ::= [<statement>] [";"<comment>] <EOL>
     for line in source_code:
+        
         # remove EOL
         line = line.strip()
+        
         # remove comments
         for i in range(len(line)):
             if line[i] == ';':
                 line = line[:i]
                 break
+        
         line = line.lower()
         
         # <statement> ::= [ <label> ":"] <mnemonic> [<arguments>]
@@ -38,6 +41,7 @@
         
         # skip empty statements
         if not statement: continue
+        
         # if needed update label tag and remove label 
         label = None
         if statement[0][-1:] == ':':
Binary file assembler/assembler.pyc has changed
--- a/assembler/language.py	Sun Dec 08 18:50:57 2013 +0000
+++ b/assembler/language.py	Sat Jan 11 02:33:32 2014 +0000
@@ -10,10 +10,18 @@
 def num_string(num):
     return hex(num)
 
-# dictionary embedded dictionary?
+
+# valid arguments for this instruction set
+# not actually in use
+iargs = ('', 'addr11', 'addr16', 'sph', 'spl', '@dptr', 'ie', '@a+dptr', 
+         '@addr16', 'vect8', '#data8', 'port_addr', 'dptr', 'bs', '@a+pc', 
+         'a', 'c', 'rel8', 'r0', 'r1', 'r2', 'r3', '#data16', 'sp', 'flags', 
+         'dpl', 'dph')
+
+# dictionary embedded dictionaries?
 # for every mnemonic in the instruction set index
-# there is an index of possible argument types ('symbols')
-# and a corresponding op code
+# there is an index of possible argument formats ('symbol')
+# for that mnemonic and a corresponding op code
 iset =  {'add': {('a', '#data8'): 166,
                  ('a', '@dptr'): 167,
                  ('a', 'dph'): 164,
@@ -270,7 +278,7 @@
 
             else:
                 # bad idea to return junk to throw errors later?
-                sysm.append(a)
+                sym.append(a)
                      
         # addresses
         elif a[:2] == PREFIX:
Binary file assembler/language.pyc has changed
Binary file emulator/a.out has changed
--- a/emulator/emu.c	Sun Dec 08 18:50:57 2013 +0000
+++ b/emulator/emu.c	Sat Jan 11 02:33:32 2014 +0000
@@ -1,16 +1,33 @@
-// emu.c
-#include <stdio.h>
+/* emu.c
+ * emulation start up and fetch/decode/execute loop */
+#include <string.h>
 #include "mem.h"
+#include "iset.h"
 
-void 
-load_program(void) {
+/* instruction table */
+void (*iset[2])(void) = { NOP,
+                          FOO };
+
+void
+boot(void) {
+    /* set everything to zero */
+    memset(&registers, 0, sizeof(registers));
+    memset(&memory, 0, sizeof(memory));
+
+    /* hack hack hack */
+    BYTE program[] = { 0x00,
+                       0x01};
+    memcpy(&memory, program, sizeof(program));
 }
 
-void 
+void
 main(void) {
-    write_mem(0x0000, 0x01);
-    BYTE op = read_mem(0x0000);
-    printf("%c" , op);
-
+    boot();
+    BYTE op;
+    int i = 0;
+    for (i ; i < 3 ; i++) {
+        op = fetch();
+        (*iset[op])();
+    }
+    dump_all();
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emulator/iset.c	Sat Jan 11 02:33:32 2014 +0000
@@ -0,0 +1,15 @@
+/* iset.c
+ * op functions */
+#include "iset.h"
+#include "mem.h"
+
+void
+NOP(void) {
+    registers.PC = registers.PC + 1;
+}
+
+void
+FOO(void) {
+    set_A(0x41);
+    registers.PC = registers.PC + 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emulator/iset.h	Sat Jan 11 02:33:32 2014 +0000
@@ -0,0 +1,13 @@
+/* iset.h
+ * op function definitions */
+#ifndef ISET_H
+#define ISET_H
+
+void 
+NOP(void);
+
+void
+FOO(void);
+
+#endif
+
--- a/emulator/mem.c	Sun Dec 08 18:50:57 2013 +0000
+++ b/emulator/mem.c	Sat Jan 11 02:33:32 2014 +0000
@@ -1,60 +1,133 @@
-// mem.c
-#include <stdio.h>
+/* mem.c
+ * functions for accessing emulator memory */
 #include "mem.h"
 
 BYTE
-read_mem(WIDE addr){
+read_mem(WIDE addr) {
     return memory[addr];
 }
 
 void
-write_mem(WIDE addr, BYTE data){
+write_mem(WIDE addr, BYTE data) {
     memory[addr] = data;
 }
 
 BYTE
-fetch(void){
-    // implement me
-    return 0;
+fetch(void) {
+    return memory[registers.PC];
 }
 
 void
-set_pc(WIDE data){
-    // implement me
+set_PC(WIDE data) {
+    registers.PC = data;
+}
+
+WIDE
+get_PC(void) {
+    return registers.PC;
 }
 
 BYTE
-get_reg(BYTE reg){
-    // implement me
-    return 0;
+get_R(BYTE reg, _Bool bank) {
+    switch(bank) {
+        case 0:
+            return registers.R[reg];
+        case 1:
+            return registers.R[reg + 0x03];
+    }
 }
 
 void
-set_reg(BYTE reg, BYTE data){
-    // implement me
+set_R(BYTE reg, _Bool bank, BYTE data) {
+    switch(bank) {
+        case 0:
+            registers.R[reg] = data;
+        case 1:
+            registers.R[reg + 0x03] = data;
+    }
+}
+
+BYTE
+get_A(void) {
+    return registers.A;
+}
+
+void
+set_A(BYTE data) {
+    registers.A = data;
+}
+
+BYTE
+get_DPH(void) {
+    return registers.DPH;
+}
+
+void
+set_DPH(BYTE data) {
+    registers.DPH = data;
+
+}
+
+BYTE
+get_DPL(void) {
+    return registers.DPL;
+}   
+
+void
+set_DPL(BYTE data) {
+    registers.DPL = data;
+}
+
+BYTE
+get_SPH(void) {
+    return registers.SPH;
+}
+
+void
+set_SPH(BYTE data) {
+    registers.SPH = data;
+}
+
+BYTE
+get_SPL(void) {
+    return registers.SPL;
+}
+
+void
+set_SPL(BYTE data) {
+    registers.SPL = data;
+}
+
+BYTE
+get_flags(void) {
+    return registers.flags;
+}
+
+void
+set_flags(BYTE data) {
+    registers.flags = data;
+}
+
+
+WIDE
+get_DPTR(void) {
+    return (((WIDE)registers.DPH) << 8) | registers.DPL;
+}
+
+void
+set_DPTR(WIDE data) {
+    registers.DPH = (BYTE)((data & 0xFF00) >> 8);
+    registers.DPL = (BYTE)(data & 0x00FF);
 }
 
 WIDE
-get_reg_wide(BYTE reg){
-    // implement me
-    return 0;
+get_SP(void) {
+    return (((WIDE)registers.SPH) << 8) | registers.SPL;
 }
 
 void
-set_reg_wide(BYTE reg, WIDE data){
-    // implement me
+set_SP(WIDE data) {
+    registers.SPH = (BYTE)((data & 0xFF00) >> 8);
+    registers.SPL = (BYTE)(data & 0x00FF);
 }
 
-/*
-void 
-main(void) {
-    write_mem(0x0000, 0x01);
-    BYTE op = read_mem(0x0000);
-    printf("%c" , op);
-
-}
-*/
-
-
-
-
--- a/emulator/mem.h	Sun Dec 08 18:50:57 2013 +0000
+++ b/emulator/mem.h	Sat Jan 11 02:33:32 2014 +0000
@@ -1,52 +1,67 @@
-// mem.h
+/*  mem.h
+ *  emultor memory structure and access function definitions  */
 #ifndef MEM_H
 #define MEM_H
 
-/*
- * data types 
+/* data types
  *  - 8 bit BYTE
- *  - 16 bit WIDE
- */
-
+ *  - 16 bit WIDE */
 typedef unsigned char BYTE;
 typedef unsigned short WIDE;
 
-/*
- * emulator memory
+/* emulator memory
  *  - registers
- *  - 64kB 16-bit main memory
- */
+ *  - 64kB 16-bit main memory */
 
 struct
 registers {
-    // 8 bit registers
+    /* 16 bit registers */
+    WIDE PC;
+    /* DPTR */
+    BYTE DPH;
+    BYTE DPL;
+    /* SP */
+    BYTE SPH;
+    BYTE SPL;
+    /*  8 bit registers
+     *   bank 0: R[0x00 - 0x02]
+     *   bank 1: R[0x03 - 0x06] */ 
+    BYTE R[0x06];
     BYTE A;
-    BYTE R0;
-    BYTE R1;
-    BYTE R2;
-    BYTE R3;
     BYTE flags;
     
-    // 16 bit registers
-    WIDE DPTR;
-    WIDE SP;
-    WIDE PC;
-};
+} registers;
 
 BYTE
 memory[0x10000];
 
-/*
- * memory access function definitions
+/* memory access function definitions
+ *  - fetch() returns BYTE
  *  - read_mem(WIDE) returns BYTE
- *  - write_mem(WIDE, BYTE) 
- *  - fetch() returns BYTE
- *  - set_pc(WIDE)
- *  - get_reg(BYTE) returns BYTE
- *  - set_reg(BYTE, BYTE)
- *  - get_reg_wide(BYTE) returns WIDE
- *  - set_reg_wide(BYTE, WIDE)
- */
+ *  - write_mem(WIDE, BYTE)
+ *  - set_PC(WIDE)
+ *  - get_PC() returns WIDE
+ *  - get_R(BYTE, BOOL) returns BYTE
+ *  - set_R(BYTE, BOOL, BYTE)
+ *  - get_A() returns BYTE
+ *  - set_A(BYTE)
+ *  - get_DPH() returns BYTE
+ *  - set_DPH(BYTE)
+ *  - get DPL() returns BYTE
+ *  - set_DPL(BYTE)
+ *  - get_SPH() returns BYTE
+ *  - set_SPH(BYTE)
+ *  - get_SPL() returns BYTE
+ *  - set_SPL(BYTE)
+ *  - get_flags() returns BYTE
+ *  - set_flags(BYTE)
+ *  - get_DPTR() returns WIDE
+ *  - set_DPTR(WIDE)
+ *  - get_SP() returns WIDE
+ *  - set_SP(WIDE) */
+
+BYTE
+fetch(void);
 
 BYTE
 read_mem(WIDE addr);
@@ -54,23 +69,65 @@
 void
 write_mem(WIDE addr, BYTE data);
 
-BYTE
-fetch(void);
+WIDE
+get_PC(void);
 
 void
-set_pc(WIDE data);
+set_PC(WIDE data);
 
 BYTE
-get_reg(BYTE reg);
+get_R(BYTE reg, _Bool bank);
 
 void
-set_reg(BYTE reg, BYTE data);
+set_R(BYTE reg, _Bool bank, BYTE data);
+
+BYTE
+get_A(void);
+
+void
+set_A(BYTE data);
+
+BYTE
+get_DPH(void);
+
+void
+set_DPH(BYTE data);
+
+BYTE
+get_DPL(void);
+
+void
+set_DPL(BYTE data);
+
+BYTE
+get_SPH(void);
+
+void
+set_SPH(BYTE data);
+
+BYTE
+get_SPL(void);
+
+void
+set_SPL(BYTE data);
+
+BYTE
+get_flags(void);
+
+void
+set_flags(BYTE data);
 
 WIDE
-get_reg_wide(BYTE reg);
+get_DPTR(void);
 
 void
-set_reg_wide(BYTE reg, WIDE data);
+set_DPTR(WIDE data);
+
+WIDE
+get_SP(void);
+
+void
+set_SP(WIDE data);
 
 #endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emulator/test.c	Sat Jan 11 02:33:32 2014 +0000
@@ -0,0 +1,60 @@
+/* test.c
+ * because we need to test things
+ */
+#include <stdio.h>
+
+void 
+dump_all(void) {
+    int i;
+    
+    /* dump reg bank 0 */
+    for (i = 0 ; i < 3 ; i++) {
+        printf("%c", get_R(i, 0x0));
+    }
+    /* dump reg bank 1 */
+    for (i = 0 ; i < 3 ; i++) {
+        printf("%c", get_R(i, 0x1));
+    } 
+    /* dump other registers */
+    printf("%c", get_A());
+    printf("%C", get_flags());
+    printf("%c", get_DPH());
+    printf("%c", get_DPL());
+    printf("%c", get_SPH());
+    printf("%c", get_SPL());
+    
+    /* dump main memory */
+    for (i = 0 ; i < 0x10000 ; i++) {
+        printf("%c", read_mem(i));
+    }
+}
+
+void
+test_pattern(void) {
+    int i;
+    /* fill mem with M's */
+    for (i = 0 ; i < 0x10000 ; i++) {
+        write_mem(i, 0x4D);
+    }
+    /* fill reg bank 1 with R's */
+    for (i = 0 ; i < 3 ; i++) {
+        set_R(i, 0, 0x52);
+    }
+    /* fill reg bank 2 with R's */
+    for (i = 0 ; i < 3 ; i++) {
+        set_R(i, 1, 0x52);
+    }
+    /* A */
+    set_A(0x41);
+    /* F */
+    set_flags(0x46);
+    /* DP */
+    set_DPTR(0x4450);
+    /* SP */
+    set_SP(0x5350);
+    //set_DPH(0x44);
+    //set_DPL(0x50);
+    //set_SPH(0x53);
+    //set_SPL(0x50);
+}
+
Binary file tests/mem.dump has changed