In /mips-tetris add SPIM test suite, /mips-tetris/helloworld.hex can now run
authorNick Downing <nick@ndcode.org>
Mon, 2 Jan 2023 23:22:28 +0000 (10:22 +1100)
committerNick Downing <nick@ndcode.org>
Tue, 3 Jan 2023 03:58:22 +0000 (14:58 +1100)
emu_mips.c
mips-tetris

index 2e281db..bee58cf 100644 (file)
 #include "cpu_mips.h"
 #endif
 
-#define EXCEPTION_TRAP_BASE 0x20
+#define REG_TRACE 0
+#define MEM_TRACE 0
 
-#define REG_TRACE 1
-#define MEM_TRACE 1
-
-#define MEM_SIZE 0x800000 // 4 MBytes code, 4 MBytes data
+#define MEM_SIZE 0x800000
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 #define MEM_SIZE_M1 (MEM_SIZE - 1)
 #define MEM_SIZE_M2 (MEM_SIZE - 2)
@@ -124,6 +122,7 @@ int load_ihx(char *name) {
     case 1:
       had_eof = true;
       break;
+#if 0
     case 3:
       if (len < 4) {
         fprintf(stderr, "invalid start address record: %s\n", line);
@@ -131,6 +130,7 @@ int load_ihx(char *name) {
       }
       entry_point = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
       break;
+#endif
     case 4:
       if (len < 2) {
         fprintf(stderr, "invalid extended linear address record: %s\n", line);
@@ -138,7 +138,6 @@ int load_ihx(char *name) {
       }
       base = (buf[4] << 24) | (buf[5] << 16);
       break;
-#if 0
     case 5:
       if (len < 4) {
         fprintf(stderr, "invalid start linear address record: %s\n", line);
@@ -146,7 +145,6 @@ int load_ihx(char *name) {
       }
       entry_point = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
       break;
-#endif
     default:
       fprintf(stderr, "unknown record type: 0x%x\n", buf[3]);
       exit(EXIT_FAILURE);
@@ -238,27 +236,13 @@ int simulator_bigendian = 1;
  * occur when calling this ;) (e.g. by doing memory load/store _before_)
  */
 uint32_t phys_addr(uint32_t vaddr, cpu_t *cpu) {
-#if MEM_TRACE
-  fprintf(stderr, "vaddr=%08x\n", vaddr);
-#endif
-  // emulate MARS memory model
-  //   .text: [0x00400000, 0x00800000) -> [0x00000000, 0x00400000)
-  //   .data: [0x10000000, 0x10400000) -> [0x00400000, 0x00800000)
-  if (vaddr < 0x400000)
-    abort();
-  if (vaddr < 0x800000)
-    return vaddr + (0 - 0x400000);
-  if (vaddr < 0x10000000)
-    abort();
-  if (vaddr < 0x10400000)
-    return vaddr + (0x400000 - 0x10000000);
-  abort();
+  return vaddr;
 }
 
 /* Read a byte, halfword or word from memory. Return exception number. */
 exception_t mem_read(memory_t *mem, uint32_t addr, void *buf, 
                      int size, cpu_t *cpu) {
-  addr = phys_addr(addr, NULL);
+  //addr = phys_addr(addr, NULL);
   switch (size) {
   case 1:
     *(uint8_t *)buf = read_byte(NULL, addr);
@@ -278,7 +262,7 @@ exception_t mem_read(memory_t *mem, uint32_t addr, void *buf,
 /* Write a byte, halfword or word to memory. Return exception number. */
 exception_t mem_write(memory_t *mem, uint32_t addr, void *buf, 
                       int size, cpu_t *cpu) {
-  addr = phys_addr(addr, NULL);
+  //addr = phys_addr(addr, NULL);
   switch (size) {
   case 1:
     write_byte(NULL, addr, *(uint8_t *)buf);
@@ -301,15 +285,19 @@ int main(int argc, char **argv) {
     printf("usage: %s image.ihx\n", argv[0]);
     exit(EXIT_FAILURE);
   }
-  load_ihx(argv[1]);
+  int entry_point = load_ihx(argv[1]);
+
+  // place exit trampoline above the stack so program can return into it
+  mem.w[((MEM_SIZE - 8) ^ MEM_SIZE_M4) >> 2] = 0x2402000a; // li $v0, 10
+  mem.w[((MEM_SIZE - 4) ^ MEM_SIZE_M4) >> 2] = 0x0000000c; // syscall
 
 #if ALT_BACKEND
   cpu_t *cpu = cpu_init(0);
 
-  // for mips-tetris assume main is at 0x400000
-  cpu->registers[PC] = 0x400000;
-  cpu->next_pc = cpu->registers[PC] + 4;
-  cpu->registers[R29] = 0x103ffffc; // sp -> last word of 4 Mbyte .data section
+  cpu->registers[PC] = entry_point;
+  cpu->next_pc = entry_point + 4;
+  cpu->registers[R29] = MEM_SIZE - 0xc; // sp
+  cpu->registers[R31] = MEM_SIZE - 8; // ra
 
   while (true) {
 #if REG_TRACE
index 55bdaca..821a1a9 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 55bdaca534c4aeb35be20f78bbb65703e08e4f3e
+Subproject commit 821a1a9d35ad299aca70d3778a7ea3162034a5c4