#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)
case 1:
had_eof = true;
break;
+#if 0
case 3:
if (len < 4) {
fprintf(stderr, "invalid start address record: %s\n", line);
}
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);
}
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);
}
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);
* 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);
/* 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);
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