URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
Compare Revisions
- This comparison shows the changes necessary to convert path
/eco32/tags/eco32-0.24/hwtests/dsptest
- from Rev 153 to Rev 211
- ↔ Reverse comparison
Rev 153 → Rev 211
/README
0,0 → 1,3
This is a test for the display. It shows the hash character ('#') |
with all possible attribute bit combinations on the console screen. |
Note: There is no output on the serial lines. |
/serial.s
0,0 → 1,98
; |
; serial.s -- the serial line interface |
; |
|
;*************************************************************** |
|
.set ser0base,0xF0300000 ; serial line 0 base address |
.set ser1base,0xF0301000 ; serial line 1 base address |
|
.export serinit ; initialize serial interface |
|
.export ser0inchk ; line 0 input check |
.export ser0in ; line 0 input |
.export ser0outchk ; line 0 output check |
.export ser0out ; line 0 output |
|
.export ser1inchk ; line 1 input check |
.export ser1in ; line 1 input |
.export ser1outchk ; line 1 output check |
.export ser1out ; line 1 output |
|
;*************************************************************** |
|
.code |
.align 4 |
|
serinit: |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser0inchk: |
add $8,$0,ser0base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser0in: |
add $8,$0,ser0base |
ser0in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser0in1 |
ldw $2,$8,4 |
jr $31 |
|
ser0outchk: |
add $8,$0,ser0base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser0out: |
add $8,$0,ser0base |
ser0out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser0out1 |
stw $4,$8,12 |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser1inchk: |
add $8,$0,ser1base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser1in: |
add $8,$0,ser1base |
ser1in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser1in1 |
ldw $2,$8,4 |
jr $31 |
|
ser1outchk: |
add $8,$0,ser1base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser1out: |
add $8,$0,ser1base |
ser1out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser1out1 |
stw $4,$8,12 |
jr $31 |
/Makefile
0,0 → 1,27
# |
# Makefile for dsptest ROM |
# |
|
BUILD = ../../build |
|
DSPTEST_SRC = start.s main.c lib.c serial.s end.s |
|
.PHONY: all install run clean |
|
all: dsptest.exo |
|
install: dsptest.exo |
|
dsptest.exo: dsptest.bin |
$(BUILD)/bin/bin2exo -S2 0 dsptest.bin dsptest.exo |
|
dsptest.bin: $(DSPTEST_SRC) |
$(BUILD)/bin/lcc -A -Wo-rom -Wl-rd -Wl0xC03F0000 \ |
-Wl-m -Wldsptest.map -o dsptest.bin $(DSPTEST_SRC) |
|
run: dsptest.bin |
$(BUILD)/bin/sim -i -c -r dsptest.bin |
|
clean: |
rm -f *~ |
rm -f dsptest.map dsptest.bin dsptest.exo |
/start.h
0,0 → 1,21
/* |
* start.h -- startup and support routines |
*/ |
|
|
#ifndef _START_H_ |
#define _START_H_ |
|
|
int cin(void); |
void cout(char c); |
|
Word getTLB_HI(int index); |
Word getTLB_LO(int index); |
void setTLB(int index, Word entryHi, Word entryLo); |
void wrtRndTLB(Word entryHi, Word entryLo); |
Word probeTLB(Word entryHi); |
void wait(int n); |
|
|
#endif /* _START_H_ */ |
/main.c
0,0 → 1,27
/* |
* main.c -- the main program |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "start.h" |
|
|
int main(void) { |
int i, j; |
unsigned int attr, ch; |
unsigned int *p; |
|
for (i = 0; i < 16; i++) { |
for (j = 0; j < 16; j++) { |
attr = i * 16 + j; |
ch = (attr << 8) | 0x23; |
p = (unsigned int *) 0xF0100000; |
p += 128 * i + 2 * j; |
*p = ch; |
} |
} |
while (1) ; |
return 0; |
} |
/end.s
0,0 → 1,19
; |
; end.s -- end-of-segment labels |
; |
|
.export _ecode |
.export _edata |
.export _ebss |
|
.code |
.align 4 |
_ecode: |
|
.data |
.align 4 |
_edata: |
|
.bss |
.align 4 |
_ebss: |
/lib.c
0,0 → 1,624
/* |
* lib.c -- the library |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "stdarg.h" |
#include "start.h" |
|
|
/**************************************************************/ |
|
|
/* |
* This is only for debugging. |
* Place a breakpoint at the very beginning of this routine |
* and call it wherever you want to break execution. |
*/ |
void debugBreak(void) { |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the length of a string (without terminating null character). |
*/ |
int strlen(const char *s) { |
const char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
return p - s; |
} |
|
|
/* |
* Compare two strings. |
* Return a number < 0, = 0, or > 0 iff the first string is less |
* than, equal to, or greater than the second one, respectively. |
*/ |
int strcmp(const char *s, const char *t) { |
while (*s == *t) { |
if (*s == '\0') { |
return 0; |
} |
s++; |
t++; |
} |
return *s - *t; |
} |
|
|
/* |
* Copy string t to string s (includes terminating null character). |
*/ |
char *strcpy(char *s, const char *t) { |
char *p; |
|
p = s; |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Append string t to string s. |
*/ |
char *strcat(char *s, const char *t) { |
char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Locate character c in string s. |
*/ |
char *strchr(const char *s, char c) { |
while (*s != c) { |
if (*s == '\0') { |
return NULL; |
} |
s++; |
} |
return (char *) s; |
} |
|
|
/* |
* Extract the next token from the string s, delimited |
* by any character from the delimiter string t. |
*/ |
char *strtok(char *s, const char *t) { |
static char *p; |
char *q; |
|
if (s != NULL) { |
p = s; |
} else { |
p++; |
} |
while (*p != '\0' && strchr(t, *p) != NULL) { |
p++; |
} |
if (*p == '\0') { |
return NULL; |
} |
q = p++; |
while (*p != '\0' && strchr(t, *p) == NULL) { |
p++; |
} |
if (*p != '\0') { |
*p = '\0'; |
} else { |
p--; |
} |
return q; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Determine if a character is 'white space'. |
*/ |
static Bool isspace(char c) { |
Bool res; |
|
switch (c) { |
case ' ': |
case '\f': |
case '\n': |
case '\r': |
case '\t': |
case '\v': |
res = true; |
break; |
default: |
res = false; |
break; |
} |
return res; |
} |
|
|
/* |
* Check for valid digit, and convert to value. |
*/ |
static Bool checkDigit(char c, int base, int *value) { |
if (c >= '0' && c <= '9') { |
*value = c - '0'; |
} else |
if (c >= 'A' && c <= 'Z') { |
*value = c - 'A' + 10; |
} else |
if (c >= 'a' && c <= 'z') { |
*value = c - 'a' + 10; |
} else { |
return false; |
} |
return *value < base; |
} |
|
|
/* |
* Convert initial part of string to unsigned long integer. |
*/ |
unsigned long strtoul(const char *s, char **endp, int base) { |
unsigned long res; |
int sign; |
int digit; |
|
res = 0; |
while (isspace(*s)) { |
s++; |
} |
if (*s == '+') { |
sign = 1; |
s++; |
} else |
if (*s == '-') { |
sign = -1; |
s++; |
} else { |
sign = 1; |
} |
if (base == 0 || base == 16) { |
if (*s == '0' && |
(*(s + 1) == 'x' || *(s + 1) == 'X')) { |
/* base is 16 */ |
s += 2; |
base = 16; |
} else { |
/* base is 0 or 16, but number does not start with "0x" */ |
if (base == 0) { |
if (*s == '0') { |
s++; |
base = 8; |
} else { |
base = 10; |
} |
} else { |
/* take base as is */ |
} |
} |
} else { |
/* take base as is */ |
} |
while (checkDigit(*s, base, &digit)) { |
res *= base; |
res += digit; |
s++; |
} |
if (endp != NULL) { |
*endp = (char *) s; |
} |
return sign * res; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Exchange two array items of a given size. |
*/ |
static void xchg(char *p, char *q, int size) { |
char t; |
|
while (size--) { |
t = *p; |
*p++ = *q; |
*q++ = t; |
} |
} |
|
|
/* |
* This is a recursive version of quicksort. |
*/ |
static void sort(char *l, char *r, int size, |
int (*cmp)(const void *, const void *)) { |
char *i; |
char *j; |
char *x; |
|
i = l; |
j = r; |
x = l + (((r - l) / size) / 2) * size; |
do { |
while (cmp(i, x) < 0) { |
i += size; |
} |
while (cmp(x, j) < 0) { |
j -= size; |
} |
if (i <= j) { |
/* exchange array elements i and j */ |
/* attention: update x if it is one of these */ |
if (x == i) { |
x = j; |
} else |
if (x == j) { |
x = i; |
} |
xchg(i, j, size); |
i += size; |
j -= size; |
} |
} while (i <= j); |
if (l < j) { |
sort(l, j, size, cmp); |
} |
if (i < r) { |
sort(i, r, size, cmp); |
} |
} |
|
|
/* |
* External interface for the quicksort algorithm. |
*/ |
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void*)) { |
sort((char *) base, (char *) base + (n - 1) * size, size, cmp); |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Input a character from the console. |
*/ |
char getchar(void) { |
return cin(); |
} |
|
|
/* |
* Output a character on the console. |
* Replace LF by CR/LF. |
*/ |
void putchar(char c) { |
if (c == '\n') { |
cout('\r'); |
} |
cout(c); |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in base 10. |
*/ |
static int countPrintn(long n) { |
long a; |
int res; |
|
res = 0; |
if (n < 0) { |
res++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
res += countPrintn(a); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in base 10. |
*/ |
static void *printn(void *(*emit)(void *, char), void *arg, |
int *nchar, long n) { |
long a; |
|
if (n < 0) { |
arg = emit(arg, '-'); |
(*nchar)++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
arg = printn(emit, arg, nchar, a); |
} |
arg = emit(arg, n % 10 + '0'); |
(*nchar)++; |
return arg; |
} |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in a given base. |
*/ |
static int countPrintu(unsigned long n, unsigned long b) { |
unsigned long a; |
int res; |
|
res = 0; |
a = n / b; |
if (a != 0) { |
res += countPrintu(a, b); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in a given base. |
*/ |
static void *printu(void *(*emit)(void *, char), void *arg, |
int *nchar, unsigned long n, unsigned long b, |
Bool upperCase) { |
unsigned long a; |
|
a = n / b; |
if (a != 0) { |
arg = printu(emit, arg, nchar, a, b, upperCase); |
} |
if (upperCase) { |
arg = emit(arg, "0123456789ABCDEF"[n % b]); |
(*nchar)++; |
} else { |
arg = emit(arg, "0123456789abcdef"[n % b]); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* Output a number of filler characters. |
*/ |
static void *fill(void *(*emit)(void *, char), void *arg, |
int *nchar, int numFillers, char filler) { |
while (numFillers-- > 0) { |
arg = emit(arg, filler); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* This function does the real work of formatted printing. |
*/ |
static int doPrintf(void *(*emit)(void *, char), void *arg, |
const char *fmt, va_list ap) { |
int nchar; |
char c; |
int n; |
long ln; |
unsigned int u; |
unsigned long lu; |
char *s; |
Bool negFlag; |
char filler; |
int width, count; |
|
nchar = 0; |
while (1) { |
while ((c = *fmt++) != '%') { |
if (c == '\0') { |
return nchar; |
} |
arg = emit(arg, c); |
nchar++; |
} |
c = *fmt++; |
if (c == '-') { |
negFlag = true; |
c = *fmt++; |
} else { |
negFlag = false; |
} |
if (c == '0') { |
filler = '0'; |
c = *fmt++; |
} else { |
filler = ' '; |
} |
width = 0; |
while (c >= '0' && c <= '9') { |
width *= 10; |
width += c - '0'; |
c = *fmt++; |
} |
if (c == 'd') { |
n = va_arg(ap, int); |
count = countPrintn(n); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, n); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
u = va_arg(ap, int); |
count = countPrintu(u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'l') { |
c = *fmt++; |
if (c == 'd') { |
ln = va_arg(ap, long); |
count = countPrintn(ln); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, ln); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
lu = va_arg(ap, long); |
count = countPrintu(lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else { |
arg = emit(arg, 'l'); |
nchar++; |
arg = emit(arg, c); |
nchar++; |
} |
} else |
if (c == 's') { |
s = va_arg(ap, char *); |
count = strlen(s); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
while ((c = *s++) != '\0') { |
arg = emit(arg, c); |
nchar++; |
} |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'c') { |
c = va_arg(ap, char); |
arg = emit(arg, c); |
nchar++; |
} else { |
arg = emit(arg, c); |
nchar++; |
} |
} |
/* never reached */ |
return 0; |
} |
|
|
/* |
* Emit a character to the console. |
*/ |
static void *emitToConsole(void *dummy, char c) { |
putchar(c); |
return dummy; |
} |
|
|
/* |
* Formatted output with a variable argument list. |
*/ |
static int vprintf(const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToConsole, NULL, fmt, ap); |
return n; |
} |
|
|
/* |
* Formatted output. |
*/ |
int printf(const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vprintf(fmt, ap); |
va_end(ap); |
return n; |
} |
|
|
/* |
* Emit a character to a buffer. |
*/ |
static void *emitToBuffer(void *bufptr, char c) { |
*(char *)bufptr = c; |
return (char *) bufptr + 1; |
} |
|
|
/* |
* Formatted output into a buffer with a variable argument list. |
*/ |
static int vsprintf(char *s, const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToBuffer, s, fmt, ap); |
s[n] = '\0'; |
return n; |
} |
|
|
/* |
* Formatted output into a buffer. |
*/ |
int sprintf(char *s, const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vsprintf(s, fmt, ap); |
va_end(ap); |
return n; |
} |
/stdarg.h
0,0 → 1,41
/* |
* stdarg.h -- variable argument lists |
*/ |
|
|
#ifndef _STDARG_H_ |
#define _STDARG_H_ |
|
|
typedef char *va_list; |
|
|
static float __va_arg_tmp; |
|
|
#define va_start(list, start) \ |
((void)((list) = (sizeof(start)<4 ? \ |
(char *)((int *)&(start)+1) : (char *)(&(start)+1)))) |
|
#define __va_arg(list, mode, n) \ |
(__typecode(mode)==1 && sizeof(mode)==4 ? \ |
(__va_arg_tmp = *(double *)(&(list += \ |
((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \ |
*(mode *)&__va_arg_tmp) : \ |
*(mode *)(&(list += \ |
((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)])) |
|
#define _bigendian_va_arg(list, mode, n) \ |
(sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \ |
sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \ |
__va_arg(list, mode, n)) |
|
#define va_end(list) ((void)0) |
|
#define va_arg(list, mode) \ |
(sizeof(mode)==8 ? \ |
*(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \ |
_bigendian_va_arg(list, mode, 3U)) |
|
|
#endif /* _STDARG_H_ */ |
/lib.h
0,0 → 1,31
/* |
* lib.h -- the library |
*/ |
|
|
#ifndef _LIB_H_ |
#define _LIB_H_ |
|
|
void debugBreak(void); |
|
int strlen(const char *s); |
int strcmp(const char *s, const char *t); |
char *strcpy(char *s, const char *t); |
char *strcat(char *s, const char *t); |
char *strchr(const char *s, char c); |
char *strtok(char *s, const char *t); |
|
unsigned long strtoul(const char *s, char **endp, int base); |
|
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void *)); |
|
char getchar(void); |
void putchar(char c); |
|
int printf(const char *fmt, ...); |
int sprintf(char *s, const char *fmt, ...); |
|
|
#endif /* _LIB_H_ */ |
/common.h
0,0 → 1,27
/* |
* common.h -- common definitions |
*/ |
|
|
#ifndef _COMMON_H_ |
#define _COMMON_H_ |
|
|
#define PAGE_SHIFT 12 /* log2 of page size */ |
#define PAGE_SIZE (1 << PAGE_SHIFT) /* page size in bytes */ |
#define OFFSET_MASK (PAGE_SIZE - 1) /* mask for offset in page */ |
#define PAGE_MASK (~OFFSET_MASK) /* mask for page number */ |
|
|
typedef enum { false, true } Bool; /* truth values */ |
|
|
typedef unsigned int Word; /* 32 bit quantities */ |
typedef unsigned short Half; /* 16 bit quantities */ |
typedef unsigned char Byte; /* 8 bit quantities */ |
|
|
#define NULL ((void *) 0) |
|
|
#endif /* _COMMON_H_ */ |
/start.s
0,0 → 1,176
; |
; start.s -- startup and support routines |
; |
|
.set dmapaddr,0xC0000000 ; base of directly mapped addresses |
.set stacktop,0xC0400000 ; monitor stack is at top of memory |
|
.set PSW,0 ; reg # of PSW |
.set TLB_INDEX,1 ; reg # of TLB Index |
.set TLB_ENTRY_HI,2 ; reg # of TLB EntryHi |
.set TLB_ENTRY_LO,3 ; reg # of TLB EntryLo |
.set TLB_ENTRIES,32 ; number of TLB entries |
|
;*************************************************************** |
|
.import _ecode |
.import _edata |
.import _ebss |
|
.import serinit |
.import ser0in |
.import ser0out |
|
.import main |
|
.export _bcode |
.export _bdata |
.export _bbss |
|
.export cin |
.export cout |
|
.export getTLB_HI |
.export getTLB_LO |
.export setTLB |
.export wrtRndTLB |
.export probeTLB |
.export wait |
|
;*************************************************************** |
|
.code |
_bcode: |
|
.data |
_bdata: |
|
.bss |
_bbss: |
|
;*************************************************************** |
|
.code |
.align 4 |
|
reset: |
j start |
|
interrupt: |
j interrupt |
|
userMiss: |
j userMiss |
|
;*************************************************************** |
|
.code |
.align 4 |
|
cin: |
j ser0in |
|
cout: |
j ser0out |
|
;*************************************************************** |
|
.code |
.align 4 |
|
start: |
; force CPU into a defined state |
mvts $0,PSW ; disable interrupts and user mode |
|
; initialize TLB |
mvts $0,TLB_ENTRY_LO ; invalidate all TLB entries |
add $8,$0,dmapaddr ; by impossible virtual page number |
add $9,$0,$0 |
add $10,$0,TLB_ENTRIES |
tlbloop: |
mvts $8,TLB_ENTRY_HI |
mvts $9,TLB_INDEX |
tbwi |
add $8,$8,0x1000 ; all entries must be different |
add $9,$9,1 |
bne $9,$10,tlbloop |
|
; copy data segment |
add $10,$0,_bdata ; lowest dst addr to be written to |
add $8,$0,_edata ; one above the top dst addr |
sub $9,$8,$10 ; $9 = size of data segment |
add $9,$9,_ecode ; data is waiting right after code |
j cpytest |
cpyloop: |
ldw $11,$9,0 ; src addr in $9 |
stw $11,$8,0 ; dst addr in $8 |
cpytest: |
sub $8,$8,4 ; downward |
sub $9,$9,4 |
bgeu $8,$10,cpyloop |
|
; clear bss segment |
add $8,$0,_bbss ; start with first word of bss |
add $9,$0,_ebss ; this is one above the top |
j clrtest |
clrloop: |
stw $0,$8,0 ; dst addr in $8 |
add $8,$8,4 ; upward |
clrtest: |
bltu $8,$9,clrloop |
|
; now do some useful work |
add $29,$0,stacktop ; setup monitor stack |
jal serinit ; init serial interface |
jal main ; enter command loop |
|
; main should never return |
j start ; just to be sure... |
|
;*************************************************************** |
|
; Word getTLB_HI(int index) |
getTLB_HI: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_HI |
jr $31 |
|
; Word getTLB_LO(int index) |
getTLB_LO: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_LO |
jr $31 |
|
; void setTLB(int index, Word entryHi, Word entryLo) |
setTLB: |
mvts $4,TLB_INDEX |
mvts $5,TLB_ENTRY_HI |
mvts $6,TLB_ENTRY_LO |
tbwi |
jr $31 |
|
; void wrtRndTLB(Word entryHi, Word entryLo) |
wrtRndTLB: |
mvts $4,TLB_ENTRY_HI |
mvts $5,TLB_ENTRY_LO |
tbwr |
jr $31 |
|
; Word probeTLB(Word entryHi) |
probeTLB: |
mvts $4,TLB_ENTRY_HI |
tbs |
mvfs $2,TLB_INDEX |
jr $31 |
|
; void wait(int n) |
wait: |
j wait2 |
wait1: |
add $4,$4,$0 |
sub $4,$4,1 |
wait2: |
bne $4,$0,wait1 |
jr $31 |